Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 937aeee in mainline


Ignore:
Timestamp:
2009-06-03T19:17:21Z (13 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master
Children:
433131d
Parents:
9db9b10
Message:

add support for passing preset files
cleanup

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/libc/generic/loader.c

    r9db9b10 r937aeee  
    3131 */
    3232/** @file
    33  */ 
     33 */
    3434
    3535#include <ipc/ipc.h>
     
    4848 *
    4949 * Spawns a new program loader task and returns the connection structure.
    50  * @param name  Symbolic name to set on the newly created task.
    51  * @return      Pointer to the loader connection structure (should be
    52  *              de-allocated using free() after use).
     50 *
     51 * @param name Symbolic name to set on the newly created task.
     52 *
     53 * @return Pointer to the loader connection structure (should be
     54 *         deallocated using free() after use).
     55 *
    5356 */
    5457int loader_spawn(const char *name)
     
    6063loader_t *loader_connect(void)
    6164{
    62         loader_t *ldr;
    63         int phone_id;
    64 
    65         phone_id = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_LOAD, 0, 0);
     65        int phone_id = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_LOAD, 0, 0);
    6666        if (phone_id < 0)
    6767                return NULL;
    68 
    69         ldr = malloc(sizeof(loader_t));
     68       
     69        loader_t *ldr = malloc(sizeof(loader_t));
    7070        if (ldr == NULL)
    7171                return NULL;
    72 
     72       
    7373        ldr->phone_id = phone_id;
    74         return ldr;     
     74        return ldr;
    7575}
    7676
     
    7979 * Retrieves the ID of the new task from the loader.
    8080 *
    81  * @param ldr           Loader connection structure.
    82  * @param task_id       Points to a variable where the ID should be stored.
    83  * @return              Zero on success or negative error code.
     81 * @param ldr     Loader connection structure.
     82 * @param task_id Points to a variable where the ID should be stored.
     83 *
     84 * @return Zero on success or negative error code.
     85 *
    8486 */
    8587int loader_get_task_id(loader_t *ldr, task_id_t *task_id)
    8688{
     89        /* Get task ID. */
    8790        ipc_call_t answer;
    88         aid_t req;
    89         int rc;
    90         ipcarg_t retval;
    91 
    92         /* Get task ID. */
    93         req = async_send_0(ldr->phone_id, LOADER_GET_TASKID, &answer);
    94         rc = ipc_data_read_start(ldr->phone_id, task_id, sizeof(task_id_t));
     91        aid_t req = async_send_0(ldr->phone_id, LOADER_GET_TASKID, &answer);
     92        int rc = ipc_data_read_start(ldr->phone_id, task_id, sizeof(task_id_t));
    9593        if (rc != EOK) {
    9694                async_wait_for(req, NULL);
    9795                return rc;
    9896        }
    99 
     97       
     98        ipcarg_t retval;
    10099        async_wait_for(req, &retval);
    101         return (int)retval;
     100        return (int) retval;
    102101}
    103102
     
    108107 * sending to the loader).
    109108 *
    110  * @param ldr           Loader connection structure.
    111  * @param path          Pathname of the program file.
    112  * @return              Zero on success or negative error code.
     109 * @param ldr  Loader connection structure.
     110 * @param path Pathname of the program file.
     111 *
     112 * @return Zero on success or negative error code.
     113 *
    113114 */
    114115int loader_set_pathname(loader_t *ldr, const char *path)
    115116{
    116         ipc_call_t answer;
    117         aid_t req;
    118         int rc;
    119         ipcarg_t retval;
    120 
    121         char *pa;
    122117        size_t pa_len;
    123 
    124         pa = absolutize(path, &pa_len);
     118        char *pa = absolutize(path, &pa_len);
    125119        if (!pa)
    126120                return 0;
    127 
     121       
    128122        /* Send program pathname */
    129         req = async_send_0(ldr->phone_id, LOADER_SET_PATHNAME, &answer);
    130         rc = ipc_data_write_start(ldr->phone_id, (void *)pa, pa_len);
     123        ipc_call_t answer;
     124        aid_t req = async_send_0(ldr->phone_id, LOADER_SET_PATHNAME, &answer);
     125        int rc = ipc_data_write_start(ldr->phone_id, (void *) pa, pa_len);
    131126        if (rc != EOK) {
    132127                async_wait_for(req, NULL);
    133128                return rc;
    134129        }
    135 
     130       
    136131        free(pa);
    137 
     132       
     133        ipcarg_t retval;
    138134        async_wait_for(req, &retval);
    139         return (int)retval;
    140 }
    141 
     135        return (int) retval;
     136}
    142137
    143138/** Set command-line arguments for the program.
     
    147142 * the command used to execute the program.
    148143 *
    149  * @param ldr           Loader connection structure.
    150  * @param argv          NULL-terminated array of pointers to arguments.
    151  * @return              Zero on success or negative error code.
     144 * @param ldr  Loader connection structure.
     145 * @param argv NULL-terminated array of pointers to arguments.
     146 *
     147 * @return Zero on success or negative error code.
     148 *
    152149 */
    153150int loader_set_args(loader_t *ldr, char *const argv[])
    154151{
    155         aid_t req;
    156         ipc_call_t answer;
    157         ipcarg_t rc;
    158 
    159         char *const *ap;
    160         char *dp;
    161         char *arg_buf;
    162         size_t buffer_size;
    163 
    164         /*
     152        /*
    165153         * Serialize the arguments into a single array. First
    166154         * compute size of the buffer needed.
    167155         */
    168         ap = argv;
    169         buffer_size = 0;
     156        char *const *ap = argv;
     157        size_t buffer_size = 0;
    170158        while (*ap != NULL) {
    171159                buffer_size += str_size(*ap) + 1;
    172                 ++ap;
    173         }
    174 
    175         arg_buf = malloc(buffer_size);
    176         if (arg_buf == NULL) return ENOMEM;
    177 
     160                ap++;
     161        }
     162       
     163        char *arg_buf = malloc(buffer_size);
     164        if (arg_buf == NULL)
     165                return ENOMEM;
     166       
    178167        /* Now fill the buffer with null-terminated argument strings */
    179168        ap = argv;
    180         dp = arg_buf;
    181 
     169        char *dp = arg_buf;
     170       
    182171        while (*ap != NULL) {
    183172                str_cpy(dp, buffer_size - (dp - arg_buf), *ap);
    184173                dp += str_size(*ap) + 1;
    185 
    186                 ++ap;
    187         }
    188 
     174                ap++;
     175        }
     176       
    189177        /* Send serialized arguments to the loader */
    190 
    191         req = async_send_0(ldr->phone_id, LOADER_SET_ARGS, &answer);
    192         rc = ipc_data_write_start(ldr->phone_id, (void *)arg_buf, buffer_size);
     178        ipc_call_t answer;
     179        aid_t req = async_send_0(ldr->phone_id, LOADER_SET_ARGS, &answer);
     180        ipcarg_t rc = ipc_data_write_start(ldr->phone_id, (void *) arg_buf, buffer_size);
    193181        if (rc != EOK) {
    194182                async_wait_for(req, NULL);
    195183                return rc;
    196184        }
    197 
     185       
    198186        async_wait_for(req, &rc);
    199         if (rc != EOK) return rc;
    200 
     187        if (rc != EOK)
     188                return rc;
     189       
    201190        /* Free temporary buffer */
    202191        free(arg_buf);
    203 
     192       
     193        return EOK;
     194}
     195
     196/** Set preset files for the program.
     197 *
     198 * Sets the vector of preset files to be passed to the loaded
     199 * program. By convention, the first three files represent stdin,
     200 * stdout and stderr respectively.
     201 *
     202 * @param ldr   Loader connection structure.
     203 * @param files NULL-terminated array of pointers to files.
     204 *
     205 * @return Zero on success or negative error code.
     206 *
     207 */
     208int loader_set_files(loader_t *ldr, fs_node_t *const files[])
     209{
     210        /*
     211         * Serialize the arguments into a single array. First
     212         * compute size of the buffer needed.
     213         */
     214        fs_node_t *const *ap = files;
     215        size_t count = 0;
     216        while (*ap != NULL) {
     217                count++;
     218                ap++;
     219        }
     220       
     221        fs_node_t *files_buf = (fs_node_t *) malloc(count * sizeof(fs_node_t));
     222        if (files_buf == NULL)
     223                return ENOMEM;
     224       
     225        /* Fill the buffer */
     226        size_t i;
     227        for (i = 0; i < count; i++)
     228                files_buf[i] = *files[i];
     229       
     230        /* Send serialized files to the loader */
     231        ipc_call_t answer;
     232        aid_t req = async_send_0(ldr->phone_id, LOADER_SET_FILES, &answer);
     233        ipcarg_t rc = ipc_data_write_start(ldr->phone_id, (void *) files_buf,
     234            count * sizeof(fs_node_t));
     235        if (rc != EOK) {
     236                async_wait_for(req, NULL);
     237                return rc;
     238        }
     239       
     240        async_wait_for(req, &rc);
     241        if (rc != EOK)
     242                return rc;
     243       
     244        /* Free temporary buffer */
     245        free(files_buf);
     246       
    204247        return EOK;
    205248}
     
    210253 * and is ready to be executed.
    211254 *
    212  * @param ldr           Loader connection structure.
    213  * @return              Zero on success or negative error code.
     255 * @param ldr Loader connection structure.
     256 *
     257 * @return Zero on success or negative error code.
     258 *
    214259 */
    215260int loader_load_program(loader_t *ldr)
    216261{
    217         int rc;
    218 
    219         rc = async_req_0_0(ldr->phone_id, LOADER_LOAD);
    220         if (rc != EOK)
    221                 return rc;
    222 
    223         return EOK;
     262        return (int) async_req_0_0(ldr->phone_id, LOADER_LOAD);
    224263}
    225264
     
    233272 * on the loader structure. It should be de-allocated using free().
    234273 *
    235  * @param ldr           Loader connection structure.
    236  * @return              Zero on success or negative error code.
     274 * @param ldr Loader connection structure.
     275 *
     276 * @return Zero on success or negative error code.
     277 *
    237278 */
    238279int loader_run(loader_t *ldr)
    239280{
    240         int rc;
    241 
    242         rc = async_req_0_0(ldr->phone_id, LOADER_RUN);
     281        int rc = async_req_0_0(ldr->phone_id, LOADER_RUN);
    243282        if (rc != EOK)
    244283                return rc;
    245 
     284       
    246285        ipc_hangup(ldr->phone_id);
    247286        ldr->phone_id = 0;
     
    255294 * on the loader structure. It should be de-allocated using free().
    256295 *
    257  * @param ldr           Loader connection structure.
    258  * @return              Zero on success or negative error code.
     296 * @param ldr Loader connection structure.
     297 *
     298 * @return Zero on success or negative error code.
     299 *
    259300 */
    260301void loader_abort(loader_t *ldr)
Note: See TracChangeset for help on using the changeset viewer.