mirror of
https://github.com/sheumann/hush.git
synced 2025-01-04 22:34:37 +00:00
init: add FEATURE_KILL_REMOVED (Eugene Bordenkircher <eugebo@gmail.com>)
init: slight size optimization
This commit is contained in:
parent
7b55c7f97d
commit
ec5631b6d6
@ -27,6 +27,26 @@ config FEATURE_USE_INITTAB
|
|||||||
help
|
help
|
||||||
Allow init to read an inittab file when the system boot.
|
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
|
config FEATURE_INIT_SCTTY
|
||||||
bool "Support running commands with a controlling-tty"
|
bool "Support running commands with a controlling-tty"
|
||||||
default n
|
default n
|
||||||
|
111
init/init.c
111
init/init.c
@ -738,21 +738,8 @@ static void delete_init_action(struct init_action *action)
|
|||||||
static void parse_inittab(void)
|
static void parse_inittab(void)
|
||||||
{
|
{
|
||||||
#if ENABLE_FEATURE_USE_INITTAB
|
#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;
|
FILE *file;
|
||||||
char buf[INIT_BUFFS_SIZE], lineAsRead[INIT_BUFFS_SIZE];
|
char buf[INIT_BUFFS_SIZE];
|
||||||
char tmpConsole[CONSOLE_NAME_SIZE];
|
|
||||||
char *id, *runlev, *action, *command, *eol;
|
|
||||||
|
|
||||||
file = fopen(INITTAB, "r");
|
file = fopen(INITTAB, "r");
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
@ -780,57 +767,43 @@ static void parse_inittab(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (fgets(buf, INIT_BUFFS_SIZE, file) != NULL) {
|
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;
|
const char *a;
|
||||||
|
|
||||||
/* Skip leading spaces */
|
/* Skip leading spaces */
|
||||||
for (id = buf; *id == ' ' || *id == '\t'; id++);
|
id = skip_whitespace(buf);
|
||||||
|
|
||||||
/* Skip the line if it's a comment */
|
/* Skip the line if it's a comment */
|
||||||
if (*id == '#' || *id == '\n')
|
if (*id == '#' || *id == '\n')
|
||||||
continue;
|
continue;
|
||||||
|
/* Trim the trailing '\n' */
|
||||||
|
*strchrnul(id, '\n') = '\0';
|
||||||
|
|
||||||
/* Trim the trailing \n */
|
/* Line is: "id:runlevel_ignored:action:command" */
|
||||||
//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 */
|
|
||||||
runlev = strchr(id, ':');
|
runlev = strchr(id, ':');
|
||||||
if (runlev == NULL || *(runlev + 1) == '\0') {
|
if (runlev == NULL /*|| runlev[1] == '\0' - not needed */)
|
||||||
message(L_LOG | L_CONSOLE, "Bad inittab entry: %s", lineAsRead);
|
goto bad_entry;
|
||||||
continue;
|
action = strchr(runlev + 1, ':');
|
||||||
} else {
|
if (action == NULL /*|| action[1] == '\0' - not needed */)
|
||||||
*runlev = '\0';
|
goto bad_entry;
|
||||||
++runlev;
|
command = strchr(action + 1, ':');
|
||||||
}
|
if (command == NULL || command[1] == '\0')
|
||||||
|
goto bad_entry;
|
||||||
|
|
||||||
/* Separate the runlevels from the action */
|
*command = '\0'; /* action => ":action\0" now */
|
||||||
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 */
|
|
||||||
for (a = actions; a[0]; a += strlen(a) + 1) {
|
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 (*id != '\0') {
|
||||||
if (strncmp(id, "/dev/", 5) == 0)
|
if (strncmp(id, "/dev/", 5) == 0)
|
||||||
id += 5;
|
id += 5;
|
||||||
@ -839,14 +812,15 @@ static void parse_inittab(void)
|
|||||||
sizeof(tmpConsole) - 5);
|
sizeof(tmpConsole) - 5);
|
||||||
id = tmpConsole;
|
id = tmpConsole;
|
||||||
}
|
}
|
||||||
new_init_action((uint8_t)a[0], command, id);
|
new_init_action((uint8_t)a[0], command + 1, id);
|
||||||
break;
|
goto next_line;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!a[0]) {
|
*command = ':';
|
||||||
/* Choke on an unknown action */
|
/* Choke on an unknown action */
|
||||||
message(L_LOG | L_CONSOLE, "Bad inittab entry: %s", lineAsRead);
|
bad_entry:
|
||||||
}
|
message(L_LOG | L_CONSOLE, "Bad inittab entry: %s", id);
|
||||||
|
next_line: ;
|
||||||
}
|
}
|
||||||
fclose(file);
|
fclose(file);
|
||||||
#endif /* FEATURE_USE_INITTAB */
|
#endif /* FEATURE_USE_INITTAB */
|
||||||
@ -866,6 +840,23 @@ static void reload_signal(int sig ATTRIBUTE_UNUSED)
|
|||||||
|
|
||||||
parse_inittab();
|
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 */
|
/* remove unused entrys */
|
||||||
for (a = init_action_list; a; a = tmp) {
|
for (a = init_action_list; a; a = tmp) {
|
||||||
tmp = a->next;
|
tmp = a->next;
|
||||||
|
Loading…
Reference in New Issue
Block a user