diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-02-19 14:13:20 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-02-19 14:13:20 +0000 |
commit | 671ca33aa1804c1c4e26bf83635206dce7ed2623 (patch) | |
tree | 4bf32b2810361b905bb7e8e1796b1cc22da0eb81 /init/init.c | |
parent | a58a637bed06f6d794fcf822d08df926812ccd23 (diff) | |
download | busybox-w32-671ca33aa1804c1c4e26bf83635206dce7ed2623.tar.gz busybox-w32-671ca33aa1804c1c4e26bf83635206dce7ed2623.tar.bz2 busybox-w32-671ca33aa1804c1c4e26bf83635206dce7ed2623.zip |
init: make it NOMMU-capable
httpd: trivial compile fix
Diffstat (limited to 'init/init.c')
-rw-r--r-- | init/init.c | 50 |
1 files changed, 31 insertions, 19 deletions
diff --git a/init/init.c b/init/init.c index a82b45b7c..13410ac39 100644 --- a/init/init.c +++ b/init/init.c | |||
@@ -117,11 +117,13 @@ static void loop_forever(void) | |||
117 | } | 117 | } |
118 | 118 | ||
119 | /* Print a message to the specified device. | 119 | /* Print a message to the specified device. |
120 | * Device may be bitwise-or'd from L_LOG | L_CONSOLE */ | 120 | * "where" may be bitwise-or'd from L_LOG | L_CONSOLE |
121 | * NB: careful, we can be called after vfork! | ||
122 | */ | ||
121 | #define messageD(...) do { if (ENABLE_DEBUG_INIT) message(__VA_ARGS__); } while (0) | 123 | #define messageD(...) do { if (ENABLE_DEBUG_INIT) message(__VA_ARGS__); } while (0) |
122 | static void message(int device, const char *fmt, ...) | 124 | static void message(int where, const char *fmt, ...) |
123 | __attribute__ ((format(printf, 2, 3))); | 125 | __attribute__ ((format(printf, 2, 3))); |
124 | static void message(int device, const char *fmt, ...) | 126 | static void message(int where, const char *fmt, ...) |
125 | { | 127 | { |
126 | static int log_fd = -1; | 128 | static int log_fd = -1; |
127 | va_list arguments; | 129 | va_list arguments; |
@@ -137,7 +139,7 @@ static void message(int device, const char *fmt, ...) | |||
137 | 139 | ||
138 | if (ENABLE_FEATURE_INIT_SYSLOG) { | 140 | if (ENABLE_FEATURE_INIT_SYSLOG) { |
139 | /* Log the message to syslogd */ | 141 | /* Log the message to syslogd */ |
140 | if (device & L_LOG) { | 142 | if (where & L_LOG) { |
141 | /* don't out "\r" */ | 143 | /* don't out "\r" */ |
142 | openlog(applet_name, 0, LOG_DAEMON); | 144 | openlog(applet_name, 0, LOG_DAEMON); |
143 | syslog(LOG_INFO, "init: %s", msg + 1); | 145 | syslog(LOG_INFO, "init: %s", msg + 1); |
@@ -157,20 +159,20 @@ static void message(int device, const char *fmt, ...) | |||
157 | log_fd = device_open(log_console, O_WRONLY | O_NONBLOCK | O_NOCTTY); | 159 | log_fd = device_open(log_console, O_WRONLY | O_NONBLOCK | O_NOCTTY); |
158 | if (log_fd < 0) { | 160 | if (log_fd < 0) { |
159 | bb_error_msg("can't log to %s", log_console); | 161 | bb_error_msg("can't log to %s", log_console); |
160 | device = L_CONSOLE; | 162 | where = L_CONSOLE; |
161 | } else { | 163 | } else { |
162 | close_on_exec_on(log_fd); | 164 | close_on_exec_on(log_fd); |
163 | } | 165 | } |
164 | } | 166 | } |
165 | } | 167 | } |
166 | if (device & L_LOG) { | 168 | if (where & L_LOG) { |
167 | full_write(log_fd, msg, l); | 169 | full_write(log_fd, msg, l); |
168 | if (log_fd == 2) | 170 | if (log_fd == 2) |
169 | return; /* don't print dup messages */ | 171 | return; /* don't print dup messages */ |
170 | } | 172 | } |
171 | } | 173 | } |
172 | 174 | ||
173 | if (device & L_CONSOLE) { | 175 | if (where & L_CONSOLE) { |
174 | /* Send console messages to console so people will see them. */ | 176 | /* Send console messages to console so people will see them. */ |
175 | full_write(2, msg, l); | 177 | full_write(2, msg, l); |
176 | } | 178 | } |
@@ -233,7 +235,8 @@ static void console_init(void) | |||
233 | putenv((char*)"TERM=linux"); | 235 | putenv((char*)"TERM=linux"); |
234 | } | 236 | } |
235 | 237 | ||
236 | /* Set terminal settings to reasonable defaults */ | 238 | /* Set terminal settings to reasonable defaults. |
239 | * NB: careful, we can be called after vfork! */ | ||
237 | static void set_sane_term(void) | 240 | static void set_sane_term(void) |
238 | { | 241 | { |
239 | struct termios tty; | 242 | struct termios tty; |
@@ -270,7 +273,8 @@ static void set_sane_term(void) | |||
270 | tcsetattr(STDIN_FILENO, TCSANOW, &tty); | 273 | tcsetattr(STDIN_FILENO, TCSANOW, &tty); |
271 | } | 274 | } |
272 | 275 | ||
273 | /* Open the new terminal device */ | 276 | /* Open the new terminal device. |
277 | * NB: careful, we can be called after vfork! */ | ||
274 | static void open_stdio_to_tty(const char* tty_name, int exit_on_failure) | 278 | static void open_stdio_to_tty(const char* tty_name, int exit_on_failure) |
275 | { | 279 | { |
276 | /* empty tty_name means "use init's tty", else... */ | 280 | /* empty tty_name means "use init's tty", else... */ |
@@ -286,6 +290,8 @@ static void open_stdio_to_tty(const char* tty_name, int exit_on_failure) | |||
286 | _exit(1); | 290 | _exit(1); |
287 | if (ENABLE_DEBUG_INIT) | 291 | if (ENABLE_DEBUG_INIT) |
288 | _exit(2); | 292 | _exit(2); |
293 | /* NB: we don't reach this if we were called after vfork. | ||
294 | * Thus halt_reboot_pwoff() itself need not be vfork-safe. */ | ||
289 | halt_reboot_pwoff(SIGUSR1); /* halt the system */ | 295 | halt_reboot_pwoff(SIGUSR1); /* halt the system */ |
290 | } | 296 | } |
291 | dup2(0, 1); | 297 | dup2(0, 1); |
@@ -294,22 +300,24 @@ static void open_stdio_to_tty(const char* tty_name, int exit_on_failure) | |||
294 | set_sane_term(); | 300 | set_sane_term(); |
295 | } | 301 | } |
296 | 302 | ||
297 | /* wrapper around exec: | 303 | /* Wrapper around exec: |
298 | * takes string (max COMMAND_SIZE chars) | 304 | * Takes string (max COMMAND_SIZE chars). |
299 | * runs [-]/bin/sh -c "exec ......." if '>' etc detected. | 305 | * If chars like '>' detected, execs '[-]/bin/sh -c "exec ......."'. |
300 | * otherwise splits words on whitespace and deals with leading dash. | 306 | * Otherwise splits words on whitespace, deals with leading dash, |
307 | * and uses plain exec(). | ||
308 | * NB: careful, we can be called after vfork! | ||
301 | */ | 309 | */ |
302 | static void init_exec(const char *command) | 310 | static void init_exec(const char *command) |
303 | { | 311 | { |
304 | char *cmd[COMMAND_SIZE / 2]; | 312 | char *cmd[COMMAND_SIZE / 2]; |
305 | char buf[COMMAND_SIZE + 6]; /* COMMAND_SIZE+strlen("exec ")+1 */ | 313 | char buf[COMMAND_SIZE + 6]; /* COMMAND_SIZE+strlen("exec ")+1 */ |
306 | int dash = (command[0] == '-'); | 314 | int dash = (command[0] == '-' /* maybe? && command[1] == '/' */); |
307 | 315 | ||
308 | /* See if any special /bin/sh requiring characters are present */ | 316 | /* See if any special /bin/sh requiring characters are present */ |
309 | if (strpbrk(command, "~`!$^&*()=|\\{}[];\"'<>?") != NULL) { | 317 | if (strpbrk(command, "~`!$^&*()=|\\{}[];\"'<>?") != NULL) { |
310 | strcpy(buf, "exec "); | 318 | strcpy(buf, "exec "); |
311 | strcpy(buf + 5, command + dash); /* excluding "-" */ | 319 | strcpy(buf + 5, command + dash); /* excluding "-" */ |
312 | /* LIBBB_DEFAULT_LOGIN_SHELL has leading dash */ | 320 | /* NB: LIBBB_DEFAULT_LOGIN_SHELL define has leading dash */ |
313 | cmd[0] = (char*)(LIBBB_DEFAULT_LOGIN_SHELL + !dash); | 321 | cmd[0] = (char*)(LIBBB_DEFAULT_LOGIN_SHELL + !dash); |
314 | cmd[1] = (char*)"-c"; | 322 | cmd[1] = (char*)"-c"; |
315 | cmd[2] = buf; | 323 | cmd[2] = buf; |
@@ -351,7 +359,7 @@ static pid_t run(const struct init_action *a) | |||
351 | sigemptyset(&nmask); | 359 | sigemptyset(&nmask); |
352 | sigaddset(&nmask, SIGCHLD); | 360 | sigaddset(&nmask, SIGCHLD); |
353 | sigprocmask(SIG_BLOCK, &nmask, &omask); | 361 | sigprocmask(SIG_BLOCK, &nmask, &omask); |
354 | pid = fork(); | 362 | pid = vfork(); |
355 | sigprocmask(SIG_SETMASK, &omask, NULL); | 363 | sigprocmask(SIG_SETMASK, &omask, NULL); |
356 | 364 | ||
357 | if (pid < 0) | 365 | if (pid < 0) |
@@ -379,8 +387,9 @@ static pid_t run(const struct init_action *a) | |||
379 | setsid(); | 387 | setsid(); |
380 | 388 | ||
381 | /* Open the new terminal device */ | 389 | /* Open the new terminal device */ |
382 | open_stdio_to_tty(a->terminal, 1 /* - exit if open fails*/); | 390 | open_stdio_to_tty(a->terminal, 1 /* - exit if open fails */); |
383 | 391 | ||
392 | // NB: do not enable unless you change vfork to fork above | ||
384 | #ifdef BUT_RUN_ACTIONS_ALREADY_DOES_WAITING | 393 | #ifdef BUT_RUN_ACTIONS_ALREADY_DOES_WAITING |
385 | /* If the init Action requires us to wait, then force the | 394 | /* If the init Action requires us to wait, then force the |
386 | * supplied terminal to be the controlling tty. */ | 395 | * supplied terminal to be the controlling tty. */ |
@@ -424,7 +433,9 @@ static pid_t run(const struct init_action *a) | |||
424 | /* Child - fall though to actually execute things */ | 433 | /* Child - fall though to actually execute things */ |
425 | } | 434 | } |
426 | #endif | 435 | #endif |
427 | if (a->action_type & ASKFIRST) { | 436 | |
437 | /* NB: on NOMMU we can't wait for input in child */ | ||
438 | if (BB_MMU && (a->action_type & ASKFIRST)) { | ||
428 | static const char press_enter[] ALIGN1 = | 439 | static const char press_enter[] ALIGN1 = |
429 | #ifdef CUSTOMIZED_BANNER | 440 | #ifdef CUSTOMIZED_BANNER |
430 | #include CUSTOMIZED_BANNER | 441 | #include CUSTOMIZED_BANNER |
@@ -809,7 +820,8 @@ static void reload_signal(int sig ATTRIBUTE_UNUSED) | |||
809 | } | 820 | } |
810 | } | 821 | } |
811 | #if CONFIG_FEATURE_KILL_DELAY | 822 | #if CONFIG_FEATURE_KILL_DELAY |
812 | if (fork() == 0) { /* child */ | 823 | /* NB: parent will wait in NOMMU case */ |
824 | if ((BB_MMU ? fork() : vfork()) == 0) { /* child */ | ||
813 | sleep(CONFIG_FEATURE_KILL_DELAY); | 825 | sleep(CONFIG_FEATURE_KILL_DELAY); |
814 | for (a = init_action_list; a; a = a->next) { | 826 | for (a = init_action_list; a; a = a->next) { |
815 | pid_t pid = a->pid; | 827 | pid_t pid = a->pid; |