fix: faulty zombie reaping - tabbed - tab interface for application supporting … | |
git clone git://git.suckless.org/tabbed | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit fdf5fc7305e86bee82c1d7466d0d74936c135b07 | |
parent 41e2b8f30667078a4da04d5bd3d9eb839b118895 | |
Author: NRK <[email protected]> | |
Date: Sat, 11 Mar 2023 06:20:07 +0600 | |
fix: faulty zombie reaping | |
issues with the current signal handler: | |
1. die() isn't async-signal-safe | |
2. there's a race-window during reinstating the signal handler allowing | |
zombies to be produced (should be rare in practice). | |
3. if waitpid fails, it will clobber the errno which can lead to | |
undesired codepath being taken on the resuming code (this one can | |
actually occur in practice). | |
to reproduce the 3rd issue: | |
~> ./tabbed & | |
[1] 20644 | |
0x1800003 | |
~> while :; do kill -s SIGCHLD 20644; done >&2 2>/dev/null | |
XIO: fatal IO error 10 (No child processes) on X server ":0" | |
after 47 requests (47 known processed) with 0 events remaining. | |
[1] + exit 1 ./tabbed | |
set the signal handler to SIG_IGN to reap zombies automatically | |
(according to POSIX.1-2001). | |
NOTE: this patch follows dwm's commit 712d663. according to the manpage, | |
none of the sa_flags being set are meaningful since we're using SIG_IGN. | |
they used to be meaningful on earlier version of the patch where it was | |
using SIG_DFL, i've kept them here just in case. | |
Diffstat: | |
M Makefile | 2 +- | |
M tabbed.c | 21 +++++++++------------ | |
2 files changed, 10 insertions(+), 13 deletions(-) | |
--- | |
diff --git a/Makefile b/Makefile | |
@@ -11,7 +11,7 @@ DOCPREFIX = ${PREFIX}/share/doc/${NAME} | |
# use system flags. | |
TABBED_CFLAGS = -I/usr/X11R6/include -I/usr/include/freetype2 ${CFLAGS} | |
TABBED_LDFLAGS = -L/usr/X11R6/lib -lX11 -lfontconfig -lXft ${LDFLAGS} | |
-TABBED_CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE | |
+TABBED_CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=7… | |
# OpenBSD (uncomment) | |
#TABBED_CFLAGS = -I/usr/X11R6/include -I/usr/X11R6/include/freetype2 ${CFLAGS} | |
diff --git a/tabbed.c b/tabbed.c | |
@@ -125,7 +125,6 @@ static void run(void); | |
static void sendxembed(int c, long msg, long detail, long d1, long d2); | |
static void setcmd(int argc, char *argv[], int); | |
static void setup(void); | |
-static void sigchld(int unused); | |
static void spawn(const Arg *arg); | |
static int textnw(const char *text, unsigned int len); | |
static void toggle(const Arg *arg); | |
@@ -976,9 +975,16 @@ setup(void) | |
XWMHints *wmh; | |
XClassHint class_hint; | |
XSizeHints *size_hint; | |
+ 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 that might have been inherited */ | |
+ while (waitpid(-1, NULL, WNOHANG) > 0); | |
/* init screen */ | |
screen = DefaultScreen(dpy); | |
@@ -1079,15 +1085,6 @@ setup(void) | |
} | |
void | |
-sigchld(int unused) | |
-{ | |
- if (signal(SIGCHLD, sigchld) == SIG_ERR) | |
- die("%s: cannot install SIGCHLD handler", argv0); | |
- | |
- while (0 < waitpid(-1, NULL, WNOHANG)); | |
-} | |
- | |
-void | |
spawn(const Arg *arg) | |
{ | |
if (fork() == 0) { |