From 5b5fc677b313908b8d1a775cd6af08202841d908 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Thu, 14 May 2020 16:31:49 +0200 Subject: Move handling of dead children back to SIGCHLD handler Signed-off-by: David Oberhollenzer --- initd/main.c | 52 ++++++++++++++++++++++------------------------------ 1 file changed, 22 insertions(+), 30 deletions(-) (limited to 'initd/main.c') diff --git a/initd/main.c b/initd/main.c index 6485842..d92a823 100644 --- a/initd/main.c +++ b/initd/main.c @@ -22,31 +22,6 @@ fail: return; } -static svc_run_data_t *wait_for_process(void) -{ - svc_run_data_t *rt; - int status; - pid_t pid; - - do { - pid = wait(&status); - - if (pid == -1) { - if (errno == EINTR) - return NULL; - - if (errno == ECHILD) - exit(EXIT_FAILURE); - } - - rt = config_rt_data_by_pid(pid); - } while (rt == NULL); - - rt->status = WIFEXITED(status) ? WEXITSTATUS(status) : EXIT_FAILURE; - rt->pid = -1; - return rt; -} - static void handle_exited(svc_run_data_t *rt) { if (rt->svc->type == SVC_RESPAWN) { @@ -85,6 +60,10 @@ static void start_service(svc_run_data_t *rt) static void handle_signal(int signo) { + svc_run_data_t *rt; + int status; + pid_t pid; + switch (signo) { case SIGTERM: config_set_target(TGT_SHUTDOWN); @@ -92,6 +71,22 @@ static void handle_signal(int signo) case SIGINT: config_set_target(TGT_REBOOT); break; + case SIGCHLD: + while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { + rt = config_rt_data_by_pid(pid); + if (rt == NULL) + continue; + + if (WIFEXITED(status)) { + rt->status = WEXITSTATUS(status); + } else { + rt->status = EXIT_FAILURE; + } + + rt->pid = -1; + handle_exited(rt); + } + break; case SIGHUP: break; case SIGUSR1: @@ -114,6 +109,7 @@ int main(void) sigaction(SIGINT, &act, NULL); sigaction(SIGHUP, &act, NULL); sigaction(SIGUSR1, &act, NULL); + sigaction(SIGCHLD, &act, NULL); if (reboot(LINUX_REBOOT_CMD_CAD_OFF)) perror("cannot disable CTRL+ALT+DEL"); @@ -122,11 +118,7 @@ int main(void) rt = config_dequeue(); if (rt == NULL) { - rt = wait_for_process(); - if (rt == NULL) - continue; - - handle_exited(rt); + pause(); } else { start_service(rt); } -- cgit v1.2.3