Unify signal handling under wl_event_loop
Merge our signal handlers into a single function and let Wayland deal with all the struct sigaction stuff. ΔSLOC: -3
This commit is contained in:
		
				
					committed by
					
						
						Leonardo Hernández
					
				
			
			
				
	
			
			
			
						parent
						
							eda0613cc4
						
					
				
				
					commit
					fbd84aca4a
				
			
							
								
								
									
										83
									
								
								dwl.c
									
									
									
									
									
								
							
							
						
						
									
										83
									
								
								dwl.c
									
									
									
									
									
								
							@@ -260,6 +260,7 @@ static void focusmon(const Arg *arg);
 | 
			
		||||
static void focusstack(const Arg *arg);
 | 
			
		||||
static Client *focustop(Monitor *m);
 | 
			
		||||
static void fullscreennotify(struct wl_listener *listener, void *data);
 | 
			
		||||
static int handlesig(int signo, void *data);
 | 
			
		||||
static void incnmaster(const Arg *arg);
 | 
			
		||||
static void inputdevice(struct wl_listener *listener, void *data);
 | 
			
		||||
static int keybinding(uint32_t mods, xkb_keysym_t sym);
 | 
			
		||||
@@ -283,7 +284,6 @@ static void pointerfocus(Client *c, struct wlr_surface *surface,
 | 
			
		||||
		double sx, double sy, uint32_t time);
 | 
			
		||||
static void printstatus(void);
 | 
			
		||||
static void quit(const Arg *arg);
 | 
			
		||||
static void quitsignal(int signo);
 | 
			
		||||
static void rendermon(struct wl_listener *listener, void *data);
 | 
			
		||||
static void requeststartdrag(struct wl_listener *listener, void *data);
 | 
			
		||||
static void resize(Client *c, struct wlr_box geo, int interact);
 | 
			
		||||
@@ -297,7 +297,6 @@ static void setmon(Client *c, Monitor *m, uint32_t newtags);
 | 
			
		||||
static void setpsel(struct wl_listener *listener, void *data);
 | 
			
		||||
static void setsel(struct wl_listener *listener, void *data);
 | 
			
		||||
static void setup(void);
 | 
			
		||||
static void sigchld(int unused);
 | 
			
		||||
static void spawn(const Arg *arg);
 | 
			
		||||
static void startdrag(struct wl_listener *listener, void *data);
 | 
			
		||||
static void tag(const Arg *arg);
 | 
			
		||||
@@ -327,6 +326,8 @@ static pid_t child_pid = -1;
 | 
			
		||||
static int locked;
 | 
			
		||||
static void *exclusive_focus;
 | 
			
		||||
static struct wl_display *dpy;
 | 
			
		||||
static struct wl_event_loop *eventloop;
 | 
			
		||||
static struct wl_event_source *sighandler[4];
 | 
			
		||||
static struct wlr_backend *backend;
 | 
			
		||||
static struct wlr_scene *scene;
 | 
			
		||||
static struct wlr_scene_tree *layers[NUM_LAYERS];
 | 
			
		||||
@@ -652,6 +653,7 @@ checkidleinhibitor(struct wlr_surface *exclude)
 | 
			
		||||
void
 | 
			
		||||
cleanup(void)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
#ifdef XWAYLAND
 | 
			
		||||
	wlr_xwayland_destroy(xwayland);
 | 
			
		||||
#endif
 | 
			
		||||
