aboutsummaryrefslogtreecommitdiff
path: root/initd
diff options
context:
space:
mode:
authorDavid Oberhollenzer <goliath@infraroot.at>2020-05-13 18:17:53 +0200
committerDavid Oberhollenzer <goliath@infraroot.at>2020-05-13 18:20:43 +0200
commitf731537024c367368b728ed01c9232c3b1951589 (patch)
treeeb1ad4c429404715e9ccd8a71db065cdbf0a01f9 /initd
parent38c5b99ae73bd5812904e565a6daae9d2a3a8c73 (diff)
initd: merge "handle exited" into "wait for a child process"
Signed-off-by: David Oberhollenzer <goliath@infraroot.at>
Diffstat (limited to 'initd')
-rw-r--r--initd/main.c134
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;