diff --git a/zyklonb.c b/zyklonb.c index aef0372..7760ed1 100644 --- a/zyklonb.c +++ b/zyklonb.c @@ -1817,20 +1817,41 @@ try_reap_plugin (struct bot_context *ctx) return true; } +static void +kill_all_zombies (struct bot_context *ctx) +{ + for (struct plugin *plugin = ctx->plugins; plugin; plugin = plugin->next) + { + if (!plugin->is_zombie) + continue; + + print_status ("forcefully killing a zombie of `%s' (PID %d)", + plugin->name, (int) plugin->pid); + kill (plugin->pid, SIGKILL); + } +} + static void on_signal_pipe_readable (const struct pollfd *fd, struct bot_context *ctx) { char dummy; (void) read (fd->fd, &dummy, 1); - if (g_termination_requested && !ctx->quitting) + if (g_termination_requested) { - // There may be a timer set to reconnect to the server - irc_cancel_timers (ctx); + g_termination_requested = false; + if (!ctx->quitting) + { + // There may be a timer set to reconnect to the server + irc_cancel_timers (ctx); - if (ctx->irc_fd != -1) - irc_send (ctx, "QUIT :Terminated by signal"); - initiate_quit (ctx); + if (ctx->irc_fd != -1) + irc_send (ctx, "QUIT :Terminated by signal"); + initiate_quit (ctx); + } + else + // Disregard proper termination, just kill all the children + kill_all_zombies (ctx); } // Reap all dead children (since the signal pipe may overflow etc. we run