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
This commit is contained in:
bakkeby 2023-01-30 09:45:51 +01:00
parent f713ddee39
commit 91551329e9
2 changed files with 21 additions and 9 deletions

View File

@ -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): 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 ```c

28
dwm.c
View File

@ -706,8 +706,10 @@ static void setlayout(const Arg *arg);
static void setmfact(const Arg *arg); static void setmfact(const Arg *arg);
static void setup(void); static void setup(void);
static void seturgent(Client *c, int urg); static void seturgent(Client *c, int urg);
static void showhide(Client *c); #if COOL_AUTOSTART_PATCH
static void sigchld(int unused); static void sigchld(int unused);
#endif // COOL_AUTOSTART_PATCH
static void showhide(Client *c);
static void spawn(const Arg *arg); static void spawn(const Arg *arg);
#if RIODRAW_PATCH #if RIODRAW_PATCH
static pid_t spawncmd(const Arg *arg); static pid_t spawncmd(const Arg *arg);
@ -3648,9 +3650,21 @@ setup(void)
XkbStateRec xkbstate; XkbStateRec xkbstate;
#endif // XKB_PATCH #endif // XKB_PATCH
Atom utf8string; Atom utf8string;
#if COOL_AUTOSTART_PATCH
/* clean up any zombies immediately */ /* clean up any zombies immediately */
sigchld(0); 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 #if RESTARTSIG_PATCH
signal(SIGHUP, sighup); signal(SIGHUP, sighup);
@ -3931,15 +3945,15 @@ showhide(Client *c)
} }
} }
#if COOL_AUTOSTART_PATCH
void void
sigchld(int unused) sigchld(int unused)
{ {
#if COOL_AUTOSTART_PATCH
pid_t pid; pid_t pid;
#endif // COOL_AUTOSTART_PATCH
if (signal(SIGCHLD, sigchld) == SIG_ERR) if (signal(SIGCHLD, sigchld) == SIG_ERR)
die("can't install SIGCHLD handler:"); die("can't install SIGCHLD handler:");
#if COOL_AUTOSTART_PATCH
while (0 < (pid = waitpid(-1, NULL, WNOHANG))) { while (0 < (pid = waitpid(-1, NULL, WNOHANG))) {
pid_t *p, *lim; 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 #if RIODRAW_PATCH
void void