[hackers] [dwm] Use sigaction(SA_NOCLDWAIT) for SIGCHLD handling || Chris Down

From: <git_AT_suckless.org>
Date: Sat, 28 Jan 2023 13:34:55 +0100 (CET)

commit 712d6639ff8e863560328131bbb92b248dc9cde7
Author: Chris Down <chris_AT_chrisdown.name>
AuthorDate: Sat Jan 28 12:53:48 2023 +0100
Commit: Hiltjo Posthuma <hiltjo_AT_codemadness.org>
CommitDate: Sat Jan 28 13:34:43 2023 +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 (in
        theory interrupted).
    
    POSIX reference:
    "Consequences of Process Termination":
    https://pubs.opengroup.org/onlinepubs/9699919799/functions/_Exit.html#tag_16_01_03_01

diff --git a/dwm.c b/dwm.c
index 03baf42..c2bd871 100644
--- a/dwm.c
+++ b/dwm.c
_AT_@ -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);
_AT_@ -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);
_AT_@ -1638,14 +1644,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)
 {
Received on Sat Jan 28 2023 - 13:34:55 CET

This archive was generated by hypermail 2.3.0 : Sat Jan 28 2023 - 13:36:32 CET