mirror of
https://github.com/sheumann/hush.git
synced 2024-12-21 23:29:34 +00:00
init: remove wait() loop on restart, it may be dangerous
This commit is contained in:
parent
4ae8a05b13
commit
9ec0ecbfdd
37
init/init.c
37
init/init.c
@ -418,14 +418,16 @@ static pid_t run(const struct init_action *a)
|
|||||||
_exit(-1);
|
_exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct init_action *mark_terminated(int pid)
|
static struct init_action *mark_terminated(pid_t pid)
|
||||||
{
|
{
|
||||||
struct init_action *a;
|
struct init_action *a;
|
||||||
|
|
||||||
for (a = init_action_list; a; a = a->next) {
|
if (pid > 0) {
|
||||||
if (a->pid == pid) {
|
for (a = init_action_list; a; a = a->next) {
|
||||||
a->pid = 0;
|
if (a->pid == pid) {
|
||||||
return a;
|
a->pid = 0;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -444,7 +446,7 @@ static void waitfor(pid_t pid)
|
|||||||
mark_terminated(wpid);
|
mark_terminated(wpid);
|
||||||
/* Unsafe. SIGTSTP handler might have wait'ed it already */
|
/* Unsafe. SIGTSTP handler might have wait'ed it already */
|
||||||
/*if (wpid == pid) break;*/
|
/*if (wpid == pid) break;*/
|
||||||
/* More reliable */
|
/* More reliable: */
|
||||||
if (kill(pid, 0))
|
if (kill(pid, 0))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -697,11 +699,11 @@ static void halt_reboot_pwoff(int sig)
|
|||||||
*/
|
*/
|
||||||
static void stop_handler(int sig UNUSED_PARAM)
|
static void stop_handler(int sig UNUSED_PARAM)
|
||||||
{
|
{
|
||||||
int saved_errno;
|
|
||||||
smallint saved_bb_got_signal;
|
smallint saved_bb_got_signal;
|
||||||
|
int saved_errno;
|
||||||
|
|
||||||
saved_errno = errno;
|
|
||||||
saved_bb_got_signal = bb_got_signal;
|
saved_bb_got_signal = bb_got_signal;
|
||||||
|
saved_errno = errno;
|
||||||
signal(SIGCONT, record_signo);
|
signal(SIGCONT, record_signo);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
@ -714,14 +716,13 @@ static void stop_handler(int sig UNUSED_PARAM)
|
|||||||
* code which is resilient against this.
|
* code which is resilient against this.
|
||||||
*/
|
*/
|
||||||
wpid = wait_any_nohang(NULL);
|
wpid = wait_any_nohang(NULL);
|
||||||
if (wpid > 0)
|
mark_terminated(wpid);
|
||||||
mark_terminated(wpid);
|
|
||||||
sleep(1);
|
sleep(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
signal(SIGCONT, SIG_DFL);
|
signal(SIGCONT, SIG_DFL);
|
||||||
bb_got_signal = saved_bb_got_signal;
|
|
||||||
errno = saved_errno;
|
errno = saved_errno;
|
||||||
|
bb_got_signal = saved_bb_got_signal;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handler for QUIT - exec "restart" action,
|
/* Handler for QUIT - exec "restart" action,
|
||||||
@ -747,8 +748,14 @@ static void restart_handler(int sig UNUSED_PARAM)
|
|||||||
|
|
||||||
if (open_stdio_to_tty(a->terminal)) {
|
if (open_stdio_to_tty(a->terminal)) {
|
||||||
dbg_message(L_CONSOLE, "Trying to re-exec %s", a->command);
|
dbg_message(L_CONSOLE, "Trying to re-exec %s", a->command);
|
||||||
while (wait(NULL) > 0)
|
/* Theoretically should be safe.
|
||||||
continue;
|
* But in practice, kernel bugs may leave
|
||||||
|
* unkillable processes, and wait() may block forever.
|
||||||
|
* Oh well. Hoping "new" init won't be too surprised
|
||||||
|
* by having children it didn't create.
|
||||||
|
*/
|
||||||
|
//while (wait(NULL) > 0)
|
||||||
|
// continue;
|
||||||
init_exec(a->command);
|
init_exec(a->command);
|
||||||
}
|
}
|
||||||
/* Open or exec failed */
|
/* Open or exec failed */
|
||||||
@ -990,14 +997,14 @@ int init_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
|
|
||||||
got_sigs |= check_delayed_sigs();
|
got_sigs |= check_delayed_sigs();
|
||||||
|
|
||||||
|
if (got_sigs)
|
||||||
|
goto dont_block;
|
||||||
/* Wait for any child process to exit.
|
/* Wait for any child process to exit.
|
||||||
* NB: "delayed" signals will also interrupt this wait(),
|
* NB: "delayed" signals will also interrupt this wait(),
|
||||||
* bb_signals_recursive_norestart() set them up for that.
|
* bb_signals_recursive_norestart() set them up for that.
|
||||||
* This guarantees we won't be stuck here
|
* This guarantees we won't be stuck here
|
||||||
* till next orphan dies.
|
* till next orphan dies.
|
||||||
*/
|
*/
|
||||||
if (got_sigs)
|
|
||||||
goto dont_block;
|
|
||||||
wpid = wait(NULL);
|
wpid = wait(NULL);
|
||||||
while (wpid > 0) {
|
while (wpid > 0) {
|
||||||
struct init_action *a = mark_terminated(wpid);
|
struct init_action *a = mark_terminated(wpid);
|
||||||
|
Loading…
Reference in New Issue
Block a user