diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-12-26 18:32:58 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-12-26 18:32:58 +0000 |
commit | d55268d0d497856a34f732aca158d07276358ab6 (patch) | |
tree | cdf152dac62fb125f86c1462dccbcd83b0a2f338 /init/init.c | |
parent | 5adfa44101ff03299775af84d30a04d88aa0bb81 (diff) | |
download | busybox-w32-d55268d0d497856a34f732aca158d07276358ab6.tar.gz busybox-w32-d55268d0d497856a34f732aca158d07276358ab6.tar.bz2 busybox-w32-d55268d0d497856a34f732aca158d07276358ab6.zip |
init: don't spawn tons of waiting children, one is enough
init: shrink signal disabling code
init: rename some functions
text data bss dec hex filename
778657 832 7344 786833 c0191 busybox_old
778445 832 7344 786621 c00bd busybox_unstripped
Diffstat (limited to 'init/init.c')
-rw-r--r-- | init/init.c | 86 |
1 files changed, 47 insertions, 39 deletions
diff --git a/init/init.c b/init/init.c index 83678c1c3..51125f348 100644 --- a/init/init.c +++ b/init/init.c | |||
@@ -96,8 +96,9 @@ static const char *const environment[] = { | |||
96 | /* Function prototypes */ | 96 | /* Function prototypes */ |
97 | static void delete_init_action(struct init_action *a); | 97 | static void delete_init_action(struct init_action *a); |
98 | static int waitfor(pid_t pid); | 98 | static int waitfor(pid_t pid); |
99 | static void shutdown_signal(int sig); | 99 | static void halt_reboot_pwoff(int sig) ATTRIBUTE_NORETURN; |
100 | 100 | ||
101 | static void loop_forever(void) ATTRIBUTE_NORETURN; | ||
101 | static void loop_forever(void) | 102 | static void loop_forever(void) |
102 | { | 103 | { |
103 | while (1) | 104 | while (1) |
@@ -259,26 +260,25 @@ static void set_sane_term(void) | |||
259 | } | 260 | } |
260 | 261 | ||
261 | /* Open the new terminal device */ | 262 | /* Open the new terminal device */ |
262 | static void open_stdio_to_tty(const char* tty_name, int fail) | 263 | static void open_stdio_to_tty(const char* tty_name, int exit_on_failure) |
263 | { | 264 | { |
264 | /* empty tty_name means "use init's tty", else... */ | 265 | /* empty tty_name means "use init's tty", else... */ |
265 | if (tty_name[0]) { | 266 | if (tty_name[0]) { |
266 | int fd = device_open(tty_name, O_RDWR); | 267 | int fd; |
267 | if (fd < 0) { | 268 | close(0); |
269 | /* fd can be only < 0 or 0: */ | ||
270 | fd = device_open(tty_name, O_RDWR); | ||
271 | if (fd) { | ||
268 | message(L_LOG | L_CONSOLE, "Can't open %s: %s", | 272 | message(L_LOG | L_CONSOLE, "Can't open %s: %s", |
269 | tty_name, strerror(errno)); | 273 | tty_name, strerror(errno)); |
270 | if (fail) | 274 | if (exit_on_failure) |
271 | _exit(1); | 275 | _exit(1); |
272 | if (!ENABLE_DEBUG_INIT) | 276 | if (ENABLE_DEBUG_INIT) |
273 | shutdown_signal(SIGUSR1); | ||
274 | else | ||
275 | _exit(2); | 277 | _exit(2); |
276 | } else { | 278 | halt_reboot_pwoff(SIGUSR1); /* halt the system */ |
277 | dup2(fd, 0); | ||
278 | dup2(fd, 1); | ||
279 | dup2(fd, 2); | ||
280 | if (fd > 2) close(fd); | ||
281 | } | 279 | } |
280 | dup2(0, 1); | ||
281 | dup2(0, 2); | ||
282 | } | 282 | } |
283 | set_sane_term(); | 283 | set_sane_term(); |
284 | } | 284 | } |
@@ -412,9 +412,7 @@ static pid_t run(const struct init_action *a) | |||
412 | } | 412 | } |
413 | #endif | 413 | #endif |
414 | 414 | ||
415 | /* Establish this process as session leader and | 415 | /* _Attempt_ to make stdin a controlling tty. */ |
416 | * _attempt_ to make stdin a controlling tty. | ||
417 | */ | ||
418 | if (ENABLE_FEATURE_INIT_SCTTY) | 416 | if (ENABLE_FEATURE_INIT_SCTTY) |
419 | ioctl(0, TIOCSCTTY, 0 /*only try, don't steal*/); | 417 | ioctl(0, TIOCSCTTY, 0 /*only try, don't steal*/); |
420 | } | 418 | } |
@@ -525,7 +523,7 @@ static void init_reboot(unsigned long magic) | |||
525 | waitpid(pid, NULL, 0); | 523 | waitpid(pid, NULL, 0); |
526 | } | 524 | } |
527 | 525 | ||
528 | static void shutdown_system(void) | 526 | static void kill_all_processes(void) |
529 | { | 527 | { |
530 | sigset_t block_signals; | 528 | sigset_t block_signals; |
531 | 529 | ||
@@ -535,7 +533,8 @@ static void shutdown_system(void) | |||
535 | run_actions(SHUTDOWN); | 533 | run_actions(SHUTDOWN); |
536 | 534 | ||
537 | /* first disable all our signals */ | 535 | /* first disable all our signals */ |
538 | sigemptyset(&block_signals); | 536 | sigfillset(&block_signals); |
537 | /*sigemptyset(&block_signals); | ||
539 | sigaddset(&block_signals, SIGHUP); | 538 | sigaddset(&block_signals, SIGHUP); |
540 | sigaddset(&block_signals, SIGQUIT); | 539 | sigaddset(&block_signals, SIGQUIT); |
541 | sigaddset(&block_signals, SIGCHLD); | 540 | sigaddset(&block_signals, SIGCHLD); |
@@ -545,7 +544,7 @@ static void shutdown_system(void) | |||
545 | sigaddset(&block_signals, SIGTERM); | 544 | sigaddset(&block_signals, SIGTERM); |
546 | sigaddset(&block_signals, SIGCONT); | 545 | sigaddset(&block_signals, SIGCONT); |
547 | sigaddset(&block_signals, SIGSTOP); | 546 | sigaddset(&block_signals, SIGSTOP); |
548 | sigaddset(&block_signals, SIGTSTP); | 547 | sigaddset(&block_signals, SIGTSTP);*/ |
549 | sigprocmask(SIG_BLOCK, &block_signals, NULL); | 548 | sigprocmask(SIG_BLOCK, &block_signals, NULL); |
550 | 549 | ||
551 | message(L_CONSOLE | L_LOG, "The system is going down NOW!"); | 550 | message(L_CONSOLE | L_LOG, "The system is going down NOW!"); |
@@ -565,12 +564,12 @@ static void shutdown_system(void) | |||
565 | sleep(1); | 564 | sleep(1); |
566 | } | 565 | } |
567 | 566 | ||
568 | static void shutdown_signal(int sig) | 567 | static void halt_reboot_pwoff(int sig) |
569 | { | 568 | { |
570 | const char *m; | 569 | const char *m; |
571 | int rb; | 570 | int rb; |
572 | 571 | ||
573 | shutdown_system(); | 572 | kill_all_processes(); |
574 | 573 | ||
575 | m = "halt"; | 574 | m = "halt"; |
576 | rb = RB_HALT_SYSTEM; | 575 | rb = RB_HALT_SYSTEM; |
@@ -588,7 +587,9 @@ static void shutdown_signal(int sig) | |||
588 | loop_forever(); | 587 | loop_forever(); |
589 | } | 588 | } |
590 | 589 | ||
591 | static void exec_signal(int sig ATTRIBUTE_UNUSED) | 590 | /* Handler for HUP and QUIT - exec "restart" action, |
591 | * else (no such action defined) do nothing */ | ||
592 | static void exec_restart_action(int sig ATTRIBUTE_UNUSED) | ||
592 | { | 593 | { |
593 | struct init_action *a, *tmp; | 594 | struct init_action *a, *tmp; |
594 | sigset_t unblock_signals; | 595 | sigset_t unblock_signals; |
@@ -596,10 +597,11 @@ static void exec_signal(int sig ATTRIBUTE_UNUSED) | |||
596 | for (a = init_action_list; a; a = tmp) { | 597 | for (a = init_action_list; a; a = tmp) { |
597 | tmp = a->next; | 598 | tmp = a->next; |
598 | if (a->action & RESTART) { | 599 | if (a->action & RESTART) { |
599 | shutdown_system(); | 600 | kill_all_processes(); |
600 | 601 | ||
601 | /* unblock all signals, blocked in shutdown_system() */ | 602 | /* unblock all signals (blocked in kill_all_processes()) */ |
602 | sigemptyset(&unblock_signals); | 603 | sigfillset(&unblock_signals); |
604 | /*sigemptyset(&unblock_signals); | ||
603 | sigaddset(&unblock_signals, SIGHUP); | 605 | sigaddset(&unblock_signals, SIGHUP); |
604 | sigaddset(&unblock_signals, SIGQUIT); | 606 | sigaddset(&unblock_signals, SIGQUIT); |
605 | sigaddset(&unblock_signals, SIGCHLD); | 607 | sigaddset(&unblock_signals, SIGCHLD); |
@@ -609,11 +611,11 @@ static void exec_signal(int sig ATTRIBUTE_UNUSED) | |||
609 | sigaddset(&unblock_signals, SIGTERM); | 611 | sigaddset(&unblock_signals, SIGTERM); |
610 | sigaddset(&unblock_signals, SIGCONT); | 612 | sigaddset(&unblock_signals, SIGCONT); |
611 | sigaddset(&unblock_signals, SIGSTOP); | 613 | sigaddset(&unblock_signals, SIGSTOP); |
612 | sigaddset(&unblock_signals, SIGTSTP); | 614 | sigaddset(&unblock_signals, SIGTSTP);*/ |
613 | sigprocmask(SIG_UNBLOCK, &unblock_signals, NULL); | 615 | sigprocmask(SIG_UNBLOCK, &unblock_signals, NULL); |
614 | 616 | ||
615 | /* Open the new terminal device */ | 617 | /* Open the new terminal device */ |
616 | open_stdio_to_tty(a->terminal, 0 /* - shutdown_signal(SIGUSR1) [halt] if open fails */); | 618 | open_stdio_to_tty(a->terminal, 0 /* - halt if open fails */); |
617 | 619 | ||
618 | messageD(L_CONSOLE | L_LOG, "Trying to re-exec %s", a->command); | 620 | messageD(L_CONSOLE | L_LOG, "Trying to re-exec %s", a->command); |
619 | BB_EXECLP(a->command, a->command, NULL); | 621 | BB_EXECLP(a->command, a->command, NULL); |
@@ -812,19 +814,25 @@ static void reload_signal(int sig ATTRIBUTE_UNUSED) | |||
812 | parse_inittab(); | 814 | parse_inittab(); |
813 | 815 | ||
814 | if (ENABLE_FEATURE_KILL_REMOVED) { | 816 | if (ENABLE_FEATURE_KILL_REMOVED) { |
817 | /* Be nice and send SIGTERM first */ | ||
815 | for (a = init_action_list; a; a = a->next) { | 818 | for (a = init_action_list; a; a = a->next) { |
816 | pid_t pid = a->pid; | 819 | pid_t pid = a->pid; |
817 | if ((a->action & ONCE) && pid != 0) { | 820 | if ((a->action & ONCE) && pid != 0) { |
818 | /* Be nice and send SIGTERM first */ | ||
819 | kill(pid, SIGTERM); | 821 | kill(pid, SIGTERM); |
820 | if (CONFIG_FEATURE_KILL_DELAY) | ||
821 | if (fork() == 0) { /* child */ | ||
822 | sleep(CONFIG_FEATURE_KILL_DELAY); | ||
823 | kill(pid, SIGKILL); | ||
824 | _exit(0); | ||
825 | } | ||
826 | } | 822 | } |
827 | } | 823 | } |
824 | #if CONFIG_FEATURE_KILL_DELAY | ||
825 | if (fork() == 0) { /* child */ | ||
826 | sleep(CONFIG_FEATURE_KILL_DELAY); | ||
827 | for (a = init_action_list; a; a = a->next) { | ||
828 | pid_t pid = a->pid; | ||
829 | if ((a->action & ONCE) && pid != 0) { | ||
830 | kill(pid, SIGKILL); | ||
831 | } | ||
832 | } | ||
833 | _exit(0); | ||
834 | } | ||
835 | #endif | ||
828 | } | 836 | } |
829 | 837 | ||
830 | /* remove unused entrys */ | 838 | /* remove unused entrys */ |
@@ -858,12 +866,12 @@ int init_main(int argc, char **argv) | |||
858 | } | 866 | } |
859 | /* Set up sig handlers -- be sure to | 867 | /* Set up sig handlers -- be sure to |
860 | * clear all of these in run() */ | 868 | * clear all of these in run() */ |
861 | signal(SIGHUP, exec_signal); | 869 | signal(SIGHUP, exec_restart_action); |
862 | signal(SIGQUIT, exec_signal); | 870 | signal(SIGQUIT, exec_restart_action); |
863 | signal(SIGUSR1, shutdown_signal); | 871 | signal(SIGUSR1, halt_reboot_pwoff); /* halt */ |
864 | signal(SIGUSR2, shutdown_signal); | 872 | signal(SIGUSR2, halt_reboot_pwoff); /* poweroff */ |
873 | signal(SIGTERM, halt_reboot_pwoff); /* reboot */ | ||
865 | signal(SIGINT, ctrlaltdel_signal); | 874 | signal(SIGINT, ctrlaltdel_signal); |
866 | signal(SIGTERM, shutdown_signal); | ||
867 | signal(SIGCONT, cont_handler); | 875 | signal(SIGCONT, cont_handler); |
868 | signal(SIGSTOP, stop_handler); | 876 | signal(SIGSTOP, stop_handler); |
869 | signal(SIGTSTP, stop_handler); | 877 | signal(SIGTSTP, stop_handler); |