Changeset 45454e9b in mainline


Ignore:
Timestamp:
2008-09-24T07:56:47Z (16 years ago)
Author:
Jiri Svoboda <jirik.svoboda@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
4470e26
Parents:
3926f30
Message:

Introduce loader API in C library.

Location:
uspace/lib/libc
Files:
2 added
4 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/libc/Makefile

    r3926f30 r45454e9b  
    7272        generic/ipc.c \
    7373        generic/async.c \
     74        generic/loader.c \
    7475        generic/getopt.c \
    7576        generic/libadt/list.o \
  • uspace/lib/libc/generic/task.c

    r3926f30 r45454e9b  
    3535
    3636#include <task.h>
    37 #include <ipc/ipc.h>
    38 #include <ipc/loader.h>
    3937#include <libc.h>
    40 #include <string.h>
    4138#include <stdlib.h>
    42 #include <async.h>
    4339#include <errno.h>
    44 #include <vfs/vfs.h>
     40#include <loader/loader.h>
    4541
    4642task_id_t task_get_id(void)
     
    5349}
    5450
    55 static int task_spawn_loader(void)
    56 {
    57         int phone_id, rc;
    58 
    59         rc = __SYSCALL1(SYS_PROGRAM_SPAWN_LOADER, (sysarg_t) &phone_id);
    60         if (rc != 0)
    61                 return rc;
    62 
    63         return phone_id;
    64 }
    65 
    66 static int loader_set_args(int phone_id, const char *argv[])
    67 {
    68         aid_t req;
    69         ipc_call_t answer;
    70         ipcarg_t rc;
    71 
    72         const char **ap;
    73         char *dp;
    74         char *arg_buf;
    75         size_t buffer_size;
    76         size_t len;
    77 
    78         /*
    79          * Serialize the arguments into a single array. First
    80          * compute size of the buffer needed.
    81          */
    82         ap = argv;
    83         buffer_size = 0;
    84         while (*ap != NULL) {
    85                 buffer_size += strlen(*ap) + 1;
    86                 ++ap;
    87         }
    88 
    89         arg_buf = malloc(buffer_size);
    90         if (arg_buf == NULL) return ENOMEM;
    91 
    92         /* Now fill the buffer with null-terminated argument strings */
    93         ap = argv;
    94         dp = arg_buf;
    95         while (*ap != NULL) {
    96                 strcpy(dp, *ap);
    97                 dp += strlen(*ap) + 1;
    98 
    99                 ++ap;
    100         }
    101 
    102         /* Send serialized arguments to the loader */
    103 
    104         req = async_send_0(phone_id, LOADER_SET_ARGS, &answer);
    105         rc = ipc_data_write_start(phone_id, (void *)arg_buf, buffer_size);
    106         if (rc != EOK) {
    107                 async_wait_for(req, NULL);
    108                 return rc;
    109         }
    110 
    111         async_wait_for(req, &rc);
    112         if (rc != EOK) return rc;
    113 
    114         /* Free temporary buffer */
    115         free(arg_buf);
    116 
    117         return EOK;
    118 }
    119 
    120 /** Create a new task by running an executable from VFS.
     51/** Create a new task by running an executable from the filesystem.
     52 *
     53 * This is really just a convenience wrapper over the more complicated
     54 * loader API.
    12155 *
    12256 * @param path  pathname of the binary to execute
     
    12660task_id_t task_spawn(const char *path, char *const argv[])
    12761{
    128         int phone_id;
    129         ipc_call_t answer;
    130         aid_t req;
     62        loader_t *ldr;
     63        task_id_t task_id;
    13164        int rc;
    132         ipcarg_t retval;
    133 
    134         char *pa;
    135         size_t pa_len;
    136         task_id_t task_id;
    137 
    138         pa = absolutize(path, &pa_len);
    139         if (!pa)
    140                 return 0;
    14165
    14266        /* Spawn a program loader */   
    143         phone_id = task_spawn_loader();
    144         if (phone_id < 0)
    145                 return 0;
    146 
    147         /*
    148          * Say hello so that the loader knows the incoming connection's
    149          * phone hash.
    150          */
    151         rc = async_req_0_0(phone_id, LOADER_HELLO);
    152         if (rc != EOK)
     67        ldr = loader_spawn();
     68        if (ldr == NULL)
    15369                return 0;
    15470
    15571        /* Get task ID. */
    156         req = async_send_0(phone_id, LOADER_GET_TASKID, &answer);
    157         rc = ipc_data_read_start(phone_id, &task_id, sizeof(task_id));
    158         if (rc != EOK) {
    159                 async_wait_for(req, NULL);
    160                 goto error;
    161         }
    162 
    163         async_wait_for(req, &retval);
    164         if (retval != EOK)
     72        rc = loader_get_task_id(ldr, &task_id);
     73        if (rc != EOK)
    16574                goto error;
    16675
    16776        /* Send program pathname */
    168         req = async_send_0(phone_id, LOADER_SET_PATHNAME, &answer);
    169         rc = ipc_data_write_start(phone_id, (void *)pa, pa_len);
    170         if (rc != EOK) {
    171                 async_wait_for(req, NULL);
    172                 return 1;
    173         }
    174 
    175         async_wait_for(req, &retval);
    176         if (retval != EOK)
     77        rc = loader_set_pathname(ldr, path);
     78        if (rc != EOK)
    17779                goto error;
    17880
    17981        /* Send arguments */
    180         rc = loader_set_args(phone_id, argv);
     82        rc = loader_set_args(ldr, argv);
    18183        if (rc != EOK)
    18284                goto error;
    18385
    18486        /* Request loader to start the program */       
    185         rc = async_req_0_0(phone_id, LOADER_RUN);
     87        rc = loader_start_program(ldr);
    18688        if (rc != EOK)
    18789                goto error;
    18890
    18991        /* Success */
    190         ipc_hangup(phone_id);
    19192        return task_id;
    19293
    19394        /* Error exit */
    19495error:
    195         ipc_hangup(phone_id);
     96        loader_abort(ldr);
    19697        return 0;
    19798}
  • uspace/lib/libc/include/ipc/loader.h

    r3926f30 r45454e9b  
    3333 */
    3434
    35 #ifndef LIBC_LOADER_H_
    36 #define LIBC_LOADER_H_
     35#ifndef LIBC_IPC_LOADER_H_
     36#define LIBC_IPC_LOADER_H_
    3737
    3838#include <ipc/ipc.h>
  • uspace/lib/libc/include/loader/pcb.h

    r3926f30 r45454e9b  
    4141typedef void (*entry_point_t)(void);
    4242
    43 /**
     43/** Program Control Block.
     44 *
    4445 * Holds pointers to data passed from the program loader to the program
    4546 * and/or to the dynamic linker. This includes the program entry point,
Note: See TracChangeset for help on using the changeset viewer.