aboutsummaryrefslogtreecommitdiff
path: root/initd/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'initd/main.c')
-rw-r--r--initd/main.c52
1 files changed, 22 insertions, 30 deletions
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);
}