aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-12-25 01:08:58 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-12-25 01:08:58 +0000
commitec5631b6d697895ff4f1f750840326f9f035df96 (patch)
tree041d1134275f62d9887c1684d9ed51c043ca7454
parent7b55c7f97d1aec5a34a33b8ce6412f2d62f7122a (diff)
downloadbusybox-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.in20
-rw-r--r--init/init.c117
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
30config 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
39config 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
30config FEATURE_INIT_SCTTY 50config 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)
738static void parse_inittab(void) 738static 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;