summaryrefslogtreecommitdiff
path: root/zyklonb.c
diff options
context:
space:
mode:
Diffstat (limited to 'zyklonb.c')
-rw-r--r--zyklonb.c55
1 files changed, 30 insertions, 25 deletions
diff --git a/zyklonb.c b/zyklonb.c
index 6b06caa..3c147a5 100644
--- a/zyklonb.c
+++ b/zyklonb.c
@@ -1787,6 +1787,32 @@ on_plugin_death (struct plugin *plugin, int status)
try_finish_quit (ctx);
}
+static bool
+try_reap_plugin (struct bot_context *ctx)
+{
+ int status;
+ pid_t zombie = waitpid (-1, &status, WNOHANG);
+
+ if (zombie == -1)
+ {
+ // No children to wait on
+ if (errno == ECHILD)
+ return false;
+
+ hard_assert (errno == EINTR);
+ return true;
+ }
+
+ if (zombie == 0)
+ return false;
+
+ struct plugin *plugin = plugin_find_by_pid (ctx, zombie);
+ // XXX: re-exec if something has died that we don't recognize?
+ if (soft_assert (plugin != NULL))
+ on_plugin_death (plugin, status);
+ return true;
+}
+
static void
on_signal_pipe_readable (const struct pollfd *fd, struct bot_context *ctx)
{
@@ -1803,31 +1829,10 @@ on_signal_pipe_readable (const struct pollfd *fd, struct bot_context *ctx)
initiate_quit (ctx);
}
- // Reap all dead children (since the pipe may overflow, we ask waitpid()
- // to return all the zombies it knows about).
- while (true)
- {
- int status;
- pid_t zombie = waitpid (-1, &status, WNOHANG);
-
- if (zombie == -1)
- {
- // No children to wait on
- if (errno == ECHILD)
- break;
-
- hard_assert (errno == EINTR);
- continue;
- }
-
- if (zombie == 0)
- break;
-
- struct plugin *plugin = plugin_find_by_pid (ctx, zombie);
- // XXX: re-exec if something has died that we don't recognize?
- if (soft_assert (plugin != NULL))
- on_plugin_death (plugin, status);
- }
+ // Reap all dead children (since the signal pipe may overflow etc. we run
+ // waitpid() in a loop to return all the zombies it knows about).
+ while (try_reap_plugin (ctx))
+ ;
}
int