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

28
dwm.c
View File

@@ -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