Re: [hackers] [dwm][PATCH] Fix signal race condition

2017-01-24 Thread Roberto E . Vargas Caballero
> If the signal(2) call within the signal handler fails, die() is called
> which in turn is not signal-safe. Therefore, the change to sigaction
> makes dwm() more portable among POSIX systems and fixes a signal race
> condition.

You are right with the original race condition, but I think your solution
has also a race condition, because you are not blocking signals while
you are in the handler. From my point of view what should be done here
is simply:

signal(SIGCHLD, SIG_IGN);

It will avoid zombie children.

Regards,




[hackers] [dwm][PATCH] Fix signal race condition

2017-01-22 Thread Tobias Stoeckmann
By switching to sigaction(2) instead of signal(2), the signal handler
for child processes can be registered only once, instead of every time
the signal was received.

If the signal(2) call within the signal handler fails, die() is called
which in turn is not signal-safe. Therefore, the change to sigaction
makes dwm() more portable among POSIX systems and fixes a signal race
condition.

In order to use sigaction(2), the target system must be compatible to
POSIX.1-2001 or SVr4, which is basically already given due to compile
flags (e.g. BSD_SOURCE).
---
 dwm.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/dwm.c b/dwm.c
index d27cb67..f593007 100644
--- a/dwm.c
+++ b/dwm.c
@@ -1537,9 +1537,14 @@ setup(void)
int i;
XSetWindowAttributes wa;
Atom utf8string;
+   struct sigaction sa;
 
/* clean up any zombies immediately */
-   sigchld(0);
+   sa.sa_handler = sigchld;
+   sa.sa_flags = SA_RESTART;
+   sigemptyset(_mask);
+   if (sigaction(SIGCHLD, , NULL))
+   die("can't install SIGCHLD handler:");
 
/* init screen */
screen = DefaultScreen(dpy);
@@ -1635,8 +1640,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));
 }
 
-- 
2.11.0