Prex Home / Browse Source - Prex Version: 0.9.0

root/usr/server/exec/main.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. register_process
  2. exec_null
  3. exec_boot
  4. exec_debug
  5. exec_shutdown
  6. exec_init
  7. exception_handler
  8. main

   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 }

/* [<][>][^][v][top][bottom][index][help] */