root / prex-0.9.0 / usr / server / exec / main.c @ 03e9c04a
History | View | Annotate | Download (4.84 KB)
1 |
/*-
|
---|---|
2 |
* Copyright (c) 2005-2007, Kohsuke Ohtani
|
3 |
* All rights reserved.
|
4 |
*
|
5 |
* Redistribution and use in source and binary forms, with or without
|
6 |
* modification, are permitted provided that the following conditions
|
7 |
* are met:
|
8 |
* 1. Redistributions of source code must retain the above copyright
|
9 |
* notice, this list of conditions and the following disclaimer.
|
10 |
* 2. Redistributions in binary form must reproduce the above copyright
|
11 |
* notice, this list of conditions and the following disclaimer in the
|
12 |
* documentation and/or other materials provided with the distribution.
|
13 |
* 3. Neither the name of the author nor the names of any co-contributors
|
14 |
* may be used to endorse or promote products derived from this software
|
15 |
* without specific prior written permission.
|
16 |
*
|
17 |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
18 |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
19 |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
20 |
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
21 |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
22 |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
23 |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
24 |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
25 |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
26 |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
27 |
* SUCH DAMAGE.
|
28 |
*/
|
29 |
|
30 |
/*
|
31 |
* Exec server - Execute various types of image files.
|
32 |
*/
|
33 |
|
34 |
#include <sys/prex.h> |
35 |
#include <sys/capability.h> |
36 |
#include <ipc/fs.h> |
37 |
#include <ipc/proc.h> |
38 |
#include <ipc/ipc.h> |
39 |
#include <sys/list.h> |
40 |
|
41 |
#include <limits.h> |
42 |
#include <unistd.h> |
43 |
#include <stdlib.h> |
44 |
#include <string.h> |
45 |
#include <stdio.h> |
46 |
#include <fcntl.h> |
47 |
#include <unistd.h> |
48 |
#include <assert.h> |
49 |
#include <errno.h> |
50 |
|
51 |
#include "exec.h" |
52 |
|
53 |
/* forward declarations */
|
54 |
static int exec_null(struct msg *); |
55 |
static int exec_debug(struct msg *); |
56 |
static int exec_boot(struct msg *); |
57 |
static int exec_shutdown(struct msg *); |
58 |
|
59 |
/*
|
60 |
* Message mapping
|
61 |
*/
|
62 |
struct msg_map {
|
63 |
int code;
|
64 |
int (*func)(struct msg *); |
65 |
}; |
66 |
|
67 |
#define MSGMAP(code, fn) {code, (int (*)(struct msg *))fn} |
68 |
|
69 |
static const struct msg_map execmsg_map[] = { |
70 |
MSGMAP(EXEC_EXECVE, exec_execve), |
71 |
MSGMAP(EXEC_BINDCAP, exec_bindcap), |
72 |
MSGMAP(STD_BOOT, exec_boot), |
73 |
MSGMAP(STD_SHUTDOWN, exec_shutdown), |
74 |
MSGMAP(STD_DEBUG, exec_debug), |
75 |
MSGMAP(0, exec_null),
|
76 |
}; |
77 |
|
78 |
static void |
79 |
register_process(void)
|
80 |
{ |
81 |
struct msg m;
|
82 |
object_t obj; |
83 |
int error;
|
84 |
|
85 |
error = object_lookup("!proc", &obj);
|
86 |
if (error)
|
87 |
sys_panic("exec: no proc");
|
88 |
|
89 |
m.hdr.code = PS_REGISTER; |
90 |
msg_send(obj, &m, sizeof(m));
|
91 |
} |
92 |
|
93 |
static int |
94 |
exec_null(struct msg *msg)
|
95 |
{ |
96 |
|
97 |
return 0; |
98 |
} |
99 |
|
100 |
static int |
101 |
exec_boot(struct msg *msg)
|
102 |
{ |
103 |
|
104 |
/* Check client's capability. */
|
105 |
if (task_chkcap(msg->hdr.task, CAP_PROTSERV) != 0) |
106 |
return EPERM;
|
107 |
|
108 |
/* Register to process server */
|
109 |
register_process(); |
110 |
|
111 |
/* Register to file server */
|
112 |
fslib_init(); |
113 |
|
114 |
return 0; |
115 |
} |
116 |
|
117 |
static int |
118 |
exec_debug(struct msg *msg)
|
119 |
{ |
120 |
|
121 |
#ifdef DEBUG
|
122 |
/* mstat(); */
|
123 |
#endif
|
124 |
return 0; |
125 |
} |
126 |
|
127 |
static int |
128 |
exec_shutdown(struct msg *msg)
|
129 |
{ |
130 |
|
131 |
DPRINTF(("exec_shutdown\n"));
|
132 |
return 0; |
133 |
} |
134 |
|
135 |
/*
|
136 |
* Initialize all exec loaders.
|
137 |
*/
|
138 |
static void |
139 |
exec_init(void)
|
140 |
{ |
141 |
struct exec_loader *ldr;
|
142 |
int i;
|
143 |
|
144 |
for (i = 0; i < nloader; i++) { |
145 |
ldr = &loader_table[i]; |
146 |
DPRINTF(("Initialize \'%s\' loader\n", ldr->el_name));
|
147 |
ldr->el_init(); |
148 |
} |
149 |
} |
150 |
|
151 |
static void |
152 |
exception_handler(int sig)
|
153 |
{ |
154 |
|
155 |
exception_return(); |
156 |
} |
157 |
|
158 |
/*
|
159 |
* Main routine for exec service.
|
160 |
*/
|
161 |
int
|
162 |
main(int argc, char *argv[]) |
163 |
{ |
164 |
const struct msg_map *map; |
165 |
struct msg *msg;
|
166 |
object_t obj; |
167 |
int error;
|
168 |
|
169 |
sys_log("Starting exec server\n");
|
170 |
|
171 |
/* Boost thread priority. */
|
172 |
thread_setpri(thread_self(), PRI_EXEC); |
173 |
|
174 |
/*
|
175 |
* Set capability for us
|
176 |
*/
|
177 |
bind_cap("/boot/exec", task_self());
|
178 |
|
179 |
/*
|
180 |
* Setup exception handler.
|
181 |
*/
|
182 |
exception_setup(exception_handler); |
183 |
|
184 |
/*
|
185 |
* Initialize exec loaders.
|
186 |
*/
|
187 |
exec_init(); |
188 |
|
189 |
/*
|
190 |
* Create an object to expose our service.
|
191 |
*/
|
192 |
error = object_create("!exec", &obj);
|
193 |
if (error)
|
194 |
sys_panic("fail to create object");
|
195 |
|
196 |
msg = malloc(MAX_EXECMSG); |
197 |
ASSERT(msg); |
198 |
|
199 |
/*
|
200 |
* Message loop
|
201 |
*/
|
202 |
for (;;) {
|
203 |
/*
|
204 |
* Wait for an incoming request.
|
205 |
*/
|
206 |
error = msg_receive(obj, msg, MAX_EXECMSG); |
207 |
if (error)
|
208 |
continue;
|
209 |
|
210 |
error = EINVAL; |
211 |
map = &execmsg_map[0];
|
212 |
while (map->code != 0) { |
213 |
if (map->code == msg->hdr.code) {
|
214 |
error = (*map->func)(msg); |
215 |
break;
|
216 |
} |
217 |
map++; |
218 |
} |
219 |
#ifdef DEBUG_EXEC
|
220 |
if (error)
|
221 |
DPRINTF(("exec: msg error=%d code=%x\n",
|
222 |
error, msg->hdr.code)); |
223 |
#endif
|
224 |
/*
|
225 |
* Reply to the client.
|
226 |
*
|
227 |
* Note: If EXEC_EXECVE request is handled successfully,
|
228 |
* the receiver task has been terminated here. But, we
|
229 |
* have to call msg_reply() even in such case to reset
|
230 |
* our IPC state.
|
231 |
*/
|
232 |
msg->hdr.status = error; |
233 |
error = msg_reply(obj, msg, MAX_EXECMSG); |
234 |
} |
235 |
} |