On 4/9/07, Brian Candler <[EMAIL PROTECTED]> wrote: ...
Suppose child 1 dies, causing a SIGCHLD to be pending, and then a second child dies, before sigsuspend() unblocks the signal. sigsuspend returns, and one child is reaped. Next time around the loop, will the second child be reaped? If so, why?
Hmm, nice catch. In theory, sigsuspend() should wake up immediately the second time through, as SIGCHLD should be pending as long as there's a child in the exited-but-not-yet-reaped state. That is, the first waitpid() shouldn't cancel the pending state because there's another child process ready to be reaped. To quote the SUS pages: http://www.opengroup.org/onlinepubs/009695399/functions/waitpid.html Otherwise, if SIGCHLD is blocked, if wait() or waitpid() return because the status of a child process is available, any pending SIGCHLD signal shall be cleared unless the status of another child process is available. Note that last line. However, OpenBSD 4.0 doesn't actually comply with that: after waitpid() there will be no SIGCHLD pending, even if there are additional children to reap. So, if you're going to have multiple children, you need to call waitpid(-1, &ret, WNOHANG) until it returns zero or -1/ECHILD before you loop back to sigsuspend() again. That way you can be sure that you haven't lost any SIGCHLDs before you reenter the sigsuspend(). I've actually confirmed that that loop does work as expected, unlike the original example which only works with one child. Philip Guenther