Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 3173 → Rev 3174

/branches/dynload/uspace/srv/loader/main.c
70,12 → 70,19
/** The Program control block */
static pcb_t pcb;
 
/** Number of arguments */
static int argc = 0;
/** Argument vector */
static char **argv = NULL;
/** Buffer holding all arguments */
static char *arg_buf = NULL;
 
/** Receive a call setting pathname of the program to execute.
*
* @param rid
* @param request
*/
static void iloader_set_pathname(ipc_callid_t rid, ipc_call_t *request)
static void loader_set_pathname(ipc_callid_t rid, ipc_call_t *request)
{
ipc_callid_t callid;
size_t len;
106,6 → 113,85
pathname = name_buf;
}
 
/** Receive a call setting arguments of the program to execute.
*
* @param rid
* @param request
*/
static void loader_set_args(ipc_callid_t rid, ipc_call_t *request)
{
ipc_callid_t callid;
size_t buf_len, arg_len;
char *p;
int n;
 
if (!ipc_data_write_receive(&callid, &buf_len)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
 
if (arg_buf != NULL) {
free(arg_buf);
arg_buf = NULL;
}
 
if (argv != NULL) {
free(argv);
argv = NULL;
}
 
arg_buf = malloc(buf_len + 1);
if (!arg_buf) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
return;
}
 
ipc_data_write_finalize(callid, arg_buf, buf_len);
ipc_answer_0(rid, EOK);
 
arg_buf[buf_len] = '\0';
 
/*
* Count number of arguments
*/
p = arg_buf;
n = 0;
while (p < arg_buf + buf_len) {
arg_len = strlen(p);
p = p + arg_len + 1;
++n;
}
 
/* Allocate argv */
argv = malloc((n + 1) * sizeof(char *));
 
if (argv == NULL) {
free(arg_buf);
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
return;
}
 
/*
* Fill argv with argument pointers
*/
p = arg_buf;
n = 0;
while (p < arg_buf + buf_len) {
argv[n] = p;
 
arg_len = strlen(p);
p = p + arg_len + 1;
++n;
}
 
argc = n;
argv[n] = NULL;
}
 
 
/** Load and run the previously selected program.
*
* @param rid
112,7 → 198,7
* @param request
* @return 0 on success, !0 on error.
*/
static int iloader_run(ipc_callid_t rid, ipc_call_t *request)
static int loader_run(ipc_callid_t rid, ipc_call_t *request)
{
int rc;
 
131,8 → 217,8
// printf("Create PCB\n");
elf_create_pcb(&prog_info, &pcb);
 
pcb.argc = 0;
pcb.argv = NULL;
pcb.argc = argc;
pcb.argv = argv;
 
if (prog_info.interp == NULL) {
/* Statically linked program */
189,10 → 275,12
// call.in_phone_hash, IPC_GET_METHOD(call));
switch (IPC_GET_METHOD(call)) {
case LOADER_SET_PATHNAME:
iloader_set_pathname(callid, &call);
loader_set_pathname(callid, &call);
continue;
case LOADER_SET_ARGS:
loader_set_args(callid, &call);
case LOADER_RUN:
iloader_run(callid, &call);
loader_run(callid, &call);
exit(0);
continue;
default:
199,8 → 287,10
retval = ENOENT;
break;
}
if ((callid & IPC_CALLID_NOTIFICATION) == 0) {
printf("responding EINVAL to method %d\n", IPC_GET_METHOD(call));
if ((callid & IPC_CALLID_NOTIFICATION) == 0 &&
IPC_GET_METHOD(call) != IPC_M_PHONE_HUNGUP) {
printf("responding EINVAL to method %d\n",
IPC_GET_METHOD(call));
ipc_answer_0(callid, EINVAL);
}
}