diff options
Diffstat (limited to 'initd/main.c')
-rw-r--r-- | initd/main.c | 134 |
1 files changed, 59 insertions, 75 deletions
diff --git a/initd/main.c b/initd/main.c index 332722c..dc2e631 100644 --- a/initd/main.c +++ b/initd/main.c @@ -54,63 +54,6 @@ fail: return; } -static void check_target_completion(void) -{ - if (singleshot > 0 || queue_idx < queue_count[target]) - return; - - switch (target) { - case TGT_BOOT: - break; - case TGT_SHUTDOWN: - for (;;) - reboot(RB_POWER_OFF); - break; - case TGT_REBOOT: - for (;;) - reboot(RB_AUTOBOOT); - break; - } -} - -static void supervisor_handle_exited(pid_t pid, int status) -{ - svc_run_data_t *rt; - service_t *svc; - size_t i; - - for (i = 0; i < rt_count; ++i) { - if (rt_data[i].pid == pid) - break; - } - - if (i >= rt_count) - return; - - rt = rt_data + i; - svc = rt->svc; - rt->status = status; - rt->pid = -1; - - if (svc->type == SVC_RESPAWN) { - if (target != TGT_REBOOT && target != TGT_SHUTDOWN) - respawn(rt); - } else { - if (rt->status == EXIT_SUCCESS) { - rt->state = STATE_COMPLETED; - } else { - rt->state = STATE_FAILED; - } - - print_status(svc->desc, rt->state); - - if (svc->type == SVC_ONCE) - singleshot -= 1; - - check_target_completion(); - } -} - static void supervisor_init(void) { int status = STATE_FAILED; @@ -159,16 +102,43 @@ out: print_status("reading configuration from " SVCDIR, status); } -static pid_t wait_for_process(int *status) +static svc_run_data_t *wait_for_process(void) { - pid_t pid = wait(status); + svc_run_data_t *rt; + int status; + pid_t pid; + size_t i; + + do { + pid = wait(&status); + if (pid == -1) + return NULL; - if (pid == -1 || !WIFEXITED(*status)) { - *status = EXIT_FAILURE; + for (i = 0; i < rt_count && rt_data[i].pid != pid; ++i) + ; + } while (i >= rt_count); + + rt = rt_data + i; + rt->status = WIFEXITED(status) ? WEXITSTATUS(status) : EXIT_FAILURE; + rt->pid = -1; + + if (rt->svc->type == SVC_RESPAWN) { + if (target != TGT_REBOOT && target != TGT_SHUTDOWN) + respawn(rt); } else { - *status = WEXITSTATUS(*status); + if (rt->status == EXIT_SUCCESS) { + rt->state = STATE_COMPLETED; + } else { + rt->state = STATE_FAILED; + } + + print_status(rt->svc->desc, rt->state); + + if (rt->svc->type == SVC_ONCE) + singleshot -= 1; } - return pid; + + return rt; } static void handle_signal(int signo) @@ -193,14 +163,31 @@ static void handle_signal(int signo) } } +static void check_target_completion(void) +{ + if (singleshot > 0 || queue_idx < queue_count[target]) + return; + + switch (target) { + case TGT_BOOT: + break; + case TGT_SHUTDOWN: + for (;;) + reboot(RB_POWER_OFF); + break; + case TGT_REBOOT: + for (;;) + reboot(RB_AUTOBOOT); + break; + } +} + int main(void) { + svc_run_data_t *rt, *terminated; struct sigaction act; - svc_run_data_t *rt; service_t *svc; size_t count; - int status; - pid_t pid; supervisor_init(); @@ -219,8 +206,10 @@ int main(void) count = queue_count[target]; if (queue_idx >= count) { - pid = wait_for_process(&status); - supervisor_handle_exited(pid, status); + terminated = wait_for_process(); + + if (terminated != NULL) + check_target_completion(); continue; } @@ -240,15 +229,10 @@ int main(void) switch (svc->type) { case SVC_WAIT: for (;;) { - pid = wait_for_process(&status); - if (pid == rt->pid) + terminated = wait_for_process(); + if (terminated == rt) break; - supervisor_handle_exited(pid, status); } - - rt->state = status == EXIT_SUCCESS ? - STATE_COMPLETED : STATE_FAILED; - print_status(svc->desc, rt->state); break; case SVC_ONCE: singleshot += 1; |