@@ -667,6 +669,8 @@ cleanup(void)
 | 
			
		||||
	wlr_cursor_destroy(cursor);
 | 
			
		||||
	wlr_output_layout_destroy(output_layout);
 | 
			
		||||
	wlr_seat_destroy(seat);
 | 
			
		||||
	for (i = 0; i < LENGTH(sighandler); i++)
 | 
			
		||||
		wl_event_source_remove(sighandler[i]);
 | 
			
		||||
	wl_display_destroy(dpy);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -820,8 +824,7 @@ createkeyboard(struct wlr_keyboard *keyboard)
 | 
			
		||||
 | 
			
		||||
	wlr_seat_set_keyboard(seat, keyboard);
 | 
			
		||||
 | 
			
		||||
	kb->key_repeat_source = wl_event_loop_add_timer(
 | 
			
		||||
			wl_display_get_event_loop(dpy), keyrepeat, kb);
 | 
			
		||||
	kb->key_repeat_source = wl_event_loop_add_timer(eventloop, keyrepeat, kb);
 | 
			
		||||
 | 
			
		||||
	/* And add the keyboard to our list of keyboards */
 | 
			
		||||
	wl_list_insert(&keyboards, &kb->link);
 | 
			
		||||
@@ -1333,6 +1336,28 @@ fullscreennotify(struct wl_listener *listener, void *data)
 | 
			
		||||
	setfullscreen(c, client_wants_fullscreen(c));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
