From e08bd1292288f662eb265461a8c1a9d7501b0445 Mon Sep 17 00:00:00 2001 From: "Devin J. Pohly" Date: Tue, 29 Mar 2022 15:55:06 -0500 Subject: [PATCH 1/2] make sure to leave XWayland process waitable On SIGCHLD, check to make sure the terminated process is not the XWayland process before reaping it, allowing wlroots to waitpid() for it successfully. Fixes #177. --- dwl.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/dwl.c b/dwl.c index 3f66be4..a14dc5c 100644 --- a/dwl.c +++ b/dwl.c @@ -1925,6 +1925,7 @@ setup(void) void sigchld(int unused) { + siginfo_t in; /* We should be able to remove this function in favor of a simple * signal(SIGCHLD, SIG_IGN); * but the Xwayland implementation in wlroots currently prevents us from @@ -1932,8 +1933,12 @@ sigchld(int unused) */ if (signal(SIGCHLD, sigchld) == SIG_ERR) EBARF("can't install SIGCHLD handler"); - while (0 < waitpid(-1, NULL, WNOHANG)) - ; + /* 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 + && in.si_pid != xwayland->server->pid) + waitpid(in.si_pid, NULL, 0); } void From 0ddde0c85a46370759e85f3437e3475b569d5c41 Mon Sep 17 00:00:00 2001 From: "Devin J. Pohly" Date: Tue, 29 Mar 2022 16:09:29 -0500 Subject: [PATCH 2/2] move sigchld() into XWayland section --- dwl.c | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/dwl.c b/dwl.c index a14dc5c..ae5ed93 100644 --- a/dwl.c +++ b/dwl.c @@ -258,7 +258,6 @@ static void setlayout(const Arg *arg); static void setmfact(const Arg *arg); static void setmon(Client *c, Monitor *m, unsigned int newtags); 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); @@ -341,6 +340,7 @@ static void activatex11(struct wl_listener *listener, void *data); static void configurex11(struct wl_listener *listener, void *data); static void createnotifyx11(struct wl_listener *listener, void *data); static Atom getatom(xcb_connection_t *xc, const char *name); +static void sigchld(int unused); static void xwaylandready(struct wl_listener *listener, void *data); static struct wl_listener new_xwayland_surface = {.notify = createnotifyx11}; static struct wl_listener xwayland_ready = {.notify = xwaylandready}; @@ -1762,7 +1762,11 @@ setup(void) dpy = wl_display_create(); /* Set up signal handlers */ +#ifdef XWAYLAND sigchld(0); +#else + signal(SIGCHLD, SIG_IGN); +#endif signal(SIGINT, quitsignal); signal(SIGTERM, quitsignal); @@ -1922,25 +1926,6 @@ setup(void) #endif } -void -sigchld(int unused) -{ - siginfo_t in; - /* We should be able to remove this function in favor of a simple - * signal(SIGCHLD, SIG_IGN); - * but the Xwayland implementation in wlroots currently prevents us from - * setting our own disposition for SIGCHLD. - */ - if (signal(SIGCHLD, sigchld) == SIG_ERR) - EBARF("can't install SIGCHLD handler"); - /* 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 - && in.si_pid != xwayland->server->pid) - waitpid(in.si_pid, NULL, 0); -} - void spawn(const Arg *arg) { @@ -2317,6 +2302,25 @@ getatom(xcb_connection_t *xc, const char *name) return atom; } +void +sigchld(int unused) +{ + siginfo_t in; + /* We should be able to remove this function in favor of a simple + * signal(SIGCHLD, SIG_IGN); + * but the Xwayland implementation in wlroots currently prevents us from + * setting our own disposition for SIGCHLD. + */ + if (signal(SIGCHLD, sigchld) == SIG_ERR) + EBARF("can't install SIGCHLD handler"); + /* 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 + && in.si_pid != xwayland->server->pid) + waitpid(in.si_pid, NULL, 0); +} + void xwaylandready(struct wl_listener *listener, void *data) {