00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00035 #include <ipc/loader.h>
00036 #include <ipc/services.h>
00037 #include <ipc/ns.h>
00038 #include <libc.h>
00039 #include <task.h>
00040 #include <str.h>
00041 #include <stdlib.h>
00042 #include <async.h>
00043 #include <errno.h>
00044 #include <vfs/vfs.h>
00045 #include <loader/loader.h>
00046
00057 int loader_spawn(const char *name)
00058 {
00059 return __SYSCALL2(SYS_PROGRAM_SPAWN_LOADER,
00060 (sysarg_t) name, str_size(name));
00061 }
00062
00063 loader_t *loader_connect(void)
00064 {
00065 int phone_id = service_connect_blocking(SERVICE_LOAD, 0, 0);
00066 if (phone_id < 0)
00067 return NULL;
00068
00069 loader_t *ldr = malloc(sizeof(loader_t));
00070 if (ldr == NULL)
00071 return NULL;
00072
00073 ldr->phone_id = phone_id;
00074 return ldr;
00075 }
00076
00087 int loader_get_task_id(loader_t *ldr, task_id_t *task_id)
00088 {
00089
00090 ipc_call_t answer;
00091 aid_t req = async_send_0(ldr->phone_id, LOADER_GET_TASKID, &answer);
00092 int rc = async_data_read_start(ldr->phone_id, task_id, sizeof(task_id_t));
00093 if (rc != EOK) {
00094 async_wait_for(req, NULL);
00095 return rc;
00096 }
00097
00098 sysarg_t retval;
00099 async_wait_for(req, &retval);
00100 return (int) retval;
00101 }
00102
00112 int loader_set_cwd(loader_t *ldr)
00113 {
00114 char *cwd;
00115 size_t len;
00116
00117 cwd = (char *) malloc(MAX_PATH_LEN + 1);
00118 if (!cwd)
00119 return ENOMEM;
00120 if (!getcwd(cwd, MAX_PATH_LEN + 1))
00121 str_cpy(cwd, MAX_PATH_LEN + 1, "/");
00122 len = str_length(cwd);
00123
00124 ipc_call_t answer;
00125 aid_t req = async_send_0(ldr->phone_id, LOADER_SET_CWD, &answer);
00126 int rc = async_data_write_start(ldr->phone_id, cwd, len);
00127 free(cwd);
00128 if (rc != EOK) {
00129 async_wait_for(req, NULL);
00130 return rc;
00131 }
00132
00133 sysarg_t retval;
00134 async_wait_for(req, &retval);
00135 return (int) retval;
00136 }
00137
00150 int loader_set_pathname(loader_t *ldr, const char *path)
00151 {
00152 size_t pa_len;
00153 char *pa = absolutize(path, &pa_len);
00154 if (!pa)
00155 return 0;
00156
00157
00158 ipc_call_t answer;
00159 aid_t req = async_send_0(ldr->phone_id, LOADER_SET_PATHNAME, &answer);
00160 int rc = async_data_write_start(ldr->phone_id, (void *) pa, pa_len);
00161 if (rc != EOK) {
00162 free(pa);
00163 async_wait_for(req, NULL);
00164 return rc;
00165 }
00166
00167 free(pa);
00168
00169 sysarg_t retval;
00170 async_wait_for(req, &retval);
00171 return (int) retval;
00172 }
00173
00186 int loader_set_args(loader_t *ldr, const char *const argv[])
00187 {
00188
00189
00190
00191
00192 const char *const *ap = argv;
00193 size_t buffer_size = 0;
00194 while (*ap != NULL) {
00195 buffer_size += str_size(*ap) + 1;
00196 ap++;
00197 }
00198
00199 char *arg_buf = malloc(buffer_size);
00200 if (arg_buf == NULL)
00201 return ENOMEM;
00202
00203
00204 ap = argv;
00205 char *dp = arg_buf;
00206
00207 while (*ap != NULL) {
00208 str_cpy(dp, buffer_size - (dp - arg_buf), *ap);
00209 dp += str_size(*ap) + 1;
00210 ap++;
00211 }
00212
00213
00214 ipc_call_t answer;
00215 aid_t req = async_send_0(ldr->phone_id, LOADER_SET_ARGS, &answer);
00216 sysarg_t rc = async_data_write_start(ldr->phone_id, (void *) arg_buf, buffer_size);
00217 if (rc != EOK) {
00218 async_wait_for(req, NULL);
00219 return rc;
00220 }
00221
00222 async_wait_for(req, &rc);
00223 if (rc != EOK)
00224 return rc;
00225
00226
00227 free(arg_buf);
00228
00229 return EOK;
00230 }
00231
00244 int loader_set_files(loader_t *ldr, fdi_node_t *const files[])
00245 {
00246
00247
00248
00249
00250 fdi_node_t *const *ap = files;
00251 size_t count = 0;
00252 while (*ap != NULL) {
00253 count++;
00254 ap++;
00255 }
00256
00257 fdi_node_t *files_buf;
00258 files_buf = (fdi_node_t *) malloc(count * sizeof(fdi_node_t));
00259 if (files_buf == NULL)
00260 return ENOMEM;
00261
00262
00263 size_t i;
00264 for (i = 0; i < count; i++)
00265 files_buf[i] = *files[i];
00266
00267
00268 ipc_call_t answer;
00269 aid_t req = async_send_0(ldr->phone_id, LOADER_SET_FILES, &answer);
00270 sysarg_t rc = async_data_write_start(ldr->phone_id, (void *) files_buf,
00271 count * sizeof(fdi_node_t));
00272 if (rc != EOK) {
00273 async_wait_for(req, NULL);
00274 return rc;
00275 }
00276
00277 async_wait_for(req, &rc);
00278 if (rc != EOK)
00279 return rc;
00280
00281
00282 free(files_buf);
00283
00284 return EOK;
00285 }
00286
00297 int loader_load_program(loader_t *ldr)
00298 {
00299 return (int) async_req_0_0(ldr->phone_id, LOADER_LOAD);
00300 }
00301
00316 int loader_run(loader_t *ldr)
00317 {
00318 int rc = async_req_0_0(ldr->phone_id, LOADER_RUN);
00319 if (rc != EOK)
00320 return rc;
00321
00322 async_hangup(ldr->phone_id);
00323 ldr->phone_id = 0;
00324 return EOK;
00325 }
00326
00338 void loader_abort(loader_t *ldr)
00339 {
00340 async_hangup(ldr->phone_id);
00341 ldr->phone_id = 0;
00342 }
00343