Add BF_BINARY_PREFIX define to configure binary path by build system.
[barrelfish] / usr / spawnd / main.c
1 /**
2  * \file
3  * \brief Spawn daemon for Barrelfish.
4  * Offers a service on each core to spawn programs from
5  * the file system.
6  */
7
8 /*
9  * Copyright (c) 2010-2011, ETH Zurich.
10  * All rights reserved.
11  *
12  * This file is distributed under the terms in the attached LICENSE file.
13  * If you do not find this file, copies can be found by writing to:
14  * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
15  */
16
17 #include <stdio.h>
18 #include <string.h>
19
20 #include <barrelfish/barrelfish.h>
21 #include <barrelfish/dispatch.h>
22 #include <barrelfish_kpi/cpu.h> // for cpu_type_to_archstr()
23 #include <barrelfish/cpu_arch.h> // for CURRENT_CPU_TYPE
24
25 #include <vfs/vfs.h>
26
27 #include <if/monitor_defs.h>
28
29 #include "internal.h"
30
31 coreid_t my_core_id;
32 bool is_bsp_core;
33 const char *gbootmodules;
34
35 /* set an initial default environment for our boot-time children */
36 static void init_environ(void)
37 {
38     int r;
39
40     /* PATH=/arch/sbin */
41     char pathstr[64];
42     snprintf(pathstr, sizeof(pathstr), "/" BF_BINARY_PREFIX "%s/sbin",
43              cpu_type_to_archstr(CURRENT_CPU_TYPE));
44     pathstr[sizeof(pathstr) - 1] = '\0';
45     r = setenv("PATH", pathstr, 0);
46     if (r != 0) {
47         USER_PANIC("failed to set PATH");
48     }
49
50     /* HOME=/ */
51     r = setenv("HOME", "/", 0);
52     if (r != 0) {
53         USER_PANIC("failed to set HOME");
54     }
55 }
56
57 /* open bootmodules file and read it in */
58 static void get_bootmodules(void)
59 {
60     errval_t err;
61
62     // open bootmodules file and read it in
63     vfs_handle_t vh;
64     err = vfs_open("/bootmodules", &vh);
65     if (err_is_fail(err)) {
66         USER_PANIC_ERR(err, "unable to open /bootmodules");
67     }
68
69     struct vfs_fileinfo info;
70     err = vfs_stat(vh, &info);
71     if (err_is_fail(err)) {
72         USER_PANIC_ERR(err, "unable to stat /bootmodules");
73     }
74
75     char *bootmodules = malloc(info.size + 1);
76     if (bootmodules == NULL) {
77         USER_PANIC_ERR(LIB_ERR_MALLOC_FAIL,
78                        "failed to allocate memory for bootmodules");
79     }
80     size_t bootmodules_len;
81     err = vfs_read(vh, bootmodules, info.size, &bootmodules_len);
82     if (err_is_fail(err)) {
83         USER_PANIC_ERR(err, "unable to read /bootmodules");
84     } else if (bootmodules_len == 0) {
85         USER_PANIC_ERR(err, "/bootmodules is empty");
86     } else if (bootmodules_len != info.size) {
87         USER_PANIC_ERR(err, "unexpected short read of /bootmodules");
88     }
89
90     err = vfs_close(vh);
91     if (err_is_fail(err)) {
92         DEBUG_ERR(err, "could not close bottmodules file");
93     }
94
95     // terminate as a string
96     bootmodules[bootmodules_len] = '\0';
97     gbootmodules = bootmodules;
98
99 }
100
101 int main(int argc, const char *argv[])
102 {
103     errval_t err;
104
105     printf("Spawnd up.\n");
106
107
108     vfs_init();
109     
110     my_core_id = disp_get_core_id();
111
112
113     // read in the bootmodules file so that we know what to start
114     get_bootmodules();
115
116     // construct sane inital environment
117     init_environ();
118
119     err = start_service();
120     if (err_is_fail(err)) {
121             USER_PANIC_ERR(err, "failed to start spawnd service loop");
122     }
123
124     messages_handler_loop();
125 }