Hi, > > void > > sigchld(int unused) > > { > > + if (signal(SIGCHLD, sigchld) == SIG_ERR) > > + die("can't install SIGCHLD handler:"); > > while (0 < waitpid(-1, NULL, WNOHANG)); > > } > > Calling `die` inside a signhandler is still an issue and can produce > bad behavior (I have seen a couple software which randomly freeze due to > calling signal unsafe functions inside a sighandler). > > If `sigaction` can fix the issue with `signal` then it's probably best > to use that. Otherwise replacing `die` with `write` and `_exit` is also > a viable solution as shown in: > https://lists.suckless.org/hackers/2207/18405.html
Indeed. in both things, we should not use die() in a signal handler and using signal to reinstall the handler opens a race condition window where we can lose sigchld signals and generate zombies process. I personally think that using a sigchld handler to collect zomby process is a bad idea. I think it is POSIX that if you use an explicit signal call to ignore SIGCHLD then the system reap them automatically without explicits wait [1]. I could not find this specification in the POSIX standard, but [2] says: POSIX.1-2001 specifies that if the disposition of SIGCHLD is set to SIG_IGN or the SA_NOCLDWAIT flag is set for SIGCHLD (see sigaction(2)), then children that terminate do not become zombies and a call to wait() or waitpid() will block until all children have terminated, and then fail with errno set to ECHILD. So it seems it is standard since long time ago. [1] https://copyprogramming.com/howto/what-is-the-use-of-ignoring-sigchld-signal-with-sigaction-2 [2] https://corp.sonic.net/ceo/perl-sigchld-ignore-system-and-you/ Roberto Vargas,