handlesig(int signo, void *data)
 | 
			
		||||
{
 | 
			
		||||
	if (signo == SIGCHLD) {
 | 
			
		||||
#ifdef XWAYLAND
 | 
			
		||||
		siginfo_t in;
 | 
			
		||||
		/* wlroots expects to reap the XWayland process itself, so we
 | 
			
		||||
		 * use WNOWAIT to keep the child waitable until we know it's not
 | 
			
		||||
		 * XWayland.
 | 
			
		||||
		 */
 | 
			
		||||
		while (!waitid(P_ALL, 0, &in, WEXITED|WNOHANG|WNOWAIT) && in.si_pid
 | 
			
		||||
				&& (!xwayland || in.si_pid != xwayland->server->pid))
 | 
			
		||||
			waitpid(in.si_pid, NULL, 0);
 | 
			
		||||
#else
 | 
			
		||||
		while (waitpid(-1, NULL, WNOHANG) > 0);
 | 
			
		||||
#endif
 | 
			
		||||
	} else if (signo == SIGINT || signo == SIGTERM) {
 | 
			
		||||
		quit(NULL);
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
incnmaster(const Arg *arg)
 | 
			
		||||
{
 | 
			
		||||
@@ -1875,12 +1900,6 @@ quit(const Arg *arg)
 | 
			
		||||
	wl_display_terminate(dpy);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
quitsignal(int signo)
 | 
			
		||||
{
 | 
			
		||||
	quit(NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
rendermon(struct wl_listener *listener, void *data)
 | 
			
		||||
{
 | 
			
		||||
@@ -1944,8 +1963,6 @@ run(char *startup_cmd)
 | 
			
		||||
{
 | 
			
		||||
	/* Add a Unix socket to the Wayland display. */
 | 
			
		||||
	const char *socket = wl_display_add_socket_auto(dpy);
 | 
			
		||||
	struct sigaction sa = {.sa_flags = SA_RESTART, .sa_handler = SIG_IGN};
 | 
			
		||||
	sigemptyset(&sa.sa_mask);
 | 
			
		||||
	if (!socket)
 | 
			
		||||
		die("startup: display_add_socket_auto");
 | 
			
		||||
	setenv("WAYLAND_DISPLAY", socket, 1);
 | 
			
		||||
@@ -1973,8 +1990,6 @@ run(char *startup_cmd)
 | 
			
		||||
		close(piperw[1]);
 | 
			
		||||
		close(piperw[0]);
 | 
			
		||||
	}
 | 
			
		||||
	/* If nobody is reading the status output, don't terminate */
 | 
			
		||||
	sigaction(SIGPIPE, &sa, NULL);
 | 
			
		||||
	printstatus();
 | 
			
		||||
 | 
			
		||||
	/* At this point the outputs are initialized, choose initial selmon based on
 | 
			
		||||
@@ -2127,20 +2142,14 @@ setsel(struct wl_listener *listener, void *data)
 | 
			
		||||
void
 | 
			
		||||
setup(void)
 | 
			
		||||
{
 | 
			
		||||
	int layer;
 | 
			
		||||
 | 
			
		||||
	/* Set up signal handlers */
 | 
			
		||||
	struct sigaction sa = {.sa_flags = SA_RESTART, .sa_handler = sigchld};
 | 
			
		||||
	sigemptyset(&sa.sa_mask);
 | 
			
		||||
	sigaction(SIGCHLD, &sa, NULL);
 | 
			
		||||
 | 
			
		||||
	sa.sa_handler = quitsignal;
 | 
			
		||||
	sigaction(SIGINT, &sa, NULL);
 | 
			
		||||
	sigaction(SIGTERM, &sa, NULL);
 | 
			
		||||
	int i, sig[] = {SIGCHLD, SIGINT, SIGTERM, SIGPIPE};
 | 
			
		||||
 | 
			
		||||
	/* The Wayland display is managed by libwayland. It handles accepting
 | 
			
		||||
	 * clients from the Unix socket, manging Wayland globals, and so on. */
 | 
			
		||||
	dpy = wl_display_create();
 | 
			
		||||
	eventloop = wl_display_get_event_loop(dpy);
 | 
			
		||||
	for (i = 0; i < LENGTH(sighandler); i++)
 | 
			
		||||
		sighandler[i] = wl_event_loop_add_signal(eventloop, sig[i], handlesig, NULL);
 | 
			
		||||
 | 
			
		||||
	/* The backend is a wlroots feature which abstracts the underlying input and
 | 
			
		||||
	 * output hardware. The autocreate option will choose the most suitable
 | 
			
		||||
@@ -2155,8 +2164,8 @@ setup(void)
 | 
			
		||||
 | 
			
		||||
	/* Initialize the scene graph used to lay out windows */
 | 
			
		||||
	scene = wlr_scene_create();
 | 
			
		||||
	for (layer = 0; layer < NUM_LAYERS; layer++)
 | 
			
		||||
		layers[layer] = wlr_scene_tree_create(&scene->tree);
 | 
			
		||||
	for (i = 0; i < NUM_LAYERS; i++)
 | 
			
		||||
		layers[i] = wlr_scene_tree_create(&scene->tree);
 | 
			
		||||
 | 
			
		||||
	/* Create a renderer with the default implementation */
 | 
			
		||||
	if (!(drw = wlr_renderer_autocreate(backend)))
 | 
			
		||||
@@ -2308,28 +2317,6 @@ setup(void)
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
sigchld(int unused)
 | 
			
		||||
{
 | 
			
		||||
#ifdef XWAYLAND
 | 
			
		||||
	siginfo_t in;
 | 
			
		||||
	/* We should be able to remove this function in favor of a simple
 | 
			
		||||
	 *	struct sigaction sa = {.sa_handler = SIG_IGN};
 | 
			
		||||
	 * 	sigaction(SIGCHLD, &sa, NULL);
 | 
			
		||||
	 * but the Xwayland implementation in wlroots currently prevents us from
 | 
			
		||||
	 * setting our own disposition for SIGCHLD.
 | 
			
		||||
	 */
 | 
			
		||||
	/* WNOWAIT leaves the child in a waitable state, in case this is the
 | 
			
		||||
	 * XWayland process
 | 
			
		||||
	 */
 | 
			
		||||
	while (!waitid(P_ALL, 0, &in, WEXITED|WNOHANG|WNOWAIT) && in.si_pid
 | 
			
		||||
			&& (!xwayland || in.si_pid != xwayland->server->pid))
 | 
			
		||||
		waitpid(in.si_pid, NULL, 0);
 | 
			
		||||
#else
 | 
			
		||||
	while (waitpid(-1, NULL, WNOHANG) > 0);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
spawn(const Arg *arg)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user