Changeset c98e6ee in mainline for uspace/lib/libc/generic/task.c
- Timestamp:
- 2008-07-08T16:05:45Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f93f168
- Parents:
- b7f9087
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/libc/generic/task.c
rb7f9087 rc98e6ee 1 1 /* 2 2 * Copyright (c) 2006 Jakub Jermar 3 * Copyright (c) 2008 Jiri Svoboda 3 4 * All rights reserved. 4 5 * … … 34 35 35 36 #include <task.h> 37 #include <ipc/ipc.h> 38 #include <ipc/loader.h> 36 39 #include <libc.h> 40 #include <string.h> 41 #include <stdlib.h> 42 #include <async.h> 43 #include <errno.h> 37 44 38 45 task_id_t task_get_id(void) … … 45 52 } 46 53 47 int task_spawn(void *image, size_t size)54 static int task_spawn_loader(void) 48 55 { 49 return __SYSCALL2(SYS_TASK_SPAWN, (sysarg_t) image, (sysarg_t) size); 56 int phone_id, rc; 57 58 rc = __SYSCALL1(SYS_PROGRAM_SPAWN_LOADER, (sysarg_t) &phone_id); 59 if (rc != 0) 60 return rc; 61 62 return phone_id; 63 } 64 65 static int loader_set_args(int phone_id, const char *argv[]) 66 { 67 aid_t req; 68 ipc_call_t answer; 69 ipcarg_t rc; 70 71 const char **ap; 72 char *dp; 73 char *arg_buf; 74 size_t buffer_size; 75 size_t len; 76 77 /* 78 * Serialize the arguments into a single array. First 79 * compute size of the buffer needed. 80 */ 81 ap = argv; 82 buffer_size = 0; 83 while (*ap != NULL) { 84 buffer_size += strlen(*ap) + 1; 85 ++ap; 86 } 87 88 arg_buf = malloc(buffer_size); 89 if (arg_buf == NULL) return ENOMEM; 90 91 /* Now fill the buffer with null-terminated argument strings */ 92 ap = argv; 93 dp = arg_buf; 94 while (*ap != NULL) { 95 strcpy(dp, *ap); 96 dp += strlen(*ap) + 1; 97 98 ++ap; 99 } 100 101 /* Send serialized arguments to the loader */ 102 103 req = async_send_0(phone_id, LOADER_SET_ARGS, &answer); 104 rc = ipc_data_write_start(phone_id, (void *)arg_buf, buffer_size); 105 if (rc != EOK) { 106 async_wait_for(req, NULL); 107 return rc; 108 } 109 110 async_wait_for(req, &rc); 111 if (rc != EOK) return rc; 112 113 /* Free temporary buffer */ 114 free(arg_buf); 115 116 return EOK; 117 } 118 119 /** Create a new task by running an executable from VFS. 120 * 121 * @param path pathname of the binary to execute 122 * @param argv command-line arguments 123 * @return ID of the newly created task or zero on error. 124 */ 125 task_id_t task_spawn(const char *path, const char *argv[]) 126 { 127 int phone_id; 128 ipc_call_t answer; 129 aid_t req; 130 int rc; 131 ipcarg_t retval; 132 133 /* Spawn a program loader */ 134 phone_id = task_spawn_loader(); 135 if (phone_id < 0) return 0; 136 137 /* 138 * Say hello so that the loader knows the incoming connection's 139 * phone hash. 140 */ 141 rc = async_req_0_0(phone_id, LOADER_HELLO); 142 if (rc != EOK) return 0; 143 144 /* Send program pathname */ 145 req = async_send_0(phone_id, LOADER_SET_PATHNAME, &answer); 146 rc = ipc_data_write_start(phone_id, (void *)path, strlen(path)); 147 if (rc != EOK) { 148 async_wait_for(req, NULL); 149 return 1; 150 } 151 152 async_wait_for(req, &retval); 153 if (retval != EOK) goto error; 154 155 /* Send arguments */ 156 rc = loader_set_args(phone_id, argv); 157 if (rc != EOK) goto error; 158 159 /* Request loader to start the program */ 160 rc = async_req_0_0(phone_id, LOADER_RUN); 161 if (rc != EOK) goto error; 162 163 /* Success */ 164 ipc_hangup(phone_id); 165 return 1; 166 167 /* Error exit */ 168 error: 169 ipc_hangup(phone_id); 170 return 0; 50 171 } 51 172
Note:
See TracChangeset
for help on using the changeset viewer.