Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 3173 → Rev 3174

/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);
}
}