Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 3471 → Rev 3437

/branches/tracing/uspace/lib/libc/include/task.h
40,7 → 40,7
typedef uint64_t task_id_t;
 
extern task_id_t task_get_id(void);
extern task_id_t task_spawn(const char *path, char *const argv[]);
extern task_id_t task_spawn(const char *path, const char *argv[]);
 
#endif
 
/branches/tracing/uspace/lib/libc/include/loader/loader.h
File deleted
/branches/tracing/uspace/lib/libc/include/loader/pcb.h
40,8 → 40,7
 
typedef void (*entry_point_t)(void);
 
/** Program Control Block.
*
/**
* Holds pointers to data passed from the program loader to the program
* and/or to the dynamic linker. This includes the program entry point,
* arguments, environment variables etc.
/branches/tracing/uspace/lib/libc/include/ipc/loader.h
32,17 → 32,15
/** @file
*/
 
#ifndef LIBC_IPC_LOADER_H_
#define LIBC_IPC_LOADER_H_
#ifndef LIBC_LOADER_H_
#define LIBC_LOADER_H_
 
#include <ipc/ipc.h>
 
typedef enum {
LOADER_HELLO = IPC_FIRST_USER_METHOD,
LOADER_GET_TASKID,
LOADER_SET_PATHNAME,
LOADER_SET_ARGS,
LOADER_LOAD,
LOADER_RUN
} fb_request_t;
 
/branches/tracing/uspace/lib/libc/generic/loader.c
File deleted
/branches/tracing/uspace/lib/libc/generic/task.c
34,10 → 34,14
*/
 
#include <task.h>
#include <ipc/ipc.h>
#include <ipc/loader.h>
#include <libc.h>
#include <string.h>
#include <stdlib.h>
#include <async.h>
#include <errno.h>
#include <loader/loader.h>
#include <vfs/vfs.h>
 
task_id_t task_get_id(void)
{
48,62 → 52,134
return task_id;
}
 
/** Create a new task by running an executable from the filesystem.
static int task_spawn_loader(void)
{
int phone_id, rc;
 
rc = __SYSCALL1(SYS_PROGRAM_SPAWN_LOADER, (sysarg_t) &phone_id);
if (rc != 0)
return rc;
 
return phone_id;
}
 
static int loader_set_args(int phone_id, const char *argv[])
{
aid_t req;
ipc_call_t answer;
ipcarg_t 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.
*
* This is really just a convenience wrapper over the more complicated
* loader API.
*
* @param path pathname of the binary to execute
* @param argv command-line arguments
* @return ID of the newly created task or zero on error.
*/
task_id_t task_spawn(const char *path, char *const argv[])
task_id_t task_spawn(const char *path, const char *argv[])
{
loader_t *ldr;
task_id_t task_id;
int phone_id;
ipc_call_t answer;
aid_t req;
int rc;
ipcarg_t retval;
 
/* Spawn a program loader. */
ldr = loader_spawn();
if (ldr == NULL)
char *pa;
size_t pa_len;
 
pa = absolutize(path, &pa_len);
if (!pa)
return 0;
 
/* Get task ID. */
rc = loader_get_task_id(ldr, &task_id);
if (rc != EOK)
goto error;
/* Spawn a program loader */
phone_id = task_spawn_loader();
if (phone_id < 0)
return 0;
 
/* Send program pathname. */
rc = loader_set_pathname(ldr, path);
/*
* Say hello so that the loader knows the incoming connection's
* phone hash.
*/
rc = async_req_0_0(phone_id, LOADER_HELLO);
if (rc != EOK)
goto error;
return 0;
 
/* Send arguments. */
rc = loader_set_args(ldr, argv);
if (rc != EOK)
/* Send program pathname */
req = async_send_0(phone_id, LOADER_SET_PATHNAME, &answer);
rc = ipc_data_write_start(phone_id, (void *)pa, pa_len);
if (rc != EOK) {
async_wait_for(req, NULL);
return 1;
}
 
async_wait_for(req, &retval);
if (retval != EOK)
goto error;
 
/* Load the program. */
rc = loader_load_program(ldr);
/* Send arguments */
rc = loader_set_args(phone_id, argv);
if (rc != EOK)
goto error;
 
/* Run it. */
/* Load the program. */
rc = loader_run(ldr);
/* Request loader to start the program */
rc = async_req_0_0(phone_id, LOADER_RUN);
if (rc != EOK)
goto error;
 
/* Success */
ipc_hangup(phone_id);
return 1;
 
free(ldr);
return task_id;
 
/* Error exit */
error:
loader_abort(ldr);
free(ldr);
 
ipc_hangup(phone_id);
return 0;
}
 
/branches/tracing/uspace/lib/libc/generic/vfs/vfs.c
599,7 → 599,6
cwd_path = pa;
cwd_len = pa_len;
futex_up(&cwd_futex);
return EOK;
}
 
char *getcwd(char *buf, size_t size)
/branches/tracing/uspace/lib/libc/generic/udebug.c
57,16 → 57,10
int udebug_thread_read(int phoneid, void *buffer, size_t n,
size_t *copied, size_t *needed)
{
ipcarg_t a_copied, a_needed;
int rc;
unsigned dest_addr;
 
rc = async_req_3_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_THREAD_READ,
(sysarg_t)buffer, n, NULL, &a_copied, &a_needed);
 
*copied = (size_t)a_copied;
*needed = (size_t)a_needed;
 
return rc;
return async_req_3_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_THREAD_READ,
(sysarg_t)buffer, n, &dest_addr, copied, needed);
}
 
int udebug_mem_read(int phoneid, void *buffer, uintptr_t addr, size_t n)
102,14 → 96,8
int udebug_go(int phoneid, thash_t tid, udebug_event_t *ev_type,
sysarg_t *val0, sysarg_t *val1)
{
ipcarg_t a_ev_type;
int rc;
 
rc = async_req_2_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_GO,
tid, &a_ev_type, val0, val1);
 
*ev_type = a_ev_type;
return rc;
return async_req_2_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_GO,
tid, (sysarg_t)ev_type, (sysarg_t)val0, (sysarg_t)val1);
}
 
int udebug_stop(int phoneid, thash_t tid)
/branches/tracing/uspace/lib/libc/Makefile
71,7 → 71,6
generic/sysinfo.c \
generic/ipc.c \
generic/async.c \
generic/loader.c \
generic/getopt.c \
generic/libadt/list.o \
generic/libadt/hash_table.o \