From 91551329e93e794001b04459a4399c074f4cf7ae Mon Sep 17 00:00:00 2001 From: bakkeby Date: Mon, 30 Jan 2023 09:45:51 +0100 Subject: [PATCH] Bump to 712d663. 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 (in theory interrupted). POSIX reference: "Consequences of Process Termination": https://pubs.opengroup.org/onlinepubs/9699919799/functions/_Exit.html#tag_16_01_03_01 Ref. https://git.suckless.org/dwm/commit/712d6639ff8e863560328131bbb92b248dc9cde7.html NB: Cool autostart patch to use prior logic for now --- README.md | 2 +- dwm.c | 28 ++++++++++++++++++++-------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 34a5f2b..633f953 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -This dwm 6.4 (89f9905, 2022-12-07) side project has a different take on dwm patching. It uses preprocessor directives to decide whether or not to include a patch during build time. Essentially this means that this build, for better or worse, contains both the patched _and_ the original code. The aim being that you can select which patches to include and the build will contain that code and nothing more. Due to the complexity of some of the patches dwm-flexipatch has diverged from mainstream dwm by making some core patches non-optional for maintenance reasons. For the classic dwm-flexipatch build refer to branch [dwm-flexipatch-1.0](https://github.com/bakkeby/dwm-flexipatch/tree/dwm-flexipatch-1.0). +This dwm 6.4 (712d663, 2023-01-28) side project has a different take on dwm patching. It uses preprocessor directives to decide whether or not to include a patch during build time. Essentially this means that this build, for better or worse, contains both the patched _and_ the original code. The aim being that you can select which patches to include and the build will contain that code and nothing more. Due to the complexity of some of the patches dwm-flexipatch has diverged from mainstream dwm by making some core patches non-optional for maintenance reasons. For the classic dwm-flexipatch build refer to branch [dwm-flexipatch-1.0](https://github.com/bakkeby/dwm-flexipatch/tree/dwm-flexipatch-1.0). For example to include the `alpha` patch then you would only need to flip this setting from 0 to 1 in [patches.h](https://github.com/bakkeby/dwm-flexipatch/blob/master/patches.def.h): ```c diff --git a/dwm.c b/dwm.c index 91e0f2a..3d3eef0 100644 --- a/dwm.c +++ b/dwm.c @@ -706,8 +706,10 @@ static void setlayout(const Arg *arg); static void setmfact(const Arg *arg); static void setup(void); static void seturgent(Client *c, int urg); -static void showhide(Client *c); +#if COOL_AUTOSTART_PATCH static void sigchld(int unused); +#endif // COOL_AUTOSTART_PATCH +static void showhide(Client *c); static void spawn(const Arg *arg); #if RIODRAW_PATCH static pid_t spawncmd(const Arg *arg); @@ -3648,9 +3650,21 @@ setup(void) XkbStateRec xkbstate; #endif // XKB_PATCH Atom utf8string; - + #if COOL_AUTOSTART_PATCH /* clean up any zombies immediately */ sigchld(0); + #else + struct sigaction sa; + + /* 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); + #endif // COOL_AUTOSTART_PATCH #if RESTARTSIG_PATCH signal(SIGHUP, sighup); @@ -3931,15 +3945,15 @@ showhide(Client *c) } } +#if COOL_AUTOSTART_PATCH void sigchld(int unused) { - #if COOL_AUTOSTART_PATCH pid_t pid; - #endif // COOL_AUTOSTART_PATCH + if (signal(SIGCHLD, sigchld) == SIG_ERR) die("can't install SIGCHLD handler:"); - #if COOL_AUTOSTART_PATCH + while (0 < (pid = waitpid(-1, NULL, WNOHANG))) { pid_t *p, *lim; @@ -3954,10 +3968,8 @@ sigchld(int unused) } } } - #else - while (0 < waitpid(-1, NULL, WNOHANG)); - #endif // COOL_AUTOSTART_PATCH } +#endif // COOL_AUTOSTART_PATCH #if RIODRAW_PATCH void