Use sigaction(SA_NOCLDWAIT) for SIGCHLD handling - dwm - dynamic window manager | |
git clone git://git.suckless.org/dwm | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 712d6639ff8e863560328131bbb92b248dc9cde7 | |
parent 89f9905714c1c1b2e8b09986dfbeca15b68d8af8 | |
Author: Chris Down <[email protected]> | |
Date: Sat, 28 Jan 2023 12:53:48 +0100 | |
Use sigaction(SA_NOCLDWAIT) for SIGCHLD handling | |
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 read 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. | |
Some addditional notes for archival purposes: | |
* NRK pointed out errno of waitpid could also theoretically get clobbered. | |
* The original patch was iterated on and modified by NRK and Hiltjo: | |
* SIG_DFL was changed to SIG_IGN, this is required, atleast on older systems | |
such as tested on Slackware 11. | |
* signals are not blocked using sigprocmask, because in theory it would | |
briefly for example also ignore a SIGTERM signal. It is OK if waitpid() is … | |
theory interrupted). | |
POSIX reference: | |
"Consequences of Process Termination": | |
https://pubs.opengroup.org/onlinepubs/9699919799/functions/_Exit.html#tag_16_01… | |
Diffstat: | |
M dwm.c | 20 +++++++++----------- | |
1 file changed, 9 insertions(+), 11 deletions(-) | |
--- | |
diff --git a/dwm.c b/dwm.c | |
@@ -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); | |
@@ -1543,9 +1542,16 @@ setup(void) | |
int i; | |
XSetWindowAttributes wa; | |
Atom utf8string; | |
+ struct sigaction sa; | |
- /* clean up any zombies immediately */ | |
- sigchld(0); | |
+ /* do not transform children into zombies when they terminate */ | |
+ sigemptyset(&sa.sa_mask); | |
+ sa.sa_flags = SA_NOCLDSTOP | SA_NOCLDWAIT | SA_RESTART; | |
+ sa.sa_handler = SIG_IGN; | |
+ sigaction(SIGCHLD, &sa, NULL); | |
+ | |
+ /* clean up any zombies (inherited from .xinitrc etc) immediately */ | |
+ while (waitpid(-1, NULL, WNOHANG) > 0); | |
/* init screen */ | |
screen = DefaultScreen(dpy); | |
@@ -1639,14 +1645,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) | |
{ | |
if (arg->v == dmenucmd) |