svn commit: trunk/busybox/init
vda at busybox.net
vda at busybox.net
Sat Jan 31 19:26:14 UTC 2009
Author: vda
Date: 2009-01-31 19:26:12 +0000 (Sat, 31 Jan 2009)
New Revision: 25184
Log:
init: remove wait() loop on restart, it may be dangerous
Modified:
trunk/busybox/init/init.c
Changeset:
Modified: trunk/busybox/init/init.c
===================================================================
--- trunk/busybox/init/init.c 2009-01-31 19:08:20 UTC (rev 25183)
+++ trunk/busybox/init/init.c 2009-01-31 19:26:12 UTC (rev 25184)
@@ -418,14 +418,16 @@
_exit(-1);
}
-static struct init_action *mark_terminated(int pid)
+static struct init_action *mark_terminated(pid_t pid)
{
struct init_action *a;
- for (a = init_action_list; a; a = a->next) {
- if (a->pid == pid) {
- a->pid = 0;
- return a;
+ if (pid > 0) {
+ for (a = init_action_list; a; a = a->next) {
+ if (a->pid == pid) {
+ a->pid = 0;
+ return a;
+ }
}
}
return NULL;
@@ -444,7 +446,7 @@
mark_terminated(wpid);
/* Unsafe. SIGTSTP handler might have wait'ed it already */
/*if (wpid == pid) break;*/
- /* More reliable */
+ /* More reliable: */
if (kill(pid, 0))
break;
}
@@ -697,11 +699,11 @@
*/
static void stop_handler(int sig UNUSED_PARAM)
{
+ smallint saved_bb_got_signal;
int saved_errno;
- smallint saved_bb_got_signal;
+ saved_bb_got_signal = bb_got_signal;
saved_errno = errno;
- saved_bb_got_signal = bb_got_signal;
signal(SIGCONT, record_signo);
while (1) {
@@ -714,14 +716,13 @@
* code which is resilient against this.
*/
wpid = wait_any_nohang(NULL);
- if (wpid > 0)
- mark_terminated(wpid);
+ mark_terminated(wpid);
sleep(1);
}
signal(SIGCONT, SIG_DFL);
+ errno = saved_errno;
bb_got_signal = saved_bb_got_signal;
- errno = saved_errno;
}
/* Handler for QUIT - exec "restart" action,
@@ -747,8 +748,14 @@
if (open_stdio_to_tty(a->terminal)) {
dbg_message(L_CONSOLE, "Trying to re-exec %s", a->command);
- while (wait(NULL) > 0)
- continue;
+ /* Theoretically should be safe.
+ * But in practice, kernel bugs may leave
+ * unkillable processes, and wait() may block forever.
+ * Oh well. Hoping "new" init won't be too surprised
+ * by having children it didn't create.
+ */
+ //while (wait(NULL) > 0)
+ // continue;
init_exec(a->command);
}
/* Open or exec failed */
@@ -990,14 +997,14 @@
got_sigs |= check_delayed_sigs();
+ if (got_sigs)
+ goto dont_block;
/* Wait for any child process to exit.
* NB: "delayed" signals will also interrupt this wait(),
* bb_signals_recursive_norestart() set them up for that.
* This guarantees we won't be stuck here
* till next orphan dies.
*/
- if (got_sigs)
- goto dont_block;
wpid = wait(NULL);
while (wpid > 0) {
struct init_action *a = mark_terminated(wpid);
More information about the busybox-cvs
mailing list