/branches/dynload/uspace/app/init/init.c |
---|
82,35 → 82,17 |
static void spawn(char *fname) |
{ |
char *argv[2]; |
printf(NAME ": Spawning %s\n", fname); |
if (task_spawn_ex(fname, NULL) != 0) { |
argv[0] = fname; |
argv[1] = NULL; |
if (task_spawn_ex(fname, argv) != 0) { |
/* Success */ |
sleep(1); |
} |
return; |
int fd = open(fname, O_RDONLY); |
if (fd >= 0) { |
ssize_t rd; |
size_t len = 0; |
// FIXME: cannot do long reads yet |
do { |
rd = read(fd, buf + len, 1024); |
if (rd > 0) |
len += rd; |
} while (rd > 0); |
if (len > 0) { |
task_spawn(buf, len); |
sleep(1); // FIXME |
} |
close(fd); |
} |
} |
int main(int argc, char *argv[]) |
/branches/dynload/uspace/app/tester/tester.c |
---|
107,8 → 107,17 |
printf("*\t\t\tRun all safe tests\n"); |
} |
int main(void) |
int main(int argc, char **argv) |
{ |
printf("Number of arguments: %d\n", argc); |
if (argv) { |
printf("Arguments:"); |
while (*argv) { |
printf(" '%s'", *argv++); |
} |
printf("\n"); |
} |
while (1) { |
char c; |
test_t *test; |
/branches/dynload/uspace/app/cli/cli.c |
---|
41,7 → 41,10 |
#define LINE_BUFFER_SIZE 128 |
static char line_buffer[LINE_BUFFER_SIZE]; |
void read_line(char *buffer, int n) |
#define MAX_ARGS 16 |
static char *argv_buf[MAX_ARGS + 1]; |
static void read_line(char *buffer, int n) |
{ |
char c; |
int chars; |
69,7 → 72,35 |
buffer[chars] = '\0'; |
} |
static void program_run(void) |
{ |
char *p; |
int n; |
p = line_buffer; |
n = 0; |
while (n < MAX_ARGS) { |
argv_buf[n++] = p; |
p = strchr(p, ' '); |
if (p == NULL) break; |
*p++ = '\0'; |
} |
argv_buf[n] = NULL; |
printf("spawn task '%s' with %d args\n", argv_buf[0], n); |
printf("args:"); |
int i; |
for (i = 0; i < n; ++i) { |
printf(" '%s'", argv_buf[i]); |
} |
printf("\n"); |
task_spawn_ex(argv_buf[0], argv_buf); |
} |
int main(int argc, char *argv[]) |
{ |
printf("This is CLI\n"); |
79,9 → 110,9 |
printf("'%s'\n", line_buffer); |
if (strcmp(line_buffer, "exit") == 0) |
break; |
printf("spawn task\n"); |
if (line_buffer[0] != '\0') |
task_spawn_ex(line_buffer, NULL); |
program_run(); |
} |
printf("Bye\n"); |
/branches/dynload/uspace/lib/libc/include/ipc/loader.h |
---|
40,6 → 40,7 |
typedef enum { |
LOADER_HELLO = IPC_FIRST_USER_METHOD, |
LOADER_SET_PATHNAME, |
LOADER_SET_ARGS, |
LOADER_RUN |
} fb_request_t; |
/branches/dynload/uspace/lib/libc/generic/task.c |
---|
38,6 → 38,7 |
#include <ipc/loader.h> |
#include <libc.h> |
#include <string.h> |
#include <stdlib.h> |
#include <async.h> |
#include <errno.h> |
61,6 → 62,60 |
return phone_id; |
} |
static int loader_set_args(int phone_id, const char *argv[]) |
{ |
aid_t req; |
ipc_call_t answer; |
int rc; |
const char **ap; |
char *dp; |
char *arg_buf; |
size_t buffer_size; |
size_t len; |
/* |
* Serialize the arguments into a single array. First |
* compute size of the buffer needed. |
*/ |
ap = argv; |
buffer_size = 0; |
while (*ap != NULL) { |
buffer_size += strlen(*ap) + 1; |
++ap; |
} |
arg_buf = malloc(buffer_size); |
if (arg_buf == NULL) return ENOMEM; |
/* Now fill the buffer with null-terminated argument strings */ |
ap = argv; |
dp = arg_buf; |
while (*ap != NULL) { |
strcpy(dp, *ap); |
dp += strlen(*ap) + 1; |
++ap; |
} |
/* Send serialized arguments to the loader */ |
req = async_send_0(phone_id, LOADER_SET_ARGS, &answer); |
rc = ipc_data_write_start(phone_id, (void *)arg_buf, buffer_size); |
if (rc != EOK) { |
async_wait_for(req, NULL); |
return rc; |
} |
async_wait_for(req, &rc); |
if (rc != EOK) return rc; |
/* Free temporary buffer */ |
free(arg_buf); |
return EOK; |
} |
/** Create a new task by running an executable from VFS. |
* |
* @param path pathname of the binary to execute |
94,15 → 149,24 |
} |
async_wait_for(req, &rc); |
if (rc != EOK) return 0; |
if (rc != EOK) goto error; |
/* Send arguments */ |
rc = loader_set_args(phone_id, argv); |
if (rc != EOK) goto error; |
/* Request loader to start the program */ |
rc = async_req_0_0(phone_id, LOADER_RUN); |
if (rc != EOK) return 0; |
if (rc != EOK) goto error; |
/* Success */ |
ipc_hangup(phone_id); |
return 1; |
return 1; |
/* Error exit */ |
error: |
ipc_hangup(phone_id); |
return 0; |
} |
int task_spawn(void *image, size_t size) |
/branches/dynload/uspace/srv/loader/include/arch.h |
---|
33,8 → 33,8 |
* @brief |
*/ |
#ifndef ILOADER_ARCH_H_ |
#define ILOADER_ARCH_H_ |
#ifndef LOADER_ARCH_H_ |
#define LOADER_ARCH_H_ |
void program_run(void *entry_point, void *pcb); |
/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); |
} |
} |