Changeset 04803bf in mainline for uspace/srv/loader/main.c
- Timestamp:
- 2011-03-21T22:00:17Z (14 years ago)
- 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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/loader/main.c
rb50b5af2 r04803bf 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 … … 73 72 /** The Program control block */ 74 73 static pcb_t pcb; 74 75 /** Current working directory */ 76 static char *cwd = NULL; 75 77 76 78 /** Number of arguments */ … … 94 96 95 97 /** Used to limit number of connections to one. */ 96 static bool connected ;98 static bool connected = false; 97 99 98 100 static void ldr_get_taskid(ipc_callid_t rid, ipc_call_t *request) … … 104 106 task_id = task_get_id(); 105 107 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); 109 111 return; 110 112 } … … 113 115 len = sizeof(task_id); 114 116 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 */ 126 static 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 } 119 140 120 141 /** Receive a call setting pathname of the program to execute. … … 125 146 static void ldr_set_pathname(ipc_callid_t rid, ipc_call_t *request) 126 147 { 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); 154 159 } 155 160 … … 161 166 static void ldr_set_args(ipc_callid_t rid, ipc_call_t *request) 162 167 { 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); 232 224 } 233 225 … … 239 231 static void ldr_set_files(ipc_callid_t rid, ipc_call_t *request) 240 232 { 241 ipc_callid_t callid;233 fdi_node_t *buf; 242 234 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); 296 275 } 297 276 … … 309 288 if (rc != EE_OK) { 310 289 DPRINTF("Failed to load executable '%s'.\n", pathname); 311 ipc_answer_0(rid, EINVAL);290 async_answer_0(rid, EINVAL); 312 291 return 1; 313 292 } 314 293 315 294 elf_create_pcb(&prog_info, &pcb); 295 296 pcb.cwd = cwd; 316 297 317 298 pcb.argc = argc; … … 324 305 /* Statically linked program */ 325 306 is_dyn_linked = false; 326 ipc_answer_0(rid, EOK);307 async_answer_0(rid, EOK); 327 308 return 0; 328 309 } … … 333 314 DPRINTF("Failed to load interpreter '%s.'\n", 334 315 prog_info.interp); 335 ipc_answer_0(rid, EINVAL);316 async_answer_0(rid, EINVAL); 336 317 return 1; 337 318 } 338 319 339 320 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); 343 324 344 325 is_dyn_linked = true; 345 ipc_answer_0(rid, EOK);326 async_answer_0(rid, EOK); 346 327 347 328 return 0; … … 367 348 /* Dynamically linked program */ 368 349 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); 372 353 program_run(interp_info.entry, &pcb); 373 354 } else { 374 355 /* Statically linked program */ 375 ipc_answer_0(rid, EOK);356 async_answer_0(rid, EOK); 376 357 program_run(prog_info.entry, &pcb); 377 358 } … … 393 374 /* Already have a connection? */ 394 375 if (connected) { 395 ipc_answer_0(iid, ELIMIT);376 async_answer_0(iid, ELIMIT); 396 377 return; 397 378 } … … 400 381 401 382 /* Accept the connection */ 402 ipc_answer_0(iid, EOK);383 async_answer_0(iid, EOK); 403 384 404 385 /* Ignore parameters, the connection is already open */ … … 409 390 callid = async_get_call(&call); 410 391 411 switch (IPC_GET_ METHOD(call)) {392 switch (IPC_GET_IMETHOD(call)) { 412 393 case IPC_M_PHONE_HUNGUP: 413 394 exit(0); 414 395 case LOADER_GET_TASKID: 415 396 ldr_get_taskid(callid, &call); 397 continue; 398 case LOADER_SET_CWD: 399 ldr_set_cwd(callid, &call); 416 400 continue; 417 401 case LOADER_SET_PATHNAME: … … 434 418 break; 435 419 } 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) { 438 421 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); 441 424 } 442 425 } … … 447 430 int main(int argc, char *argv[]) 448 431 { 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 455 435 /* 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)); 458 438 if (rc != EOK) 459 439 return -1; 460 461 /* Set a handler of incomming connections. */462 async_set_client_connection(ldr_connection);463 440 464 441 /* 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) 466 443 return -2; 467 444 468 445 async_manager(); 469 446
Note:
See TracChangeset
for help on using the changeset viewer.