[hackers] [dwm][PATCH v2] Use sigaction(SA_NOCLDWAIT) for SIGCHLD handling

From: Chris Down <chris_AT_chrisdown.name>
Date: Wed, 27 Jul 2022 07:36:28 +0100

signal() semantics are pretty unclearly specified. For example,
depending on OS kernel and libc, the handler may be returned to SIG_DFL
(hence the inner call to readd the signal handler). Moving to
sigaction() means the behaviour is consistently defined.

Using SA_NOCLDWAIT also allows us to avoid calling the non-reentrant
function die() in the handler.

waitpid() and sigaction() can also fail with EINTR, which may mean our
zombie handling fails, so block signals while setting things up to be
careful.
---
 dwm.c | 25 ++++++++++++++-----------
 1 file changed, 14 insertions(+), 11 deletions(-)
diff --git a/dwm.c b/dwm.c
index b3c43ee..963baca 100644
--- a/dwm.c
+++ b/dwm.c
_AT_@ -205,7 +205,6 @@ static void setmfact(const Arg *arg);
 static void setup(void);
 static void seturgent(Client *c, int urg);
 static void showhide(Client *c);
-static void sigchld(int unused);
 static void spawn(const Arg *arg);
 static void tag(const Arg *arg);
 static void tagmon(const Arg *arg);
_AT_@ -1537,11 +1536,23 @@ void
 setup(void)
 {
 	int i;
+	sigset_t sm, oldsm;
 	XSetWindowAttributes wa;
 	Atom utf8string;
+	const struct sigaction sc = {
+		.sa_handler = SIG_DFL,
+		.sa_flags = SA_RESTART | SA_NOCLDWAIT | SA_NOCLDSTOP,
+	};
+
+	sigfillset(&sm);
+	sigprocmask(SIG_SETMASK, &sm, &oldsm);
 
-	/* clean up any zombies immediately */
-	sigchld(0);
+	if (sigaction(SIGCHLD, &sc, NULL) < 0)
+		die("sigaction failed:");
+	/* for zombies inherited before SA_NOCLDWAIT from .xinitrc, etc */
+	while (waitpid(-1, NULL, WNOHANG) > 0);
+
+	sigprocmask(SIG_SETMASK, &oldsm, NULL);
 
 	/* init screen */
 	screen = DefaultScreen(dpy);
_AT_@ -1635,14 +1646,6 @@ showhide(Client *c)
 	}
 }
 
-void
-sigchld(int unused)
-{
-	if (signal(SIGCHLD, sigchld) == SIG_ERR)
-		die("can't install SIGCHLD handler:");
-	while (0 < waitpid(-1, NULL, WNOHANG));
-}
-
 void
 spawn(const Arg *arg)
 {
-- 
2.37.1
Received on Wed Jul 27 2022 - 08:36:28 CEST

This archive was generated by hypermail 2.3.0 : Wed Jul 27 2022 - 11:24:31 CEST