>>> What I observe is that a process that explicitly ignores SIGCHLD >>> (SIG_IGN), then forks a child which exits, when wait()ing for the >>> child, gets ECHILD (i.e., wait returns -1 and errno is ECHILD). >> And the ECHILD return is delayed until all children have terminated > Huh, I hadn't realized (or expected) that. So I guess it's wrong to > implement this by just detaching the child up front...?
I would say so, especially since that would mean the child's parent is no longer the process that forked it (which could break other use cases). > I'm guessing also then that it's the signal setting when the child > exits that matters; I had always thought it was the signal setting > when the child was forked. Oh, interesting point. Yes, in a test I just did on NetBSD 5.2, it is the signal setting when the child exits that matters - program below. (I tried it on 1.4T, but that's old enough it doesn't have the magic SIG_IGN semantic for SIGCHLD, not even when set before the child is forked.) I don't know whether POSIX specifies that or not. #include <stdio.h> #include <errno.h> #include <signal.h> #include <stdlib.h> #include <unistd.h> #include <strings.h> #include <sys/wait.h> int main(void); int main(void) { pid_t kid; pid_t dead; fflush(0); kid = fork(); if (kid == 0) { printf("child sleeping\n"); sleep(5); printf("child exiting\n"); exit(0); } printf("child %d forked\n",(int)kid); printf("parent sleeping\n"); sleep(1); printf("parent ignoring SIGCHLD\n"); signal(SIGCHLD,SIG_IGN); while (1) { printf("parent waiting\n"); dead = wait(0); if (dead < 0) { if (errno == ECHILD) { printf("wait error: %s\n",strerror(ECHILD)); break; } else { printf("wait error: %s\n",strerror(errno)); } } else { printf("child %d reaped\n",dead); } } printf("parent exiting\n"); return(0); } > "signals are a semantic cesspool" That they are. /~\ The ASCII Mouse \ / Ribbon Campaign X Against HTML mo...@rodents-montreal.org / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B