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;
 | 
						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
 | 
					static void
 | 
				
			||||||
on_signal_pipe_readable (const struct pollfd *fd, struct bot_context *ctx)
 | 
					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;
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		struct plugin *plugin = plugin_find_by_pid (ctx, zombie);
 | 
							struct plugin *plugin = plugin_find_by_pid (ctx, zombie);
 | 
				
			||||||
		// Something has died but we don't recognize it (re-exec?)
 | 
							// XXX: re-exec if something has died that we don't recognize?
 | 
				
			||||||
		if (!soft_assert (plugin != NULL))
 | 
							if (soft_assert (plugin != NULL))
 | 
				
			||||||
			continue;
 | 
								on_plugin_death (plugin, status);
 | 
				
			||||||
 | 
					 | 
				
			||||||
		// 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);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user