Subversion Repositories HelenOS

Compare Revisions

Regard whitespace Rev 4376 → Rev 4377

/branches/tracing/uspace/srv/loader/main.c
50,8 → 50,10
#include <fcntl.h>
#include <sys/types.h>
#include <ipc/ipc.h>
#include <ipc/services.h>
#include <ipc/loader.h>
#include <loader/pcb.h>
#include <console.h>
#include <errno.h>
#include <async.h>
#include <as.h>
59,6 → 61,8
#include <elf.h>
#include <elf_load.h>
 
#define DPRINTF(...)
 
/** Pathname of the file that will be loaded */
static char *pathname = NULL;
 
77,6 → 81,8
 
static bool is_dyn_linked;
 
/** Used to limit number of connections to one. */
static bool connected;
 
static void loader_get_taskid(ipc_callid_t rid, ipc_call_t *request)
{
92,7 → 98,8
return;
}
 
if (len > sizeof(task_id)) len = sizeof(task_id);
if (len > sizeof(task_id))
len = sizeof(task_id);
 
ipc_data_read_finalize(callid, &task_id, len);
ipc_answer_0(rid, EOK);
143,11 → 150,11
static void loader_set_args(ipc_callid_t rid, ipc_call_t *request)
{
ipc_callid_t callid;
size_t buf_len, arg_len;
size_t buf_size, arg_size;
char *p;
int n;
 
if (!ipc_data_write_receive(&callid, &buf_len)) {
if (!ipc_data_write_receive(&callid, &buf_size)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
163,7 → 170,7
argv = NULL;
}
 
arg_buf = malloc(buf_len + 1);
arg_buf = malloc(buf_size + 1);
if (!arg_buf) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
170,10 → 177,9
return;
}
 
ipc_data_write_finalize(callid, arg_buf, buf_len);
ipc_answer_0(rid, EOK);
ipc_data_write_finalize(callid, arg_buf, buf_size);
 
arg_buf[buf_len] = '\0';
arg_buf[buf_size] = '\0';
 
/*
* Count number of arguments
180,9 → 186,9
*/
p = arg_buf;
n = 0;
while (p < arg_buf + buf_len) {
arg_len = strlen(p);
p = p + arg_len + 1;
while (p < arg_buf + buf_size) {
arg_size = str_size(p);
p = p + arg_size + 1;
++n;
}
 
191,7 → 197,6
 
if (argv == NULL) {
free(arg_buf);
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
return;
}
201,16 → 206,18
*/
p = arg_buf;
n = 0;
while (p < arg_buf + buf_len) {
while (p < arg_buf + buf_size) {
argv[n] = p;
 
arg_len = strlen(p);
p = p + arg_len + 1;
arg_size = str_size(p);
p = p + arg_size + 1;
++n;
}
 
argc = n;
argv[n] = NULL;
 
ipc_answer_0(rid, EOK);
}
 
/** Load the previously selected program.
224,8 → 231,8
int rc;
 
rc = elf_load_file(pathname, 0, &prog_info);
if (rc < 0) {
printf("Failed to load executable '%s'.\n", pathname);
if (rc != EE_OK) {
DPRINTF("Failed to load executable '%s'.\n", pathname);
ipc_answer_0(rid, EINVAL);
return 1;
}
243,8 → 250,9
}
 
rc = elf_load_file(prog_info.interp, 0, &interp_info);
if (rc < 0) {
printf("Failed to load interpreter '%s.'\n", prog_info.interp);
if (rc != EE_OK) {
DPRINTF("Failed to load interpreter '%s.'\n",
prog_info.interp);
ipc_answer_0(rid, EINVAL);
return 1;
}
264,18 → 272,24
*/
static void loader_run(ipc_callid_t rid, ipc_call_t *request)
{
const char *cp;
/* Set the task name. */
cp = str_rchr(pathname, '/');
cp = (cp == NULL) ? pathname : (cp + 1);
task_set_name(cp);
if (is_dyn_linked == true) {
/* Dynamically linked program */
printf("run dynamic linker\n");
printf("entry point: 0x%lx\n", interp_info.entry);
close_console();
DPRINTF("Run ELF interpreter.\n");
DPRINTF("Entry point: 0x%lx\n", interp_info.entry);
console_close();
 
ipc_answer_0(rid, EOK);
elf_run(&interp_info, &pcb);
 
} else {
/* Statically linked program */
close_console();
console_close();
ipc_answer_0(rid, EOK);
elf_run(&prog_info, &pcb);
}
294,8 → 308,20
ipc_call_t call;
int retval;
 
/* Already have a connection? */
if (connected) {
ipc_answer_0(iid, ELIMIT);
return;
}
connected = true;
/* Accept the connection */
ipc_answer_0(iid, EOK);
/* Ignore parameters, the connection is already open */
(void)iid; (void)icall;
(void) iid;
(void) icall;
 
while (1) {
callid = async_get_call(&call);
324,7 → 350,7
}
if ((callid & IPC_CALLID_NOTIFICATION) == 0 &&
IPC_GET_METHOD(call) != IPC_M_PHONE_HUNGUP) {
printf("responding EINVAL to method %d\n",
DPRINTF("Responding EINVAL to method %d.\n",
IPC_GET_METHOD(call));
ipc_answer_0(callid, EINVAL);
}
335,31 → 361,20
*/
int main(int argc, char *argv[])
{
ipc_callid_t callid;
ipc_call_t call;
ipcarg_t phone_hash;
ipcarg_t phonead;
 
/* The first call only communicates the incoming phone hash */
callid = ipc_wait_for_call(&call);
connected = false;
 
if (IPC_GET_METHOD(call) != LOADER_HELLO) {
if (IPC_GET_METHOD(call) != IPC_M_PHONE_HUNGUP)
ipc_answer_0(callid, EINVAL);
return 1;
}
/* Set a handler of incomming connections. */
async_set_client_connection(loader_connection);
 
ipc_answer_0(callid, EOK);
phone_hash = call.in_phone_hash;
/* Register at naming service. */
if (ipc_connect_to_me(PHONE_NS, SERVICE_LOAD, 0, 0, &phonead) != 0)
return -1;
 
/*
* Up until now async must not be used as it couldn't
* handle incoming requests. (Which means e.g. printf()
* cannot be used)
*/
async_new_connection(phone_hash, 0, NULL, loader_connection);
async_manager();
 
/* not reached */
/* Never reached */
return 0;
}