source: mainline/uspace/lib/libc/generic/task.c@ 34a74ab

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

Merge program-loader related stuff from dynload branch to trunk. (huge)

  • Property mode set to 100644
File size: 4.1 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
45task_id_t task_get_id(void)
46{
47 task_id_t task_id;
48
49 (void) __SYSCALL1(SYS_TASK_GET_ID, (sysarg_t) &task_id);
50
51 return task_id;
52}
53
54static int task_spawn_loader(void)
55{
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
65static 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 */
125task_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 */
168error:
169 ipc_hangup(phone_id);
170 return 0;
171}
172
173/** @}
174 */
Note: See TracBrowser for help on using the repository browser.