Ignore:
File:
1 edited

Legend:

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

    rb19e892 r153c7a29  
    4848#include <unistd.h>
    4949#include <stdbool.h>
     50#include <fcntl.h>
    5051#include <sys/types.h>
    5152#include <ipc/services.h>
     
    6162#include <elf/elf_load.h>
    6263#include <vfs/vfs.h>
    63 #include <vfs/inbox.h>
    6464
    6565#define DPRINTF(...)
    6666
    67 /** File that will be loaded */
    68 static char *progname = NULL;
    69 static int program_fd = -1;
     67/** Pathname of the file that will be loaded */
     68static char *pathname = NULL;
    7069
    7170/** The Program control block */
     
    8281static char *arg_buf = NULL;
    8382
    84 /** Inbox entries. */
    85 static struct pcb_inbox_entry inbox[INBOX_MAX_ENTRIES];
    86 static int inbox_entries = 0;
     83/** Number of preset files */
     84static unsigned int filc = 0;
    8785
    8886static elf_info_t prog_info;
     
    132130}
    133131
    134 /** Receive a call setting the program to execute.
    135  *
    136  * @param rid
    137  * @param request
    138  */
    139 static 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);
     132/** Receive a call setting pathname of the program to execute.
     133 *
     134 * @param rid
     135 * @param request
     136 */
     137static 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);
    164150}
    165151
     
    229215}
    230216
    231 /** Receive a call setting inbox files of the program to execute.
    232  *
    233  * @param rid
    234  * @param request
    235  */
    236 static 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++;
     217/** Receive a call setting preset files of the program to execute.
     218 *
     219 * @param rid
     220 * @param request
     221 */
     222static 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
    273243        async_answer_0(rid, EOK);
    274244}
     
    282252static int ldr_load(ipc_callid_t rid, ipc_call_t *request)
    283253{
    284         int rc = elf_load(program_fd, &prog_info);
     254        int rc;
     255       
     256        rc = elf_load(pathname, &prog_info);
    285257        if (rc != EE_OK) {
    286                 DPRINTF("Failed to load executable for '%s'.\n", progname);
     258                DPRINTF("Failed to load executable '%s'.\n", pathname);
    287259                async_answer_0(rid, EINVAL);
    288260                return 1;
     
    296268        pcb.argv = argv;
    297269       
    298         pcb.inbox = inbox;
    299         pcb.inbox_entries = inbox_entries;
     270        pcb.filc = filc;
    300271       
    301272        async_answer_0(rid, rc);
     
    311282static void ldr_run(ipc_callid_t rid, ipc_call_t *request)
    312283{
     284        const char *cp;
     285       
    313286        DPRINTF("Set task name\n");
    314287
    315288        /* Set the task name. */
    316         task_set_name(progname);
     289        cp = str_rchr(pathname, '/');
     290        cp = (cp == NULL) ? pathname : (cp + 1);
     291        task_set_name(cp);
    317292       
    318293        /* Run program */
     
    361336                        ldr_set_cwd(callid, &call);
    362337                        continue;
    363                 case LOADER_SET_PROGRAM:
    364                         ldr_set_program(callid, &call);
     338                case LOADER_SET_PATHNAME:
     339                        ldr_set_pathname(callid, &call);
    365340                        continue;
    366341                case LOADER_SET_ARGS:
    367342                        ldr_set_args(callid, &call);
    368343                        continue;
    369                 case LOADER_ADD_INBOX:
    370                         ldr_add_inbox(callid, &call);
     344                case LOADER_SET_FILES:
     345                        ldr_set_files(callid, &call);
    371346                        continue;
    372347                case LOADER_LOAD:
Note: See TracChangeset for help on using the changeset viewer.