aboutsummaryrefslogtreecommitdiff
path: root/initd
diff options
context:
space:
mode:
Diffstat (limited to 'initd')
-rw-r--r--initd/supervisor.c40
1 files changed, 29 insertions, 11 deletions
diff --git a/initd/supervisor.c b/initd/supervisor.c
index 5849b9c..c1b44e7 100644
--- a/initd/supervisor.c
+++ b/initd/supervisor.c
@@ -16,7 +16,6 @@ static size_t queue_count[TGT_MAX];
static size_t queue_idx = 0;
static int target = TGT_BOOT;
static size_t singleshot = 0;
-static bool waiting = false;
/*****************************************************************************/
@@ -57,7 +56,7 @@ fail:
static void check_target_completion(void)
{
- if (singleshot > 0 || queue_idx < queue_count[target] || waiting)
+ if (singleshot > 0 || queue_idx < queue_count[target])
return;
switch (target) {
@@ -105,11 +104,8 @@ void supervisor_handle_exited(pid_t pid, int status)
print_status(svc->desc, rt->state);
- if (svc->type == SVC_ONCE) {
+ if (svc->type == SVC_ONCE)
singleshot -= 1;
- } else if (svc->type == SVC_WAIT) {
- waiting = false;
- }
check_target_completion();
}
@@ -177,14 +173,25 @@ out:
print_status("reading configuration from " SVCDIR, status);
}
+static pid_t wait_for_process(int *status)
+{
+ pid_t pid = wait(status);
+
+ if (pid == -1 || !WIFEXITED(*status)) {
+ *status = EXIT_FAILURE;
+ } else {
+ *status = WEXITSTATUS(*status);
+ }
+ return pid;
+}
+
bool supervisor_process_queues(void)
{
svc_run_data_t *rt;
service_t *svc;
size_t count;
-
- if (waiting)
- return false;
+ int status;
+ pid_t pid;
count = queue_count[target];
if (queue_idx >= count)
@@ -198,12 +205,23 @@ bool supervisor_process_queues(void)
if (rt->pid == -1) {
rt->state = STATE_FAILED;
+ print_status(svc->desc, rt->state);
} else {
rt->state = STATE_RUNNING;
+ print_status(svc->desc, rt->state);
switch (svc->type) {
case SVC_WAIT:
- waiting = true;
+ for (;;) {
+ pid = wait_for_process(&status);
+ if (pid == rt->pid)
+ 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;
@@ -213,9 +231,9 @@ bool supervisor_process_queues(void)
} else {
rt->status = EXIT_SUCCESS;
rt->state = STATE_COMPLETED;
+ print_status(svc->desc, rt->state);
}
- print_status(svc->desc, rt->state);
check_target_completion();
return true;
}