Subversion Repositories HelenOS

Compare Revisions

Regard whitespace Rev 4475 → Rev 4476

/trunk/uspace/lib/libc/generic/loader.c
47,9 → 47,12
/** Connect to a new program loader.
*
* Spawns a new program loader task and returns the connection structure.
*
* @param name Symbolic name to set on the newly created task.
*
* @return Pointer to the loader connection structure (should be
* de-allocated using free() after use).
* deallocated using free() after use).
*
*/
int loader_spawn(const char *name)
{
59,14 → 62,11
 
loader_t *loader_connect(void)
{
loader_t *ldr;
int phone_id;
 
phone_id = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_LOAD, 0, 0);
int phone_id = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_LOAD, 0, 0);
if (phone_id < 0)
return NULL;
 
ldr = malloc(sizeof(loader_t));
loader_t *ldr = malloc(sizeof(loader_t));
if (ldr == NULL)
return NULL;
 
80,23 → 80,22
*
* @param ldr Loader connection structure.
* @param task_id Points to a variable where the ID should be stored.
*
* @return Zero on success or negative error code.
*
*/
int loader_get_task_id(loader_t *ldr, task_id_t *task_id)
{
/* Get task ID. */
ipc_call_t answer;
aid_t req;
int rc;
ipcarg_t retval;
 
/* Get task ID. */
req = async_send_0(ldr->phone_id, LOADER_GET_TASKID, &answer);
rc = ipc_data_read_start(ldr->phone_id, task_id, sizeof(task_id_t));
aid_t req = async_send_0(ldr->phone_id, LOADER_GET_TASKID, &answer);
int rc = ipc_data_read_start(ldr->phone_id, task_id, sizeof(task_id_t));
if (rc != EOK) {
async_wait_for(req, NULL);
return rc;
}
 
ipcarg_t retval;
async_wait_for(req, &retval);
return (int)retval;
}
109,25 → 108,21
*
* @param ldr Loader connection structure.
* @param path Pathname of the program file.
*
* @return Zero on success or negative error code.
*
*/
int loader_set_pathname(loader_t *ldr, const char *path)
{
ipc_call_t answer;
aid_t req;
int rc;
ipcarg_t retval;
 
char *pa;
size_t pa_len;
 
pa = absolutize(path, &pa_len);
char *pa = absolutize(path, &pa_len);
if (!pa)
return 0;
 
/* Send program pathname */
req = async_send_0(ldr->phone_id, LOADER_SET_PATHNAME, &answer);
rc = ipc_data_write_start(ldr->phone_id, (void *)pa, pa_len);
ipc_call_t answer;
aid_t req = async_send_0(ldr->phone_id, LOADER_SET_PATHNAME, &answer);
int rc = ipc_data_write_start(ldr->phone_id, (void *) pa, pa_len);
if (rc != EOK) {
async_wait_for(req, NULL);
return rc;
135,11 → 130,11
 
free(pa);
 
ipcarg_t retval;
async_wait_for(req, &retval);
return (int)retval;
}
 
 
/** Set command-line arguments for the program.
*
* Sets the vector of command-line arguments to be passed to the loaded
148,48 → 143,41
*
* @param ldr Loader connection structure.
* @param argv NULL-terminated array of pointers to arguments.
*
* @return Zero on success or negative error code.
*
*/
int loader_set_args(loader_t *ldr, char *const argv[])
{
aid_t req;
ipc_call_t answer;
ipcarg_t rc;
 
char *const *ap;
char *dp;
char *arg_buf;
size_t buffer_size;
 
/*
* Serialize the arguments into a single array. First
* compute size of the buffer needed.
*/
ap = argv;
buffer_size = 0;
char *const *ap = argv;
size_t buffer_size = 0;
while (*ap != NULL) {
buffer_size += str_size(*ap) + 1;
++ap;
ap++;
}
 
arg_buf = malloc(buffer_size);
if (arg_buf == NULL) return ENOMEM;
char *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;
char *dp = arg_buf;
 
while (*ap != NULL) {
str_cpy(dp, buffer_size - (dp - arg_buf), *ap);
dp += str_size(*ap) + 1;
 
++ap;
ap++;
}
 
/* Send serialized arguments to the loader */
 
req = async_send_0(ldr->phone_id, LOADER_SET_ARGS, &answer);
rc = ipc_data_write_start(ldr->phone_id, (void *)arg_buf, buffer_size);
ipc_call_t answer;
aid_t req = async_send_0(ldr->phone_id, LOADER_SET_ARGS, &answer);
ipcarg_t rc = ipc_data_write_start(ldr->phone_id, (void *) arg_buf, buffer_size);
if (rc != EOK) {
async_wait_for(req, NULL);
return rc;
196,7 → 184,8
}
 
async_wait_for(req, &rc);
if (rc != EOK) return rc;
if (rc != EOK)
return rc;
 
/* Free temporary buffer */
free(arg_buf);
204,25 → 193,75
return EOK;
}
 
/** Instruct loader to load the program.
/** Set preset files for the program.
*
* If this function succeeds, the program has been successfully loaded
* and is ready to be executed.
* Sets the vector of preset files to be passed to the loaded
* program. By convention, the first three files represent stdin,
* stdout and stderr respectively.
*
* @param ldr Loader connection structure.
* @param files NULL-terminated array of pointers to files.
*
* @return Zero on success or negative error code.
*
*/
int loader_load_program(loader_t *ldr)
int loader_set_files(loader_t *ldr, fs_node_t *const files[])
{
int rc;
/*
* Serialize the arguments into a single array. First
* compute size of the buffer needed.
*/
fs_node_t *const *ap = files;
size_t count = 0;
while (*ap != NULL) {
count++;
ap++;
}
 
rc = async_req_0_0(ldr->phone_id, LOADER_LOAD);
fs_node_t *files_buf = (fs_node_t *) malloc(count * sizeof(fs_node_t));
if (files_buf == NULL)
return ENOMEM;
/* Fill the buffer */
size_t i;
for (i = 0; i < count; i++)
files_buf[i] = *files[i];
/* Send serialized files to the loader */
ipc_call_t answer;
aid_t req = async_send_0(ldr->phone_id, LOADER_SET_FILES, &answer);
ipcarg_t rc = ipc_data_write_start(ldr->phone_id, (void *) files_buf,
count * sizeof(fs_node_t));
if (rc != EOK) {
async_wait_for(req, NULL);
return rc;
}
async_wait_for(req, &rc);
if (rc != EOK)
return rc;
 
/* Free temporary buffer */
free(files_buf);
return EOK;
}
 
/** Instruct loader to load the program.
*
* If this function succeeds, the program has been successfully loaded
* and is ready to be executed.
*
* @param ldr Loader connection structure.
*
* @return Zero on success or negative error code.
*
*/
int loader_load_program(loader_t *ldr)
{
return (int) async_req_0_0(ldr->phone_id, LOADER_LOAD);
}
 
/** Instruct loader to execute the program.
*
* Note that this function blocks until the loader actually replies
233,13 → 272,13
* on the loader structure. It should be de-allocated using free().
*
* @param ldr Loader connection structure.
*
* @return Zero on success or negative error code.
*
*/
int loader_run(loader_t *ldr)
{
int rc;
 
rc = async_req_0_0(ldr->phone_id, LOADER_RUN);
int rc = async_req_0_0(ldr->phone_id, LOADER_RUN);
if (rc != EOK)
return rc;
 
255,7 → 294,9
* on the loader structure. It should be de-allocated using free().
*
* @param ldr Loader connection structure.
*
* @return Zero on success or negative error code.
*
*/
void loader_abort(loader_t *ldr)
{