svn commit: trunk/busybox/init

vda at busybox.net vda at busybox.net
Tue Dec 25 01:08:59 UTC 2007


Author: vda
Date: 2007-12-24 17:08:58 -0800 (Mon, 24 Dec 2007)
New Revision: 20682

Log:
init: add FEATURE_KILL_REMOVED (Eugene Bordenkircher <eugebo at gmail.com>)
init: slight size optimization



Modified:
   trunk/busybox/init/Config.in
   trunk/busybox/init/init.c


Changeset:
Modified: trunk/busybox/init/Config.in
===================================================================
--- trunk/busybox/init/Config.in	2007-12-24 17:33:56 UTC (rev 20681)
+++ trunk/busybox/init/Config.in	2007-12-25 01:08:58 UTC (rev 20682)
@@ -27,6 +27,26 @@
 	help
 	  Allow init to read an inittab file when the system boot.
 
+config FEATURE_KILL_REMOVED
+	bool "Support killing processes that have been removed from inittab"
+	default y
+	depends on FEATURE_USE_INITTAB
+	help
+	  When respawn entries are removed from inittab and a SIGHUP is 
+	  sent to init, this feature will kill the processes that have 
+	  been removed.
+
+config FEATURE_KILL_DELAY
+	int "How long to wait between TERM and KILL (0 - send TERM only)"
+	range 0 1024
+	default 0
+	depends on FEATURE_KILL_REMOVED
+	help
+	  With nonzero setting, init sends TERM, forks, child waits N
+	  seconds, sends KILL and exits. Setting it too high is unwise
+	  (child will hang around for too long and can actually kill
+	  wrong process!)
+
 config FEATURE_INIT_SCTTY
 	bool "Support running commands with a controlling-tty"
 	default n

