Changeset c98e6ee in mainline for uspace/lib/libc/generic


Ignore:
Timestamp:
2008-07-08T16:05:45Z (17 years ago)
Author:
Jiri Svoboda <jirik.svoboda@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f93f168
Parents:
b7f9087
Message:

Merge program-loader related stuff from dynload branch to trunk. (huge)

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

Legend:

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

    rb7f9087 rc98e6ee  
    8484{
    8585        return __SYSCALL1(SYS_AS_AREA_DESTROY, (sysarg_t ) address);
     86}
     87
     88/** Change address-space area flags.
     89 *
     90 * @param address Virtual address pointing into the address space area being
     91 *      modified.
     92 * @param flags New flags describing type of the area.
     93 *
     94 * @return Zero on success or a code from @ref errno.h on failure.
     95 */
     96int as_area_change_flags(void *address, int flags)
     97{
     98        return __SYSCALL2(SYS_AS_AREA_CHANGE_FLAGS, (sysarg_t) address,
     99            (sysarg_t) flags);
    86100}
    87101
  • uspace/lib/libc/generic/io/stream.c

    rb7f9087 rc98e6ee  
    9797}
    9898
     99void close_console(void)
     100{
     101        if (console_phone >= 0) {
     102                if (ipc_hangup(console_phone) == 0) {
     103                        console_phone = -1;
     104                }
     105        }
     106}
     107
    99108void klog_update(void)
    100109{
  • uspace/lib/libc/generic/libc.c

    rb7f9087 rc98e6ee  
    4949#include <async.h>
    5050#include <as.h>
     51#include <loader/pcb.h>
    5152
    5253extern char _heap;
     54extern int main(int argc, char *argv[]);
    5355
    5456void _exit(int status)
     
    5759}
    5860
    59 void __main(void)
     61void __main(void *pcb_ptr)
    6062{
    6163        fibril_t *f;
     64        int argc;
     65        char **argv;
    6266
    6367        (void) as_area_create(&_heap, 1, AS_AREA_WRITE | AS_AREA_READ);
     
    6771       
    6872        open_console();
     73
     74        /* Save the PCB pointer */
     75        __pcb = (pcb_t *)pcb_ptr;
     76
     77        if (__pcb == NULL) {
     78                argc = 0;
     79                argv = NULL;
     80        } else {
     81                argc = __pcb->argc;
     82                argv = __pcb->argv;
     83        }
     84
     85        main(argc, argv);
    6986}
    7087
  • uspace/lib/libc/generic/task.c

    rb7f9087 rc98e6ee  
    11/*
    22 * Copyright (c) 2006 Jakub Jermar
     3 * Copyright (c) 2008 Jiri Svoboda
    34 * All rights reserved.
    45 *
     
    3435
    3536#include <task.h>
     37#include <ipc/ipc.h>
     38#include <ipc/loader.h>
    3639#include <libc.h>
     40#include <string.h>
     41#include <stdlib.h>
     42#include <async.h>
     43#include <errno.h>
    3744
    3845task_id_t task_get_id(void)
     
    4552}
    4653
    47 int task_spawn(void *image, size_t size)
     54static int task_spawn_loader(void)
    4855{
    49         return __SYSCALL2(SYS_TASK_SPAWN, (sysarg_t) image, (sysarg_t) size);
     56        int phone_id, rc;
     57
     58        rc = __SYSCALL1(SYS_PROGRAM_SPAWN_LOADER, (sysarg_t) &phone_id);
     59        if (rc != 0)
     60                return rc;
     61
     62        return phone_id;
     63}
     64
     65static int loader_set_args(int phone_id, const char *argv[])
     66{
     67        aid_t req;
     68        ipc_call_t answer;
     69        ipcarg_t rc;
     70
     71        const char **ap;
     72        char *dp;
     73        char *arg_buf;
     74        size_t buffer_size;
     75        size_t len;
     76
     77        /*
     78         * Serialize the arguments into a single array. First
     79         * compute size of the buffer needed.
     80         */
     81        ap = argv;
     82        buffer_size = 0;
     83        while (*ap != NULL) {
     84                buffer_size += strlen(*ap) + 1;
     85                ++ap;
     86        }
     87
     88        arg_buf = malloc(buffer_size);
     89        if (arg_buf == NULL) return ENOMEM;
     90
     91        /* Now fill the buffer with null-terminated argument strings */
     92        ap = argv;
     93        dp = arg_buf;
     94        while (*ap != NULL) {
     95                strcpy(dp, *ap);
     96                dp += strlen(*ap) + 1;
     97
     98                ++ap;
     99        }
     100
     101        /* Send serialized arguments to the loader */
     102
     103        req = async_send_0(phone_id, LOADER_SET_ARGS, &answer);
     104        rc = ipc_data_write_start(phone_id, (void *)arg_buf, buffer_size);
     105        if (rc != EOK) {
     106                async_wait_for(req, NULL);
     107                return rc;
     108        }
     109
     110        async_wait_for(req, &rc);
     111        if (rc != EOK) return rc;
     112
     113        /* Free temporary buffer */
     114        free(arg_buf);
     115
     116        return EOK;
     117}
     118
     119/** Create a new task by running an executable from VFS.
     120 *
     121 * @param path  pathname of the binary to execute
     122 * @param argv  command-line arguments
     123 * @return      ID of the newly created task or zero on error.
     124 */
     125task_id_t task_spawn(const char *path, const char *argv[])
     126{
     127        int phone_id;
     128        ipc_call_t answer;
     129        aid_t req;
     130        int rc;
     131        ipcarg_t retval;
     132
     133        /* Spawn a program loader */   
     134        phone_id = task_spawn_loader();
     135        if (phone_id < 0) return 0;
     136
     137        /*
     138         * Say hello so that the loader knows the incoming connection's
     139         * phone hash.
     140         */
     141        rc = async_req_0_0(phone_id, LOADER_HELLO);
     142        if (rc != EOK) return 0;
     143
     144        /* Send program pathname */
     145        req = async_send_0(phone_id, LOADER_SET_PATHNAME, &answer);
     146        rc = ipc_data_write_start(phone_id, (void *)path, strlen(path));
     147        if (rc != EOK) {
     148                async_wait_for(req, NULL);
     149                return 1;
     150        }
     151
     152        async_wait_for(req, &retval);
     153        if (retval != EOK) goto error;
     154
     155        /* Send arguments */
     156        rc = loader_set_args(phone_id, argv);
     157        if (rc != EOK) goto error;
     158
     159        /* Request loader to start the program */       
     160        rc = async_req_0_0(phone_id, LOADER_RUN);
     161        if (rc != EOK) goto error;
     162
     163        /* Success */
     164        ipc_hangup(phone_id);
     165        return 1;
     166
     167        /* Error exit */
     168error:
     169        ipc_hangup(phone_id);
     170        return 0;
    50171}
    51172
Note: See TracChangeset for help on using the changeset viewer.