source: mainline/uspace/lib/libc/generic/task.c@ 2e3355a

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 2e3355a was 2e3355a, checked in by Jiri Svoboda <jirik.svoboda@…>, 17 years ago

Include trace on sparc64 ramdisk. Assorted fixes.

  • Property mode set to 100644
File size: 4.5 KB
Line 
1/*
2 * Copyright (c) 2006 Jakub Jermar
3 * Copyright (c) 2008 Jiri Svoboda
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/** @addtogroup libc
31 * @{
32 */
33/** @file
34 */
35
36#include <task.h>
37#include <ipc/ipc.h>
38#include <ipc/loader.h>
39#include <libc.h>
40#include <string.h>
41#include <stdlib.h>
42#include <async.h>
43#include <errno.h>
44#include <vfs/vfs.h>
45
46task_id_t task_get_id(void)
47{
48 task_id_t task_id;
49
50 (void) __SYSCALL1(SYS_TASK_GET_ID, (sysarg_t) &task_id);
51
52 return task_id;
53}
54
55static int task_spawn_loader(void)
56{
57 int phone_id, rc;
58
59 rc = __SYSCALL1(SYS_PROGRAM_SPAWN_LOADER, (sysarg_t) &phone_id);
60 if (rc != 0)
61 return rc;
62
63 return phone_id;
64}
65
66static int loader_set_args(int phone_id, const char *argv[])
67{
68 aid_t req;
69 ipc_call_t answer;
70 ipcarg_t rc;
71
72 const char **ap;
73 char *dp;
74 char *arg_buf;
75 size_t buffer_size;
76 size_t len;
77
78 /*
79 * Serialize the arguments into a single array. First
80 * compute size of the buffer needed.
81 */
82 ap = argv;
83 buffer_size = 0;
84 while (*ap != NULL) {
85 buffer_size += strlen(*ap) + 1;
86 ++ap;
87 }
88
89 arg_buf = malloc(buffer_size);
90 if (arg_buf == NULL) return ENOMEM;
91
92 /* Now fill the buffer with null-terminated argument strings */
93 ap = argv;
94 dp = arg_buf;
95 while (*ap != NULL) {
96 strcpy(dp, *ap);
97 dp += strlen(*ap) + 1;
98
99 ++ap;
100 }
101
102 /* Send serialized arguments to the loader */
103
104 req = async_send_0(phone_id, LOADER_SET_ARGS, &answer);
105 rc = ipc_data_write_start(phone_id, (void *)arg_buf, buffer_size);
106 if (rc != EOK) {
107 async_wait_for(req, NULL);
108 return rc;
109 }
110
111 async_wait_for(req, &rc);
112 if (rc != EOK) return rc;
113
114 /* Free temporary buffer */
115 free(arg_buf);
116
117 return EOK;
118}
119
120/** Create a new task by running an executable from VFS.
121 *
122 * @param path pathname of the binary to execute
123 * @param argv command-line arguments
124 * @return ID of the newly created task or zero on error.
125 */
126task_id_t task_spawn(const char *path, char *const argv[])
127{
128 int phone_id;
129 ipc_call_t answer;
130 aid_t req;
131 int rc;
132 ipcarg_t retval;
133
134 char *pa;
135 size_t pa_len;
136 task_id_t task_id;
137
138 pa = absolutize(path, &pa_len);
139 if (!pa)
140 return 0;
141
142 /* Spawn a program loader */
143 phone_id = task_spawn_loader();
144 if (phone_id < 0)
145 return 0;
146
147 /*
148 * Say hello so that the loader knows the incoming connection's
149 * phone hash.
150 */
151 rc = async_req_0_0(phone_id, LOADER_HELLO);
152 if (rc != EOK)
153 return 0;
154
155 /* Get task ID. */
156 req = async_send_0(phone_id, LOADER_GET_TASKID, &answer);
157 rc = ipc_data_read_start(phone_id, &task_id, sizeof(task_id));
158 if (rc != EOK) {
159 async_wait_for(req, NULL);
160 goto error;
161 }
162
163 async_wait_for(req, &retval);
164 if (retval != EOK)
165 goto error;
166
167 /* Send program pathname */
168 req = async_send_0(phone_id, LOADER_SET_PATHNAME, &answer);
169 rc = ipc_data_write_start(phone_id, (void *)pa, pa_len);
170 if (rc != EOK) {
171 async_wait_for(req, NULL);
172 return 1;
173 }
174
175 async_wait_for(req, &retval);
176 if (retval != EOK)
177 goto error;
178
179 /* Send arguments */
180 rc = loader_set_args(phone_id, argv);
181 if (rc != EOK)
182 goto error;
183
184 /* Request loader to start the program */
185 rc = async_req_0_0(phone_id, LOADER_RUN);
186 if (rc != EOK)
187 goto error;
188
189 /* Success */
190 ipc_hangup(phone_id);
191 return task_id;
192
193 /* Error exit */
194error:
195 ipc_hangup(phone_id);
196 return 0;
197}
198
199/** @}
200 */
Note: See TracBrowser for help on using the repository browser.