diff options
author | Přemysl Janouch <p.janouch@gmail.com> | 2015-06-15 00:53:42 +0200 |
---|---|---|
committer | Přemysl Janouch <p.janouch@gmail.com> | 2015-06-15 00:53:42 +0200 |
commit | e34ecd6bb9cef25833bdb941ab7fc9fd67a6487f (patch) | |
tree | ee85a8eeae615cc040cbbb1f8c45bdb0bb869662 /zyklonb.c | |
parent | 634841ea18eab7f1a050734bff9b65fbf477d440 (diff) | |
download | xK-e34ecd6bb9cef25833bdb941ab7fc9fd67a6487f.tar.gz xK-e34ecd6bb9cef25833bdb941ab7fc9fd67a6487f.tar.xz xK-e34ecd6bb9cef25833bdb941ab7fc9fd67a6487f.zip |
ZyklonB: factor out on_plugin_death()
Diffstat (limited to 'zyklonb.c')
-rw-r--r-- | zyklonb.c | 86 |
1 files changed, 46 insertions, 40 deletions
@@ -1745,6 +1745,49 @@ parse_config (struct bot_context *ctx, struct error **e) } static void +on_plugin_death (struct plugin *plugin, int status) +{ + struct bot_context *ctx = plugin->ctx; + + // TODO: callbacks on children death, so that we may tell the user + // "plugin `name' died like a dirty jewish pig"; use `status' + if (!plugin->is_zombie && WIFSIGNALED (status)) + { + const char *notes = ""; +#ifdef WCOREDUMP + if (WCOREDUMP (status)) + notes = " (core dumped)"; +#endif + print_warning ("Plugin `%s' died from signal %d%s", + plugin->name, WTERMSIG (status), notes); + } + + // Let's go through the zombie state to simplify things a bit + // TODO: might not be a completely bad idea to restart the plugin + plugin_zombify (plugin); + + plugin->pid = -1; + + // In theory we could close `read_fd', set `read_event->closed' to true + // and expect epoll to no longer return events for the descriptor, as + // all the pipe ends should be closed by then (the child is dead, so its + // pipe FDs have been closed [assuming it hasn't forked without closing + // the descriptors, which would be evil], and we would have closed all + // of our FDs for this pipe as well). In practice that doesn't work. + poller_fd_reset (&plugin->read_event); + + xclose (plugin->read_fd); + plugin->read_fd = -1; + + LIST_UNLINK (ctx->plugins, plugin); + plugin_free (plugin); + free (plugin); + + // Living child processes block us from quitting + try_finish_quit (ctx); +} + +static void on_signal_pipe_readable (const struct pollfd *fd, struct bot_context *ctx) { char dummy; @@ -1781,46 +1824,9 @@ on_signal_pipe_readable (const struct pollfd *fd, struct bot_context *ctx) break; struct plugin *plugin = plugin_find_by_pid (ctx, zombie); - // Something has died but we don't recognize it (re-exec?) - if (!soft_assert (plugin != NULL)) - continue; - - // TODO: callbacks on children death, so that we may tell the user - // "plugin `name' died like a dirty jewish pig"; use `status' - if (!plugin->is_zombie && WIFSIGNALED (status)) - { - const char *notes = ""; -#ifdef WCOREDUMP - if (WCOREDUMP (status)) - notes = " (core dumped)"; -#endif - print_warning ("Plugin `%s' died from signal %d%s", - plugin->name, WTERMSIG (status), notes); - } - - // Let's go through the zombie state to simplify things a bit - // TODO: might not be a completely bad idea to restart the plugin - plugin_zombify (plugin); - - plugin->pid = -1; - - // In theory we could close `read_fd', set `read_event->closed' to true - // and expect epoll to no longer return events for the descriptor, as - // all the pipe ends should be closed by then (the child is dead, so its - // pipe FDs have been closed [assuming it hasn't forked without closing - // the descriptors, which would be evil], and we would have closed all - // of our FDs for this pipe as well). In practice that doesn't work. - poller_fd_reset (&plugin->read_event); - - xclose (plugin->read_fd); - plugin->read_fd = -1; - - LIST_UNLINK (ctx->plugins, plugin); - plugin_free (plugin); - free (plugin); - - // Living child processes block us from quitting - try_finish_quit (ctx); + // XXX: re-exec if something has died that we don't recognize? + if (soft_assert (plugin != NULL)) + on_plugin_death (plugin, status); } } |