ZyklonB: factor out on_plugin_death()
This commit is contained in:
		
							
								
								
									
										86
									
								
								zyklonb.c
									
									
									
									
									
								
							
							
						
						
									
										86
									
								
								zyklonb.c
									
									
									
									
									
								
							@@ -1744,6 +1744,49 @@ parse_config (struct bot_context *ctx, struct error **e)
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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)
 | 
			
		||||
{
 | 
			
		||||
@@ -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);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user