Statistics
| Branch: | Revision:

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
}