ZyklonB: factor out on_plugin_death()
This commit is contained in:
		
							
								
								
									
										82
									
								
								zyklonb.c
									
									
									
									
									
								
							
							
						
						
									
										82
									
								
								zyklonb.c
									
									
									
									
									
								
							@@ -1745,45 +1745,9 @@ parse_config (struct bot_context *ctx, struct error **e)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_signal_pipe_readable (const struct pollfd *fd, struct bot_context *ctx)
 | 
			
		||||
on_plugin_death (struct plugin *plugin, int status)
 | 
			
		||||
{
 | 
			
		||||
	char dummy;
 | 
			
		||||
	(void) read (fd->fd, &dummy, 1);
 | 
			
		||||
 | 
			
		||||
	if (g_termination_requested && !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);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 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);
 | 
			
		||||
		// Something has died but we don't recognize it (re-exec?)
 | 
			
		||||
		if (!soft_assert (plugin != NULL))
 | 
			
		||||
			continue;
 | 
			
		||||
	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'
 | 
			
		||||
@@ -1821,6 +1785,48 @@ on_signal_pipe_readable (const struct pollfd *fd, struct bot_context *ctx)
 | 
			
		||||
 | 
			
		||||
	// 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;
 | 
			
		||||
	(void) read (fd->fd, &dummy, 1);
 | 
			
		||||
 | 
			
		||||
	if (g_termination_requested && !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);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 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);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user