diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-12-25 01:08:58 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-12-25 01:08:58 +0000 |
commit | ec5631b6d697895ff4f1f750840326f9f035df96 (patch) | |
tree | 041d1134275f62d9887c1684d9ed51c043ca7454 | |
parent | 7b55c7f97d1aec5a34a33b8ce6412f2d62f7122a (diff) | |
download | busybox-w32-ec5631b6d697895ff4f1f750840326f9f035df96.tar.gz busybox-w32-ec5631b6d697895ff4f1f750840326f9f035df96.tar.bz2 busybox-w32-ec5631b6d697895ff4f1f750840326f9f035df96.zip |
init: add FEATURE_KILL_REMOVED (Eugene Bordenkircher <eugebo@gmail.com>)
init: slight size optimization
-rw-r--r-- | init/Config.in | 20 | ||||
-rw-r--r-- | init/init.c | 117 |
2 files changed, 74 insertions, 63 deletions
diff --git a/init/Config.in b/init/Config.in index 318f523a0..1084de905 100644 --- a/init/Config.in +++ b/init/Config.in | |||
@@ -27,6 +27,26 @@ config FEATURE_USE_INITTAB | |||
27 | help | 27 | help |
28 | Allow init to read an inittab file when the system boot. | 28 | Allow init to read an inittab file when the system boot. |
29 | 29 | ||
30 | config FEATURE_KILL_REMOVED | ||
31 | bool "Support killing processes that have been removed from inittab" | ||
32 | default y | ||
33 | depends on FEATURE_USE_INITTAB | ||
34 | help | ||
35 | When respawn entries are removed from inittab and a SIGHUP is | ||
36 | sent to init, this feature will kill the processes that have | ||
37 | been removed. | ||
38 | |||
39 | config FEATURE_KILL_DELAY | ||
40 | int "How long to wait between TERM and KILL (0 - send TERM only)" | ||
41 | range 0 1024 | ||
42 | default 0 | ||
43 | depends on FEATURE_KILL_REMOVED | ||
44 | help | ||
45 | With nonzero setting, init sends TERM, forks, child waits N | ||
46 | seconds, sends KILL and exits. Setting it too high is unwise | ||
47 | (child will hang around for too long and can actually kill | ||
48 | wrong process!) | ||
49 | |||
30 | config FEATURE_INIT_SCTTY | 50 | config FEATURE_INIT_SCTTY |
31 | bool "Support running commands with a controlling-tty" | 51 | bool "Support running commands with a controlling-tty" |
32 | default n | 52 | default n |
diff --git a/init/init.c b/init/init.c index baa5a5000..e6581880c 100644 --- a/init/init.c +++ b/init/init.c | |||
@@ -738,21 +738,8 @@ static void delete_init_action(struct init_action *action) | |||
738 | static void parse_inittab(void) | 738 | static void parse_inittab(void) |
739 | { | 739 | { |
740 | #if ENABLE_FEATURE_USE_INITTAB | 740 | #if ENABLE_FEATURE_USE_INITTAB |
741 | static const char actions[] = | ||
742 | STR_SYSINIT "sysinit\0" | ||
743 | STR_RESPAWN "respawn\0" | ||
744 | STR_ASKFIRST "askfirst\0" | ||
745 | STR_WAIT "wait\0" | ||
746 | STR_ONCE "once\0" | ||
747 | STR_CTRLALTDEL "ctrlaltdel\0" | ||
748 | STR_SHUTDOWN "shutdown\0" | ||
749 | STR_RESTART "restart\0" | ||
750 | ; | ||
751 | |||
752 | FILE *file; | 741 | FILE *file; |
753 | char buf[INIT_BUFFS_SIZE], lineAsRead[INIT_BUFFS_SIZE]; | 742 | char buf[INIT_BUFFS_SIZE]; |
754 | char tmpConsole[CONSOLE_NAME_SIZE]; | ||
755 | char *id, *runlev, *action, *command, *eol; | ||
756 | 743 | ||
757 | file = fopen(INITTAB, "r"); | 744 | file = fopen(INITTAB, "r"); |
758 | if (file == NULL) { | 745 | if (file == NULL) { |
@@ -780,57 +767,43 @@ static void parse_inittab(void) | |||
780 | } | 767 | } |
781 | 768 | ||
782 | while (fgets(buf, INIT_BUFFS_SIZE, file) != NULL) { | 769 | while (fgets(buf, INIT_BUFFS_SIZE, file) != NULL) { |
770 | static const char actions[] = | ||
771 | STR_SYSINIT "sysinit\0" | ||
772 | STR_RESPAWN "respawn\0" | ||
773 | STR_ASKFIRST "askfirst\0" | ||
774 | STR_WAIT "wait\0" | ||
775 | STR_ONCE "once\0" | ||
776 | STR_CTRLALTDEL "ctrlaltdel\0" | ||
777 | STR_SHUTDOWN "shutdown\0" | ||
778 | STR_RESTART "restart\0" | ||
779 | ; | ||
780 | char tmpConsole[CONSOLE_NAME_SIZE]; | ||
781 | char *id, *runlev, *action, *command; | ||
783 | const char *a; | 782 | const char *a; |
784 | 783 | ||
785 | /* Skip leading spaces */ | 784 | /* Skip leading spaces */ |
786 | for (id = buf; *id == ' ' || *id == '\t'; id++); | 785 | id = skip_whitespace(buf); |
787 | |||
788 | /* Skip the line if it's a comment */ | 786 | /* Skip the line if it's a comment */ |
789 | if (*id == '#' || *id == '\n') | 787 | if (*id == '#' || *id == '\n') |
790 | continue; | 788 | continue; |
789 | /* Trim the trailing '\n' */ | ||
790 | *strchrnul(id, '\n') = '\0'; | ||
791 | 791 | ||
792 | /* Trim the trailing \n */ | 792 | /* Line is: "id:runlevel_ignored:action:command" */ |
793 | //XXX: chomp() ? | ||
794 | eol = strrchr(id, '\n'); | ||
795 | if (eol != NULL) | ||
796 | *eol = '\0'; | ||
797 | |||
798 | /* Keep a copy around for posterity's sake (and error msgs) */ | ||
799 | strcpy(lineAsRead, buf); | ||
800 | |||
801 | /* Separate the ID field from the runlevels */ | ||
802 | runlev = strchr(id, ':'); | 793 | runlev = strchr(id, ':'); |
803 | if (runlev == NULL || *(runlev + 1) == '\0') { | 794 | if (runlev == NULL /*|| runlev[1] == '\0' - not needed */) |
804 | message(L_LOG | L_CONSOLE, "Bad inittab entry: %s", lineAsRead); | 795 | goto bad_entry; |
805 | continue; | 796 | action = strchr(runlev + 1, ':'); |
806 | } else { | 797 | if (action == NULL /*|| action[1] == '\0' - not needed */) |
807 | *runlev = '\0'; | 798 | goto bad_entry; |
808 | ++runlev; | 799 | command = strchr(action + 1, ':'); |
809 | } | 800 | if (command == NULL || command[1] == '\0') |
810 | 801 | goto bad_entry; | |
811 | /* Separate the runlevels from the action */ | 802 | |
812 | action = strchr(runlev, ':'); | 803 | *command = '\0'; /* action => ":action\0" now */ |
813 | if (action == NULL || *(action + 1) == '\0') { | ||
814 | message(L_LOG | L_CONSOLE, "Bad inittab entry: %s", lineAsRead); | ||
815 | continue; | ||
816 | } else { | ||
817 | *action = '\0'; | ||
818 | ++action; | ||
819 | } | ||
820 | |||
821 | /* Separate the action from the command */ | ||
822 | command = strchr(action, ':'); | ||
823 | if (command == NULL || *(command + 1) == '\0') { | ||
824 | message(L_LOG | L_CONSOLE, "Bad inittab entry: %s", lineAsRead); | ||
825 | continue; | ||
826 | } else { | ||
827 | *command = '\0'; | ||
828 | ++command; | ||
829 | } | ||
830 | |||
831 | /* Ok, now process it */ | ||
832 | for (a = actions; a[0]; a += strlen(a) + 1) { | 804 | for (a = actions; a[0]; a += strlen(a) + 1) { |
833 | if (strcmp(a + 1, action) == 0) { | 805 | if (strcmp(a + 1, action + 1) == 0) { |
806 | *runlev = '\0'; | ||
834 | if (*id != '\0') { | 807 | if (*id != '\0') { |
835 | if (strncmp(id, "/dev/", 5) == 0) | 808 | if (strncmp(id, "/dev/", 5) == 0) |
836 | id += 5; | 809 | id += 5; |
@@ -839,14 +812,15 @@ static void parse_inittab(void) | |||
839 | sizeof(tmpConsole) - 5); | 812 | sizeof(tmpConsole) - 5); |
840 | id = tmpConsole; | 813 | id = tmpConsole; |
841 | } | 814 | } |
842 | new_init_action((uint8_t)a[0], command, id); | 815 | new_init_action((uint8_t)a[0], command + 1, id); |
843 | break; | 816 | goto next_line; |
844 | } | 817 | } |
845 | } | 818 | } |
846 | if (!a[0]) { | 819 | *command = ':'; |
847 | /* Choke on an unknown action */ | 820 | /* Choke on an unknown action */ |
848 | message(L_LOG | L_CONSOLE, "Bad inittab entry: %s", lineAsRead); | 821 | bad_entry: |
849 | } | 822 | message(L_LOG | L_CONSOLE, "Bad inittab entry: %s", id); |
823 | next_line: ; | ||
850 | } | 824 | } |
851 | fclose(file); | 825 | fclose(file); |
852 | #endif /* FEATURE_USE_INITTAB */ | 826 | #endif /* FEATURE_USE_INITTAB */ |
@@ -860,12 +834,29 @@ static void reload_signal(int sig ATTRIBUTE_UNUSED) | |||
860 | message(L_LOG, "reloading /etc/inittab"); | 834 | message(L_LOG, "reloading /etc/inittab"); |
861 | 835 | ||
862 | /* disable old entrys */ | 836 | /* disable old entrys */ |
863 | for (a = init_action_list; a; a = a->next ) { | 837 | for (a = init_action_list; a; a = a->next) { |
864 | a->action = ONCE; | 838 | a->action = ONCE; |
865 | } | 839 | } |
866 | 840 | ||
867 | parse_inittab(); | 841 | parse_inittab(); |
868 | 842 | ||
843 | #if ENABLE_FEATURE_KILL_REMOVED | ||
844 | for (a = init_action_list; a; a = a->next) { | ||
845 | pid_t pid = a->pid; | ||
846 | if ((a->action & ONCE) && pid != 0) { | ||
847 | /* Be nice and send SIGTERM first */ | ||
848 | kill(pid, SIGTERM); | ||
849 | #if CONFIG_FEATURE_KILL_DELAY | ||
850 | if (fork() == 0) { /* child */ | ||
851 | sleep(CONFIG_FEATURE_KILL_DELAY); | ||
852 | kill(pid, SIGKILL); | ||
853 | _exit(0); | ||
854 | } | ||
855 | #endif | ||
856 | } | ||
857 | } | ||
858 | #endif /* FEATURE_KILL_REMOVED */ | ||
859 | |||
869 | /* remove unused entrys */ | 860 | /* remove unused entrys */ |
870 | for (a = init_action_list; a; a = tmp) { | 861 | for (a = init_action_list; a; a = tmp) { |
871 | tmp = a->next; | 862 | tmp = a->next; |