Skip to content
This repository has been archived by the owner on Jan 26, 2024. It is now read-only.

Commit

Permalink
Don't bother with ignoring SIGCHLD
Browse files Browse the repository at this point in the history
It added complexity, especially with the differences in behavior between
handled and ignored signals across an exec().
  • Loading branch information
djpohly authored and sevz17 committed Jun 16, 2023
1 parent 9c592da commit 68a17f9
Showing 1 changed file with 32 additions and 41 deletions.
73 changes: 32 additions & 41 deletions dwl.c
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ 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);
Expand Down Expand Up @@ -397,7 +398,6 @@ 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 sethints(struct wl_listener *listener, void *data);
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};
Expand Down Expand Up @@ -1963,8 +1963,6 @@ run(char *startup_cmd)
if ((child_pid = fork()) < 0)
die("startup: fork:");
if (child_pid == 0) {
sa.sa_handler = SIG_DFL;
sigaction(SIGCHLD, &sa, NULL);
dup2(piperw[0], STDIN_FILENO);
close(piperw[0]);
close(piperw[1]);
Expand Down Expand Up @@ -2129,27 +2127,19 @@ setsel(struct wl_listener *listener, void *data)
void
setup(void)
{
struct sigaction sa_term = {.sa_flags = SA_RESTART, .sa_handler = quitsignal};
struct sigaction sa_sigchld = {
#ifdef XWAYLAND
.sa_flags = SA_RESTART,
.sa_handler = sigchld,
#else
.sa_flags = SA_NOCLDSTOP | SA_NOCLDWAIT | SA_RESTART,
.sa_handler = SIG_IGN,
#endif
};
sigemptyset(&sa_term.sa_mask);
sigemptyset(&sa_sigchld.sa_mask);
/* 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);

/* 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();

/* Set up signal handlers */
sigaction(SIGCHLD, &sa_sigchld, NULL);
sigaction(SIGINT, &sa_term, NULL);
sigaction(SIGTERM, &sa_term, NULL);

/* The backend is a wlroots feature which abstracts the underlying input and
* output hardware. The autocreate option will choose the most suitable
* backend based on the current environment, such as opening an X11 window
Expand Down Expand Up @@ -2323,13 +2313,32 @@ 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)
{
if (fork() == 0) {
struct sigaction sa = {.sa_flags = SA_RESTART, .sa_handler = SIG_DFL};
sigemptyset(&sa.sa_mask);
sigaction(SIGCHLD, &sa, NULL);
dup2(STDERR_FILENO, STDOUT_FILENO);
setsid();
execvp(((char **)arg->v)[0], (char **)arg->v);
Expand Down Expand Up @@ -2772,24 +2781,6 @@ sethints(struct wl_listener *listener, void *data)
}
}

void
sigchld(int unused)
{
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);
}

void
xwaylandready(struct wl_listener *listener, void *data)
{
Expand Down

0 comments on commit 68a17f9

Please sign in to comment.