Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/loader/main.c

    r153c7a29 rb19e892  
    4848#include <unistd.h>
    4949#include <stdbool.h>
    50 #include <fcntl.h>
    5150#include <sys/types.h>
    5251#include <ipc/services.h>
     
    6261#include <elf/elf_load.h>
    6362#include <vfs/vfs.h>
     63#include <vfs/inbox.h>
    6464
    6565#define DPRINTF(...)
    6666
    67 /** Pathname of the file that will be loaded */
    68 static char *pathname = NULL;
     67/** File that will be loaded */
     68static char *progname = NULL;
     69static int program_fd = -1;
    6970
    7071/** The Program control block */
     
    8182static char *arg_buf = NULL;
    8283
    83 /** Number of preset files */
    84 static unsigned int filc = 0;
     84/** Inbox entries. */
     85static struct pcb_inbox_entry inbox[INBOX_MAX_ENTRIES];
     86static int inbox_entries = 0;
    8587
    8688static elf_info_t prog_info;
     
    130132}
    131133
    132 /** Receive a call setting pathname of the program to execute.
    133  *
    134  * @param rid
    135  * @param request
    136  */
    137 static void ldr_set_pathname(ipc_callid_t rid, ipc_call_t *request)
    138 {
    139         char *buf;
    140         int rc = async_data_write_accept((void **) &buf, true, 0, 0, 0, NULL);
    141        
    142         if (rc == EOK) {
    143                 if (pathname != NULL)
    144                         free(pathname);
    145                
    146                 pathname = buf;
    147         }
    148        
    149         async_answer_0(rid, rc);
     134/** Receive a call setting the program to execute.
     135 *
     136 * @param rid
     137 * @param request
     138 */
     139static void ldr_set_program(ipc_callid_t rid, ipc_call_t *request)
     140{
     141        ipc_callid_t writeid;
     142        size_t namesize;
     143        if (!async_data_write_receive(&writeid, &namesize)) {
     144                async_answer_0(rid, EINVAL);
     145                return;
     146        }
     147
     148        char* name = malloc(namesize);
     149        int rc = async_data_write_finalize(writeid, name, namesize);
     150        if (rc != EOK) {
     151                async_answer_0(rid, EINVAL);
     152                return;
     153        }
     154
     155        int file = vfs_receive_handle(true);
     156        if (file < 0) {
     157                async_answer_0(rid, EINVAL);
     158                return;
     159        }
     160       
     161        progname = name;
     162        program_fd = file;
     163        async_answer_0(rid, EOK);
    150164}
    151165
     
    215229}
    216230
    217 /** Receive a call setting preset files of the program to execute.
    218  *
    219  * @param rid
    220  * @param request
    221  */
    222 static void ldr_set_files(ipc_callid_t rid, ipc_call_t *request)
    223 {
    224         size_t count = IPC_GET_ARG1(*request);
    225 
    226         async_exch_t *vfs_exch = vfs_exchange_begin();
    227 
    228         for (filc = 0; filc < count; filc++) {
    229                 ipc_callid_t callid;
    230                 int fd;
    231 
    232                 if (!async_state_change_receive(&callid, NULL, NULL, NULL)) {
    233                         async_answer_0(callid, EINVAL);
    234                         break;
    235                 }
    236                 async_state_change_finalize(callid, vfs_exch);
    237                 fd = vfs_fd_wait();
    238                 assert(fd == (int) filc);
    239         }
    240 
    241         vfs_exchange_end(vfs_exch);
    242 
     231/** Receive a call setting inbox files of the program to execute.
     232 *
     233 * @param rid
     234 * @param request
     235 */
     236static void ldr_add_inbox(ipc_callid_t rid, ipc_call_t *request)
     237{
     238        if (inbox_entries == INBOX_MAX_ENTRIES) {
     239                async_answer_0(rid, ERANGE);
     240                return;
     241        }
     242
     243        ipc_callid_t writeid;
     244        size_t namesize;
     245        if (!async_data_write_receive(&writeid, &namesize)) {
     246                async_answer_0(rid, EINVAL);
     247                return;
     248        }
     249
     250        char* name = malloc(namesize);
     251        int rc = async_data_write_finalize(writeid, name, namesize);
     252        if (rc != EOK) {
     253                async_answer_0(rid, EINVAL);
     254                return;
     255        }
     256
     257        int file = vfs_receive_handle(true);
     258        if (file < 0) {
     259                async_answer_0(rid, EINVAL);
     260                return;
     261        }
     262
     263        /*
     264         * We need to set the root early for dynamically linked binaries so
     265         * that the loader can use it too.
     266         */
     267        if (str_cmp(name, "root") == 0)
     268                vfs_root_set(file);
     269
     270        inbox[inbox_entries].name = name;
     271        inbox[inbox_entries].file = file;
     272        inbox_entries++;
    243273        async_answer_0(rid, EOK);
    244274}
     
    252282static int ldr_load(ipc_callid_t rid, ipc_call_t *request)
    253283{
    254         int rc;
    255        
    256         rc = elf_load(pathname, &prog_info);
     284        int rc = elf_load(program_fd, &prog_info);
    257285        if (rc != EE_OK) {
    258                 DPRINTF("Failed to load executable '%s'.\n", pathname);
     286                DPRINTF("Failed to load executable for '%s'.\n", progname);
    259287                async_answer_0(rid, EINVAL);
    260288                return 1;
     
    268296        pcb.argv = argv;
    269297       
    270         pcb.filc = filc;
     298        pcb.inbox = inbox;
     299        pcb.inbox_entries = inbox_entries;
    271300       
    272301        async_answer_0(rid, rc);
     
    282311static void ldr_run(ipc_callid_t rid, ipc_call_t *request)
    283312{
    284         const char *cp;
    285        
    286313        DPRINTF("Set task name\n");
    287314
    288315        /* Set the task name. */
    289         cp = str_rchr(pathname, '/');
    290         cp = (cp == NULL) ? pathname : (cp + 1);
    291         task_set_name(cp);
     316        task_set_name(progname);
    292317       
    293318        /* Run program */
     
    336361                        ldr_set_cwd(callid, &call);
    337362                        continue;
    338                 case LOADER_SET_PATHNAME:
    339                         ldr_set_pathname(callid, &call);
     363                case LOADER_SET_PROGRAM:
     364                        ldr_set_program(callid, &call);
    340365                        continue;
    341366                case LOADER_SET_ARGS:
    342367                        ldr_set_args(callid, &call);
    343368                        continue;
    344                 case LOADER_SET_FILES:
    345                         ldr_set_files(callid, &call);
     369                case LOADER_ADD_INBOX:
     370                        ldr_add_inbox(callid, &call);
    346371                        continue;
    347372                case LOADER_LOAD:
Note: See TracChangeset for help on using the changeset viewer.