Date: Sat, 31 May 2003 12:46:31 -0700 (PDT) From: =?ISO-8859-1?Q?Mikko_Ty=F6l=E4j=E4rvi?= <mbsd@pacbell.net> To: Paul Herman <pherman@frenchfries.net> Cc: hackers@freebsd.org Subject: Re: Proper behaviour for wait()? Message-ID: <20030531122701.H326@atlas.home> In-Reply-To: <20030530213533.E229-100000@mammoth.eat.frenchfries.net> References: <20030530213533.E229-100000@mammoth.eat.frenchfries.net>
next in thread | previous in thread | raw e-mail | index | archive | help
On Fri, 30 May 2003, Paul Herman wrote: > Just curious, > > anyone know what the "proper" behavior for wait() is when SIGCHLD > is ignored? Is it simply undefined? Don't see anything mentioned > in the wait(2) manpage one way or tother, and other OSes don't seem > to agree much. If you ignore SIGCHLD using sigaction(), and set the SA_NOCLDWAIT flag, the child will automatically go away. On BSD derived systems, if you ignore SIGCHLD using signal(3), and depend on the above behavior, you tend to end up with a zombie. SUSv3, says (under "sigaction"): "SA_NOCLDWAIT [XSI] If set, and sig equals SIGCHLD, child processes of the calling processes shall not be transformed into zombie processes when they terminate. If the calling process subsequently waits for its children, and the process has no unwaited-for children that were transformed into zombie processes, it shall block until all of its children terminate, and wait(), waitid(), and waitpid() shall fail and set errno to [ECHILD]. Otherwise, terminating child processes shall be transformed into zombie processes, unless SIGCHLD is set to SIG_IGN." And in the "Signal Concepts" section (as part of an XSI extension): "If the action for the SIGCHLD signal is set to SIG_IGN, child processes of the calling processes shall not be transformed into zombie processes when they terminate. If the calling process subsequently waits for its children, and the process has no unwaited-for children that were transformed into zombie processes, it shall block until all of its children terminate, and wait(), waitid(), and waitpid() shall fail and set errno to [ECHILD]." This part does not mention the method of setting the handler to SIG_IGN, so signal(3) should be able to get rid of zombies. That is not true on FreeBSD. The only way (except "for historical reasons") the above standards excerpts would make sense to me, is if setting the SIGCHLD handler to SIG_IGN always makes the system reap child processes, and if using sigaction() with the SA_NOCLDWAIT flag would allow you to get signal delivery together with automatic zombie reaping (i.e. handler gets called, but wait() will fail). But I've never seen that behavior described anyware, so that is probably not the intent. Also, it does not work that way on FreeBSD: once I've set the SA_NOCHLDWAIT flag, I don't get any SIGCGHLD signals. And now over to someone who actually knows what they're talking about... :) $.02, /Mikko > > -Paul. > > bash$ cat wait.c > #include <sys/types.h> > #include <sys/wait.h> > #include <signal.h> > #include <stdio.h> > #include <unistd.h> > > int main() { > int status; > pid_t pid = fork(); > > if (!pid) { sleep(1); _exit(0); } > > signal(SIGCHLD, SIG_IGN); > printf("waitpid() = %d\n", waitpid(pid, &status, 0)); > signal(SIGCHLD, SIG_DFL); > return 0; > } > bash$ cc wait.c > > [FreeBSD 4.8] > bash$ ./a.out > waitpid() = 7553 > bash$ > > [Linux 2.4.21] > bash$ ./a.out > waitpid() = 24536 > bash$ > > [Darwin 6.6] > bash$ ./a.out > waitpid() = -1 > bash$ > > [Solaris 8] > bash$ ./a.out > waitpid() = -1 > bash$ > > [OpenBSD 3.3] > bash$ ./a.out > ...just hangs... > > _______________________________________________ > freebsd-hackers@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-hackers > To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@freebsd.org" >
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030531122701.H326>