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 readd 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.
---
 dwm.c | 20 ++++++++------------
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/dwm.c b/dwm.c
index b3c43ee..687b6ec 100644
--- a/dwm.c
+++ b/dwm.c
@@ -29,7 +29,6 @@
 #include <string.h>
 #include <unistd.h>
 #include <sys/types.h>
-#include <sys/wait.h>
 #include <X11/cursorfont.h>
 #include <X11/keysym.h>
 #include <X11/Xatom.h>
@@ -205,7 +204,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);
@@ -1539,9 +1537,15 @@ setup(void)
        int i;
        XSetWindowAttributes wa;
        Atom utf8string;
+       const struct sigaction sc = {
+               .sa_handler = SIG_DFL,
+               .sa_flags = SA_RESTART | SA_NOCLDWAIT,
+       };
 
-       /* clean up any zombies immediately */
-       sigchld(0);
+       if (sigaction(SIGCHLD, &sc, NULL)) {
+               perror("sigaction");
+               exit(EXIT_FAILURE);
+       }
 
        /* init screen */
        screen = DefaultScreen(dpy);
@@ -1635,14 +1639,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)
 {
-- 
2.37.1


Reply via email to