Changes in uspace/srv/loader/main.c [1ea99cc:ffa2c8ef] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/loader/main.c
r1ea99cc rffa2c8ef 50 50 #include <fcntl.h> 51 51 #include <sys/types.h> 52 #include <ipc/ipc.h>53 52 #include <ipc/services.h> 54 53 #include <ipc/loader.h> … … 58 57 #include <errno.h> 59 58 #include <async.h> 60 #include <str ing.h>59 #include <str.h> 61 60 #include <as.h> 62 61 … … 66 65 #define DPRINTF(...) 67 66 68 void program_run(void *entry, pcb_t *pcb);69 70 67 /** Pathname of the file that will be loaded */ 71 68 static char *pathname = NULL; … … 73 70 /** The Program control block */ 74 71 static pcb_t pcb; 72 73 /** Current working directory */ 74 static char *cwd = NULL; 75 75 76 76 /** Number of arguments */ … … 94 94 95 95 /** Used to limit number of connections to one. */ 96 static bool connected ;96 static bool connected = false; 97 97 98 98 static void ldr_get_taskid(ipc_callid_t rid, ipc_call_t *request) … … 104 104 task_id = task_get_id(); 105 105 106 if (! ipc_data_read_receive(&callid, &len)) {107 ipc_answer_0(callid, EINVAL);108 ipc_answer_0(rid, EINVAL);106 if (!async_data_read_receive(&callid, &len)) { 107 async_answer_0(callid, EINVAL); 108 async_answer_0(rid, EINVAL); 109 109 return; 110 110 } … … 113 113 len = sizeof(task_id); 114 114 115 ipc_data_read_finalize(callid, &task_id, len); 116 ipc_answer_0(rid, EOK); 117 } 118 115 async_data_read_finalize(callid, &task_id, len); 116 async_answer_0(rid, EOK); 117 } 118 119 /** Receive a call setting the current working directory. 120 * 121 * @param rid 122 * @param request 123 */ 124 static void ldr_set_cwd(ipc_callid_t rid, ipc_call_t *request) 125 { 126 char *buf; 127 int rc = async_data_write_accept((void **) &buf, true, 0, 0, 0, NULL); 128 129 if (rc == EOK) { 130 if (cwd != NULL) 131 free(cwd); 132 133 cwd = buf; 134 } 135 136 async_answer_0(rid, rc); 137 } 119 138 120 139 /** Receive a call setting pathname of the program to execute. … … 125 144 static void ldr_set_pathname(ipc_callid_t rid, ipc_call_t *request) 126 145 { 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; 146 char *buf; 147 int rc = async_data_write_accept((void **) &buf, true, 0, 0, 0, NULL); 148 149 if (rc == EOK) { 150 if (pathname != NULL) 151 free(pathname); 152 153 pathname = buf; 154 } 155 156 async_answer_0(rid, rc); 154 157 } 155 158 … … 161 164 static void ldr_set_args(ipc_callid_t rid, ipc_call_t *request) 162 165 { 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); 166 char *buf; 167 size_t buf_size; 168 int rc = async_data_write_accept((void **) &buf, true, 0, 0, 0, &buf_size); 169 170 if (rc == EOK) { 171 /* 172 * Count number of arguments 173 */ 174 char *cur = buf; 175 int count = 0; 176 177 while (cur < buf + buf_size) { 178 size_t arg_size = str_size(cur); 179 cur += arg_size + 1; 180 count++; 181 } 182 183 /* 184 * Allocate new argv 185 */ 186 char **_argv = (char **) malloc((count + 1) * sizeof(char *)); 187 if (_argv == NULL) { 188 free(buf); 189 async_answer_0(rid, ENOMEM); 190 return; 191 } 192 193 /* 194 * Fill the new argv with argument pointers 195 */ 196 cur = buf; 197 count = 0; 198 while (cur < buf + buf_size) { 199 _argv[count] = cur; 200 201 size_t arg_size = str_size(cur); 202 cur += arg_size + 1; 203 count++; 204 } 205 _argv[count] = NULL; 206 207 /* 208 * Copy temporary data to global variables 209 */ 210 if (arg_buf != NULL) 211 free(arg_buf); 212 213 if (argv != NULL) 214 free(argv); 215 216 argc = count; 217 arg_buf = buf; 218 argv = _argv; 219 } 220 221 async_answer_0(rid, rc); 232 222 } 233 223 … … 239 229 static void ldr_set_files(ipc_callid_t rid, ipc_call_t *request) 240 230 { 241 ipc_callid_t callid;231 fdi_node_t *buf; 242 232 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); 233 int rc = async_data_write_accept((void **) &buf, false, 0, 0, 234 sizeof(fdi_node_t), &buf_size); 235 236 if (rc == EOK) { 237 int count = buf_size / sizeof(fdi_node_t); 238 239 /* 240 * Allocate new filv 241 */ 242 fdi_node_t **_filv = (fdi_node_t **) calloc(count + 1, sizeof(fdi_node_t *)); 243 if (_filv == NULL) { 244 free(buf); 245 async_answer_0(rid, ENOMEM); 246 return; 247 } 248 249 /* 250 * Fill the new filv with argument pointers 251 */ 252 int i; 253 for (i = 0; i < count; i++) 254 _filv[i] = &buf[i]; 255 256 _filv[count] = NULL; 257 258 /* 259 * Copy temporary data to global variables 260 */ 261 if (fil_buf != NULL) 262 free(fil_buf); 263 264 if (filv != NULL) 265 free(filv); 266 267 filc = count; 268 fil_buf = buf; 269 filv = _filv; 270 } 271 272 async_answer_0(rid, EOK); 296 273 } 297 274 … … 306 283 int rc; 307 284 308 rc = elf_load_file(pathname, 0, 0,&prog_info);285 rc = elf_load_file(pathname, 0, &prog_info); 309 286 if (rc != EE_OK) { 310 287 DPRINTF("Failed to load executable '%s'.\n", pathname); 311 ipc_answer_0(rid, EINVAL);288 async_answer_0(rid, EINVAL); 312 289 return 1; 313 290 } 314 291 315 292 elf_create_pcb(&prog_info, &pcb); 293 294 pcb.cwd = cwd; 316 295 317 296 pcb.argc = argc; … … 324 303 /* Statically linked program */ 325 304 is_dyn_linked = false; 326 ipc_answer_0(rid, EOK);305 async_answer_0(rid, EOK); 327 306 return 0; 328 307 } 329 308 330 printf("Load ELF interpreter '%s'\n", prog_info.interp); 331 rc = elf_load_file(prog_info.interp, 0, 0, &interp_info); 309 rc = elf_load_file(prog_info.interp, 0, &interp_info); 332 310 if (rc != EE_OK) { 333 311 DPRINTF("Failed to load interpreter '%s.'\n", 334 312 prog_info.interp); 335 ipc_answer_0(rid, EINVAL);313 async_answer_0(rid, EINVAL); 336 314 return 1; 337 315 } 338 316 339 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);343 344 317 is_dyn_linked = true; 345 ipc_answer_0(rid, EOK);318 async_answer_0(rid, EOK); 346 319 347 320 return 0; … … 367 340 /* Dynamically linked program */ 368 341 DPRINTF("Run ELF interpreter.\n"); 369 DPRINTF("Entry point: 0x%lx\n", interp_info.entry);370 371 ipc_answer_0(rid, EOK);372 program_run(interp_info.entry, &pcb);342 DPRINTF("Entry point: %p\n", interp_info.entry); 343 344 async_answer_0(rid, EOK); 345 elf_run(&interp_info, &pcb); 373 346 } else { 374 347 /* Statically linked program */ 375 ipc_answer_0(rid, EOK);376 program_run(prog_info.entry, &pcb);348 async_answer_0(rid, EOK); 349 elf_run(&prog_info, &pcb); 377 350 } 378 351 … … 393 366 /* Already have a connection? */ 394 367 if (connected) { 395 ipc_answer_0(iid, ELIMIT);368 async_answer_0(iid, ELIMIT); 396 369 return; 397 370 } … … 400 373 401 374 /* Accept the connection */ 402 ipc_answer_0(iid, EOK);375 async_answer_0(iid, EOK); 403 376 404 377 /* Ignore parameters, the connection is already open */ … … 409 382 callid = async_get_call(&call); 410 383 411 switch (IPC_GET_ METHOD(call)) {384 switch (IPC_GET_IMETHOD(call)) { 412 385 case IPC_M_PHONE_HUNGUP: 413 386 exit(0); 414 387 case LOADER_GET_TASKID: 415 388 ldr_get_taskid(callid, &call); 389 continue; 390 case LOADER_SET_CWD: 391 ldr_set_cwd(callid, &call); 416 392 continue; 417 393 case LOADER_SET_PATHNAME: … … 434 410 break; 435 411 } 436 if ((callid & IPC_CALLID_NOTIFICATION) == 0 && 437 IPC_GET_METHOD(call) != IPC_M_PHONE_HUNGUP) { 412 if (IPC_GET_IMETHOD(call) != IPC_M_PHONE_HUNGUP) { 438 413 DPRINTF("Responding EINVAL to method %d.\n", 439 IPC_GET_ METHOD(call));440 ipc_answer_0(callid, EINVAL);414 IPC_GET_IMETHOD(call)); 415 async_answer_0(callid, EINVAL); 441 416 } 442 417 } … … 447 422 int main(int argc, char *argv[]) 448 423 { 449 ipcarg_t phonead; 450 task_id_t id; 451 int rc; 452 453 connected = false; 454 424 /* Set a handler of incomming connections. */ 425 async_set_client_connection(ldr_connection); 426 455 427 /* 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));428 task_id_t id = task_get_id(); 429 int rc = async_req_2_0(PHONE_NS, NS_ID_INTRO, LOWER32(id), UPPER32(id)); 458 430 if (rc != EOK) 459 431 return -1; 460 461 /* Set a handler of incomming connections. */462 async_set_client_connection(ldr_connection);463 432 464 433 /* Register at naming service. */ 465 if ( ipc_connect_to_me(PHONE_NS, SERVICE_LOAD, 0, 0, &phonead) != 0)434 if (service_register(SERVICE_LOAD) != EOK) 466 435 return -2; 467 436 468 437 async_manager(); 469 438
Note:
See TracChangeset
for help on using the changeset viewer.