Messages in this thread | | | Subject | Re: More SIGCHLD musings | Date | Tue, 25 Jun 1996 16:18:03 +0200 | From | Michiel Boland <> |
| |
More news. Thanks to all who replied.
When a child dies, SIGCHLD is generated, and the parent process is woken up. That makes sense.
However, judging from line 671 in kernel/exit.c, when the parent calls wait4(), the SIGCHLD is discarded!
To me, that is just simply wrong. The signal might be blocked, and it should be delivered when we unblock it, which is exactly what happens on the non-Linux systems.
A trace on SunOS shows that SIGCHLD is delivered right after the final call to sigprocmask(). So SunOS is *not* unblocking the signal when we call wait(), contrary to what has been suggested. Ditto for Solaris.
I have received a report (hi Harald :) that SIGCHLD is also delivered on AIX 3.2.5, AIX 4.1.4, Digital Unix 3.2 and HP/UX 9.something. So Linux is clearly in the minority here.
Blocking SIGCHLD is perfectly legal, e.g. most implementations of system() apparently do this.
For example, try the following program. On a sane system it should print `Number of children = 1'. On Linux however, it prints `Number of children = 0'. This is wrong, and should be fixed. (By not discarding SIGCHLD when wait4() is called.)
-------------------------------- #include <stdio.h> #include <errno.h> #include <sys/types.h> #include <sys/wait.h> #include <signal.h> #include <unistd.h> #include <stdlib.h>
volatile int numchildren = 0;
static void sigchld() { int pid; int saved_errno = errno;
while ((pid = waitpid(-1, 0, WNOHANG)) != 0) if (pid == -1) { if (errno != EINTR) break; } else ++numchildren; errno = saved_errno; }
int main(void) { struct sigaction act;
act.sa_handler = sigchld; sigemptyset(&act.sa_mask); act.sa_flags = 0; sigaction(SIGCHLD, &act, 0);
switch(fork()) { case -1: perror("fork"); return 1; case 0: sleep(5); _exit(0); break; default: system("sleep 10"); break; }
printf("Number of children = %d\n", numchildren); return 0; }
-- Michiel Boland <boland@sci.kun.nl> University of Nijmegen The Netherlands
| |