Modified: trunk/busybox/init/init.c
===================================================================
--- trunk/busybox/init/init.c	2007-12-24 17:33:56 UTC (rev 20681)
+++ trunk/busybox/init/init.c	2007-12-25 01:08:58 UTC (rev 20682)
@@ -738,21 +738,8 @@
 static void parse_inittab(void)
 {
 #if ENABLE_FEATURE_USE_INITTAB
-	static const char actions[] =
-		STR_SYSINIT    "sysinit\0"
-		STR_RESPAWN    "respawn\0"
-		STR_ASKFIRST   "askfirst\0"
-		STR_WAIT       "wait\0"
-		STR_ONCE       "once\0"
-		STR_CTRLALTDEL "ctrlaltdel\0"
-		STR_SHUTDOWN   "shutdown\0"
-		STR_RESTART    "restart\0"
-	;
-
 	FILE *file;
-	char buf[INIT_BUFFS_SIZE], lineAsRead[INIT_BUFFS_SIZE];
-	char tmpConsole[CONSOLE_NAME_SIZE];
-	char *id, *runlev, *action, *command, *eol;
+	char buf[INIT_BUFFS_SIZE];
 
 	file = fopen(INITTAB, "r");
 	if (file == NULL) {
@@ -780,57 +767,43 @@
 	}
 
 	while (fgets(buf, INIT_BUFFS_SIZE, file) != NULL) {
+		static const char actions[] =
+			STR_SYSINIT    "sysinit\0"
+			STR_RESPAWN    "respawn\0"
+			STR_ASKFIRST   "askfirst\0"
+			STR_WAIT       "wait\0"
+			STR_ONCE       "once\0"
+			STR_CTRLALTDEL "ctrlaltdel\0"
+			STR_SHUTDOWN   "shutdown\0"
+			STR_RESTART    "restart\0"
+		;
+		char tmpConsole[CONSOLE_NAME_SIZE];
+		char *id, *runlev, *action, *command;
 		const char *a;
 
 		/* Skip leading spaces */
-		for (id = buf; *id == ' ' || *id == '\t'; id++);
-
+		id = skip_whitespace(buf);
 		/* Skip the line if it's a comment */
 		if (*id == '#' || *id == '\n')
 			continue;
+		/* Trim the trailing '\n' */
+		*strchrnul(id, '\n') = '\0';
 
-		/* Trim the trailing \n */
-		//XXX: chomp() ?
-		eol = strrchr(id, '\n');
-		if (eol != NULL)
-			*eol = '\0';
-
-		/* Keep a copy around for posterity's sake (and error msgs) */
-		strcpy(lineAsRead, buf);
-
-		/* Separate the ID field from the runlevels */
+		/* Line is: "id:runlevel_ignored:action:command" */
 		runlev = strchr(id, ':');
-		if (runlev == NULL || *(runlev + 1) == '\0') {
-			message(L_LOG | L_CONSOLE, "Bad inittab entry: %s", lineAsRead);
-			continue;
-		} else {
-			*runlev = '\0';
-			++runlev;
-		}
+		if (runlev == NULL /*|| runlev[1] == '\0' - not needed */)
+			goto bad_entry;
+		action = strchr(runlev + 1, ':');
+		if (action == NULL /*|| action[1] == '\0' - not needed */)
+			goto bad_entry;
+		command = strchr(action + 1, ':');
+		if (command == NULL || command[1] == '\0')
+			goto bad_entry;
 
-		/* Separate the runlevels from the action */
-		action = strchr(runlev, ':');
-		if (action == NULL || *(action + 1) == '\0') {
-			message(L_LOG | L_CONSOLE, "Bad inittab entry: %s", lineAsRead);
-			continue;
-		} else {
-			*action = '\0';
-			++action;
-		}
-
-		/* Separate the action from the command */
-		command = strchr(action, ':');
-		if (command == NULL || *(command + 1) == '\0') {
-			message(L_LOG | L_CONSOLE, "Bad inittab entry: %s", lineAsRead);
-			continue;
-		} else {
-			*command = '\0';
-			++command;
-		}
-
-		/* Ok, now process it */
+		*command = '\0'; /* action => ":action\0" now */
 		for (a = actions; a[0]; a += strlen(a) + 1) {
-			if (strcmp(a + 1, action) == 0) {
+			if (strcmp(a + 1, action + 1) == 0) {
+				*runlev = '\0';
 				if (*id != '\0') {
 					if (strncmp(id, "/dev/", 5) == 0)
 						id += 5;
@@ -839,14 +812,15 @@
 						sizeof(tmpConsole) - 5);
 					id = tmpConsole;
 				}
-				new_init_action((uint8_t)a[0], command, id);
-				break;
+				new_init_action((uint8_t)a[0], command + 1, id);
+				goto next_line;
 			}
 		}
-		if (!a[0]) {
-			/* Choke on an unknown action */
-			message(L_LOG | L_CONSOLE, "Bad inittab entry: %s", lineAsRead);
-		}
+		*command = ':';
+		/* Choke on an unknown action */
+ bad_entry:
+		message(L_LOG | L_CONSOLE, "Bad inittab entry: %s", id);
+ next_line: ;
 	}
 	fclose(file);
 #endif /* FEATURE_USE_INITTAB */
@@ -860,12 +834,29 @@
 	message(L_LOG, "reloading /etc/inittab");
 
 	/* disable old entrys */
-	for (a = init_action_list; a; a = a->next ) {
+	for (a = init_action_list; a; a = a->next) {
 		a->action = ONCE;
 	}
 
 	parse_inittab();
 
+#if ENABLE_FEATURE_KILL_REMOVED
+	for (a = init_action_list; a; a = a->next) {
+		pid_t pid = a->pid;
+		if ((a->action & ONCE) && pid != 0) {
+			/* Be nice and send SIGTERM first */
+			kill(pid, SIGTERM);
+#if CONFIG_FEATURE_KILL_DELAY
+			if (fork() == 0) { /* child */
+				sleep(CONFIG_FEATURE_KILL_DELAY);
+				kill(pid, SIGKILL);
+				_exit(0);
+			}
+#endif
+		}
+	}
+#endif /* FEATURE_KILL_REMOVED */
+
 	/* remove unused entrys */
 	for (a = init_action_list; a; a = tmp) {
 		tmp = a->next;




More information about the busybox-cvs mailing list