aboutsummaryrefslogtreecommitdiff
path: root/init/init.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-12-26 18:32:58 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-12-26 18:32:58 +0000
commitd55268d0d497856a34f732aca158d07276358ab6 (patch)
treecdf152dac62fb125f86c1462dccbcd83b0a2f338 /init/init.c
parent5adfa44101ff03299775af84d30a04d88aa0bb81 (diff)
downloadbusybox-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.c86
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 */
97static void delete_init_action(struct init_action *a); 97static void delete_init_action(struct init_action *a);
98static int waitfor(pid_t pid); 98static int waitfor(pid_t pid);
99static void shutdown_signal(int sig); 99static void halt_reboot_pwoff(int sig) ATTRIBUTE_NORETURN;
100 100
101static void loop_forever(void) ATTRIBUTE_NORETURN;
101static void loop_forever(void) 102static 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 */
262static void open_stdio_to_tty(const char* tty_name, int fail) 263static 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
528static void shutdown_system(void) 526static 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
568static void shutdown_signal(int sig) 567static 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
591static void exec_signal(int sig ATTRIBUTE_UNUSED) 590/* Handler for HUP and QUIT - exec "restart" action,
591 * else (no such action defined) do nothing */
592static 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);