Changeset 04803bf in mainline for uspace/srv/loader/main.c


Ignore:
Timestamp:
2011-03-21T22:00:17Z (14 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
143932e3
Parents:
b50b5af2 (diff), 7308e84 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes (needs fixes).

File:
1 edited

Legend:

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

    rb50b5af2 r04803bf  
    5050#include <fcntl.h>
    5151#include <sys/types.h>
    52 #include <ipc/ipc.h>
    5352#include <ipc/services.h>
    5453#include <ipc/loader.h>
     
    5857#include <errno.h>
    5958#include <async.h>
    60 #include <string.h>
     59#include <str.h>
    6160#include <as.h>
    6261
     
    7372/** The Program control block */
    7473static pcb_t pcb;
     74
     75/** Current working directory */
     76static char *cwd = NULL;
    7577
    7678/** Number of arguments */
     
    9496
    9597/** Used to limit number of connections to one. */
    96 static bool connected;
     98static bool connected = false;
    9799
    98100static void ldr_get_taskid(ipc_callid_t rid, ipc_call_t *request)
     
    104106        task_id = task_get_id();
    105107       
    106         if (!ipc_data_read_receive(&callid, &len)) {
    107                 ipc_answer_0(callid, EINVAL);
    108                 ipc_answer_0(rid, EINVAL);
     108        if (!async_data_read_receive(&callid, &len)) {
     109                async_answer_0(callid, EINVAL);
     110                async_answer_0(rid, EINVAL);
    109111                return;
    110112        }
     
    113115                len = sizeof(task_id);
    114116       
    115         ipc_data_read_finalize(callid, &task_id, len);
    116         ipc_answer_0(rid, EOK);
    117 }
    118 
     117        async_data_read_finalize(callid, &task_id, len);
     118        async_answer_0(rid, EOK);
     119}
     120
     121/** Receive a call setting the current working directory.
     122 *
     123 * @param rid
     124 * @param request
     125 */
     126static void ldr_set_cwd(ipc_callid_t rid, ipc_call_t *request)
     127{
     128        char *buf;
     129        int rc = async_data_write_accept((void **) &buf, true, 0, 0, 0, NULL);
     130       
     131        if (rc == EOK) {
     132                if (cwd != NULL)
     133                        free(cwd);
     134               
     135                cwd = buf;
     136        }
     137       
     138        async_answer_0(rid, rc);
     139}
    119140
    120141/** Receive a call setting pathname of the program to execute.
     
    125146static void ldr_set_pathname(ipc_callid_t rid, ipc_call_t *request)
    126147{
    127         ipc_callid_t callid;
    128         size_t len;
    129         char *name_buf;
    130        
    131         if (!ipc_data_write_receive(&callid, &len)) {
    132                 ipc_answer_0(callid, EINVAL);
    133                 ipc_answer_0(rid, EINVAL);
    134                 return;
    135         }
    136        
    137         name_buf = malloc(len + 1);
    138         if (!name_buf) {
    139                 ipc_answer_0(callid, ENOMEM);
    140                 ipc_answer_0(rid, ENOMEM);
    141                 return;
    142         }
    143        
    144         ipc_data_write_finalize(callid, name_buf, len);
    145         ipc_answer_0(rid, EOK);
    146        
    147         if (pathname != NULL) {
    148                 free(pathname);
    149                 pathname = NULL;
    150         }
    151        
    152         name_buf[len] = '\0';
    153         pathname = name_buf;
     148        char *buf;
     149        int rc = async_data_write_accept((void **) &buf, true, 0, 0, 0, NULL);
     150       
     151        if (rc == EOK) {
     152                if (pathname != NULL)
     153                        free(pathname);
     154               
     155                pathname = buf;
     156        }
     157       
     158        async_answer_0(rid, rc);
    154159}
    155160
     
    161166static void ldr_set_args(ipc_callid_t rid, ipc_call_t *request)
    162167{
    163         ipc_callid_t callid;
    164         size_t buf_size, arg_size;
    165         char *p;
    166         int n;
    167        
    168         if (!ipc_data_write_receive(&callid, &buf_size)) {
    169                 ipc_answer_0(callid, EINVAL);
    170                 ipc_answer_0(rid, EINVAL);
    171                 return;
    172         }
    173        
    174         if (arg_buf != NULL) {
    175                 free(arg_buf);
    176                 arg_buf = NULL;
    177         }
    178        
    179         if (argv != NULL) {
    180                 free(argv);
    181                 argv = NULL;
    182         }
    183        
    184         arg_buf = malloc(buf_size + 1);
    185         if (!arg_buf) {
    186                 ipc_answer_0(callid, ENOMEM);
    187                 ipc_answer_0(rid, ENOMEM);
    188                 return;
    189         }
    190        
    191         ipc_data_write_finalize(callid, arg_buf, buf_size);
    192        
    193         arg_buf[buf_size] = '\0';
    194        
    195         /*
    196          * Count number of arguments
    197          */
    198         p = arg_buf;
    199         n = 0;
    200         while (p < arg_buf + buf_size) {
    201                 arg_size = str_size(p);
    202                 p = p + arg_size + 1;
    203                 ++n;
    204         }
    205        
    206         /* Allocate argv */
    207         argv = malloc((n + 1) * sizeof(char *));
    208        
    209         if (argv == NULL) {
    210                 free(arg_buf);
    211                 ipc_answer_0(rid, ENOMEM);
    212                 return;
    213         }
    214 
    215         /*
    216          * Fill argv with argument pointers
    217          */
    218         p = arg_buf;
    219         n = 0;
    220         while (p < arg_buf + buf_size) {
    221                 argv[n] = p;
    222                
    223                 arg_size = str_size(p);
    224                 p = p + arg_size + 1;
    225                 ++n;
    226         }
    227        
    228         argc = n;
    229         argv[n] = NULL;
    230 
    231         ipc_answer_0(rid, EOK);
     168        char *buf;
     169        size_t buf_size;
     170        int rc = async_data_write_accept((void **) &buf, true, 0, 0, 0, &buf_size);
     171       
     172        if (rc == EOK) {
     173                /*
     174                 * Count number of arguments
     175                 */
     176                char *cur = buf;
     177                int count = 0;
     178               
     179                while (cur < buf + buf_size) {
     180                        size_t arg_size = str_size(cur);
     181                        cur += arg_size + 1;
     182                        count++;
     183                }
     184               
     185                /*
     186                 * Allocate new argv
     187                 */
     188                char **_argv = (char **) malloc((count + 1) * sizeof(char *));
     189                if (_argv == NULL) {
     190                        free(buf);
     191                        async_answer_0(rid, ENOMEM);
     192                        return;
     193                }
     194               
     195                /*
     196                 * Fill the new argv with argument pointers
     197                 */
     198                cur = buf;
     199                count = 0;
     200                while (cur < buf + buf_size) {
     201                        _argv[count] = cur;
     202                       
     203                        size_t arg_size = str_size(cur);
     204                        cur += arg_size + 1;
     205                        count++;
     206                }
     207                _argv[count] = NULL;
     208               
     209                /*
     210                 * Copy temporary data to global variables
     211                 */
     212                if (arg_buf != NULL)
     213                        free(arg_buf);
     214               
     215                if (argv != NULL)
     216                        free(argv);
     217               
     218                argc = count;
     219                arg_buf = buf;
     220                argv = _argv;
     221        }
     222       
     223        async_answer_0(rid, rc);
    232224}
    233225
     
    239231static void ldr_set_files(ipc_callid_t rid, ipc_call_t *request)
    240232{
    241         ipc_callid_t callid;
     233        fdi_node_t *buf;
    242234        size_t buf_size;
    243         if (!ipc_data_write_receive(&callid, &buf_size)) {
    244                 ipc_answer_0(callid, EINVAL);
    245                 ipc_answer_0(rid, EINVAL);
    246                 return;
    247         }
    248        
    249         if ((buf_size % sizeof(fdi_node_t)) != 0) {
    250                 ipc_answer_0(callid, EINVAL);
    251                 ipc_answer_0(rid, EINVAL);
    252                 return;
    253         }
    254        
    255         if (fil_buf != NULL) {
    256                 free(fil_buf);
    257                 fil_buf = NULL;
    258         }
    259        
    260         if (filv != NULL) {
    261                 free(filv);
    262                 filv = NULL;
    263         }
    264        
    265         fil_buf = malloc(buf_size);
    266         if (!fil_buf) {
    267                 ipc_answer_0(callid, ENOMEM);
    268                 ipc_answer_0(rid, ENOMEM);
    269                 return;
    270         }
    271        
    272         ipc_data_write_finalize(callid, fil_buf, buf_size);
    273        
    274         int count = buf_size / sizeof(fdi_node_t);
    275        
    276         /* Allocate filvv */
    277         filv = malloc((count + 1) * sizeof(fdi_node_t *));
    278        
    279         if (filv == NULL) {
    280                 free(fil_buf);
    281                 ipc_answer_0(rid, ENOMEM);
    282                 return;
    283         }
    284        
    285         /*
    286          * Fill filv with argument pointers
    287          */
    288         int i;
    289         for (i = 0; i < count; i++)
    290                 filv[i] = &fil_buf[i];
    291        
    292         filc = count;
    293         filv[count] = NULL;
    294        
    295         ipc_answer_0(rid, EOK);
     235        int rc = async_data_write_accept((void **) &buf, false, 0, 0,
     236            sizeof(fdi_node_t), &buf_size);
     237       
     238        if (rc == EOK) {
     239                int count = buf_size / sizeof(fdi_node_t);
     240               
     241                /*
     242                 * Allocate new filv
     243                 */
     244                fdi_node_t **_filv = (fdi_node_t **) calloc(count + 1, sizeof(fdi_node_t *));
     245                if (_filv == NULL) {
     246                        free(buf);
     247                        async_answer_0(rid, ENOMEM);
     248                        return;
     249                }
     250               
     251                /*
     252                 * Fill the new filv with argument pointers
     253                 */
     254                int i;
     255                for (i = 0; i < count; i++)
     256                        _filv[i] = &buf[i];
     257               
     258                _filv[count] = NULL;
     259               
     260                /*
     261                 * Copy temporary data to global variables
     262                 */
     263                if (fil_buf != NULL)
     264                        free(fil_buf);
     265               
     266                if (filv != NULL)
     267                        free(filv);
     268               
     269                filc = count;
     270                fil_buf = buf;
     271                filv = _filv;
     272        }
     273       
     274        async_answer_0(rid, EOK);
    296275}
    297276
     
    309288        if (rc != EE_OK) {
    310289                DPRINTF("Failed to load executable '%s'.\n", pathname);
    311                 ipc_answer_0(rid, EINVAL);
     290                async_answer_0(rid, EINVAL);
    312291                return 1;
    313292        }
    314293       
    315294        elf_create_pcb(&prog_info, &pcb);
     295       
     296        pcb.cwd = cwd;
    316297       
    317298        pcb.argc = argc;
     
    324305                /* Statically linked program */
    325306                is_dyn_linked = false;
    326                 ipc_answer_0(rid, EOK);
     307                async_answer_0(rid, EOK);
    327308                return 0;
    328309        }
     
    333314                DPRINTF("Failed to load interpreter '%s.'\n",
    334315                    prog_info.interp);
    335                 ipc_answer_0(rid, EINVAL);
     316                async_answer_0(rid, EINVAL);
    336317                return 1;
    337318        }
    338319       
    339320        printf("Run interpreter.\n");
    340         printf("entry point: 0x%lx\n", interp_info.entry);
    341         printf("pcb address: 0x%lx\n", &pcb);
    342         printf("prog dynamic: 0x%lx\n", prog_info.dynamic);
     321        printf("entry point: 0x%lx\n", (unsigned long) interp_info.entry);
     322        printf("pcb address: 0x%lx\n", (unsigned long) &pcb);
     323        printf("prog dynamic: 0x%lx\n", (unsigned long) prog_info.dynamic);
    343324
    344325        is_dyn_linked = true;
    345         ipc_answer_0(rid, EOK);
     326        async_answer_0(rid, EOK);
    346327       
    347328        return 0;
     
    367348                /* Dynamically linked program */
    368349                DPRINTF("Run ELF interpreter.\n");
    369                 DPRINTF("Entry point: 0x%lx\n", interp_info.entry);
    370                
    371                 ipc_answer_0(rid, EOK);
     350                DPRINTF("Entry point: %p\n", interp_info.entry);
     351               
     352                async_answer_0(rid, EOK);
    372353                program_run(interp_info.entry, &pcb);
    373354        } else {
    374355                /* Statically linked program */
    375                 ipc_answer_0(rid, EOK);
     356                async_answer_0(rid, EOK);
    376357                program_run(prog_info.entry, &pcb);
    377358        }
     
    393374        /* Already have a connection? */
    394375        if (connected) {
    395                 ipc_answer_0(iid, ELIMIT);
     376                async_answer_0(iid, ELIMIT);
    396377                return;
    397378        }
     
    400381       
    401382        /* Accept the connection */
    402         ipc_answer_0(iid, EOK);
     383        async_answer_0(iid, EOK);
    403384       
    404385        /* Ignore parameters, the connection is already open */
     
    409390                callid = async_get_call(&call);
    410391               
    411                 switch (IPC_GET_METHOD(call)) {
     392                switch (IPC_GET_IMETHOD(call)) {
    412393                case IPC_M_PHONE_HUNGUP:
    413394                        exit(0);
    414395                case LOADER_GET_TASKID:
    415396                        ldr_get_taskid(callid, &call);
     397                        continue;
     398                case LOADER_SET_CWD:
     399                        ldr_set_cwd(callid, &call);
    416400                        continue;
    417401                case LOADER_SET_PATHNAME:
     
    434418                        break;
    435419                }
    436                 if ((callid & IPC_CALLID_NOTIFICATION) == 0 &&
    437                     IPC_GET_METHOD(call) != IPC_M_PHONE_HUNGUP) {
     420                if (IPC_GET_IMETHOD(call) != IPC_M_PHONE_HUNGUP) {
    438421                        DPRINTF("Responding EINVAL to method %d.\n",
    439                             IPC_GET_METHOD(call));
    440                         ipc_answer_0(callid, EINVAL);
     422                            IPC_GET_IMETHOD(call));
     423                        async_answer_0(callid, EINVAL);
    441424                }
    442425        }
     
    447430int main(int argc, char *argv[])
    448431{
    449         ipcarg_t phonead;
    450         task_id_t id;
    451         int rc;
    452 
    453         connected = false;
    454 
     432        /* Set a handler of incomming connections. */
     433        async_set_client_connection(ldr_connection);
     434       
    455435        /* Introduce this task to the NS (give it our task ID). */
    456         id = task_get_id();
    457         rc = async_req_2_0(PHONE_NS, NS_ID_INTRO, LOWER32(id), UPPER32(id));
     436        task_id_t id = task_get_id();
     437        int rc = async_req_2_0(PHONE_NS, NS_ID_INTRO, LOWER32(id), UPPER32(id));
    458438        if (rc != EOK)
    459439                return -1;
    460 
    461         /* Set a handler of incomming connections. */
    462         async_set_client_connection(ldr_connection);
    463440       
    464441        /* Register at naming service. */
    465         if (ipc_connect_to_me(PHONE_NS, SERVICE_LOAD, 0, 0, &phonead) != 0)
     442        if (service_register(SERVICE_LOAD) != EOK)
    466443                return -2;
    467 
     444       
    468445        async_manager();
    469446       
Note: See TracChangeset for help on using the changeset viewer.