aboutsummaryrefslogtreecommitdiff
path: root/init
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2009-01-31 19:26:12 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2009-01-31 19:26:12 +0000
commit9ec0ecbfdde2396c4c1c91b4a040ccb006f424c2 (patch)
tree1a5d4a1c3f542afe6ed737f297c1a77e822e593f /init
parent4ae8a05b131836184eb32c440a6bf814ff81b069 (diff)
downloadbusybox-w32-9ec0ecbfdde2396c4c1c91b4a040ccb006f424c2.tar.gz
busybox-w32-9ec0ecbfdde2396c4c1c91b4a040ccb006f424c2.tar.bz2
busybox-w32-9ec0ecbfdde2396c4c1c91b4a040ccb006f424c2.zip
init: remove wait() loop on restart, it may be dangerous
Diffstat (limited to 'init')
-rw-r--r--init/init.c37
1 files changed, 22 insertions, 15 deletions
diff --git a/init/init.c b/init/init.c
index 7ba8b67ec..68e624294 100644
--- a/init/init.c
+++ b/init/init.c
@@ -418,14 +418,16 @@ static pid_t run(const struct init_action *a)
418 _exit(-1); 418 _exit(-1);
419} 419}
420 420
421static struct init_action *mark_terminated(int pid) 421static struct init_action *mark_terminated(pid_t pid)
422{ 422{
423 struct init_action *a; 423 struct init_action *a;
424 424
425 for (a = init_action_list; a; a = a->next) { 425 if (pid > 0) {
426 if (a->pid == pid) { 426 for (a = init_action_list; a; a = a->next) {
427 a->pid = 0; 427 if (a->pid == pid) {
428 return a; 428 a->pid = 0;
429 return a;
430 }
429 } 431 }
430 } 432 }
431 return NULL; 433 return NULL;
@@ -444,7 +446,7 @@ static void waitfor(pid_t pid)
444 mark_terminated(wpid); 446 mark_terminated(wpid);
445 /* Unsafe. SIGTSTP handler might have wait'ed it already */ 447 /* Unsafe. SIGTSTP handler might have wait'ed it already */
446 /*if (wpid == pid) break;*/ 448 /*if (wpid == pid) break;*/
447 /* More reliable */ 449 /* More reliable: */
448 if (kill(pid, 0)) 450 if (kill(pid, 0))
449 break; 451 break;
450 } 452 }
@@ -697,11 +699,11 @@ static void halt_reboot_pwoff(int sig)
697 */ 699 */
698static void stop_handler(int sig UNUSED_PARAM) 700static void stop_handler(int sig UNUSED_PARAM)
699{ 701{
700 int saved_errno;
701 smallint saved_bb_got_signal; 702 smallint saved_bb_got_signal;
703 int saved_errno;
702 704
703 saved_errno = errno;
704 saved_bb_got_signal = bb_got_signal; 705 saved_bb_got_signal = bb_got_signal;
706 saved_errno = errno;
705 signal(SIGCONT, record_signo); 707 signal(SIGCONT, record_signo);
706 708
707 while (1) { 709 while (1) {
@@ -714,14 +716,13 @@ static void stop_handler(int sig UNUSED_PARAM)
714 * code which is resilient against this. 716 * code which is resilient against this.
715 */ 717 */
716 wpid = wait_any_nohang(NULL); 718 wpid = wait_any_nohang(NULL);
717 if (wpid > 0) 719 mark_terminated(wpid);
718 mark_terminated(wpid);
719 sleep(1); 720 sleep(1);
720 } 721 }
721 722
722 signal(SIGCONT, SIG_DFL); 723 signal(SIGCONT, SIG_DFL);
723 bb_got_signal = saved_bb_got_signal;
724 errno = saved_errno; 724 errno = saved_errno;
725 bb_got_signal = saved_bb_got_signal;
725} 726}
726 727
727/* Handler for QUIT - exec "restart" action, 728/* Handler for QUIT - exec "restart" action,
@@ -747,8 +748,14 @@ static void restart_handler(int sig UNUSED_PARAM)
747 748
748 if (open_stdio_to_tty(a->terminal)) { 749 if (open_stdio_to_tty(a->terminal)) {
749 dbg_message(L_CONSOLE, "Trying to re-exec %s", a->command); 750 dbg_message(L_CONSOLE, "Trying to re-exec %s", a->command);
750 while (wait(NULL) > 0) 751 /* Theoretically should be safe.
751 continue; 752 * But in practice, kernel bugs may leave
753 * unkillable processes, and wait() may block forever.
754 * Oh well. Hoping "new" init won't be too surprised
755 * by having children it didn't create.
756 */
757 //while (wait(NULL) > 0)
758 // continue;
752 init_exec(a->command); 759 init_exec(a->command);
753 } 760 }
754 /* Open or exec failed */ 761 /* Open or exec failed */
@@ -990,14 +997,14 @@ int init_main(int argc UNUSED_PARAM, char **argv)
990 997
991 got_sigs |= check_delayed_sigs(); 998 got_sigs |= check_delayed_sigs();
992 999
1000 if (got_sigs)
1001 goto dont_block;
993 /* Wait for any child process to exit. 1002 /* Wait for any child process to exit.
994 * NB: "delayed" signals will also interrupt this wait(), 1003 * NB: "delayed" signals will also interrupt this wait(),
995 * bb_signals_recursive_norestart() set them up for that. 1004 * bb_signals_recursive_norestart() set them up for that.
996 * This guarantees we won't be stuck here 1005 * This guarantees we won't be stuck here
997 * till next orphan dies. 1006 * till next orphan dies.
998 */ 1007 */
999 if (got_sigs)
1000 goto dont_block;
1001 wpid = wait(NULL); 1008 wpid = wait(NULL);
1002 while (wpid > 0) { 1009 while (wpid > 0) {
1003 struct init_action *a = mark_terminated(wpid); 1010 struct init_action *a = mark_terminated(wpid);