From owner-freebsd-hackers@FreeBSD.ORG Sat May 31 12:46:32 2003 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 7C77B37B401 for ; Sat, 31 May 2003 12:46:32 -0700 (PDT) Received: from mta6.snfc21.pbi.net (mta6.snfc21.pbi.net [206.13.28.240]) by mx1.FreeBSD.org (Postfix) with ESMTP id 0502043F85 for ; Sat, 31 May 2003 12:46:32 -0700 (PDT) (envelope-from mbsd@pacbell.net) Received: from atlas ([64.165.199.230]) by mta6.snfc21.pbi.net (iPlanet Messaging Server 5.1 HotFix 1.6 (built Oct 18 2002)) with ESMTP id <0HFR00K8RO9J3W@mta6.snfc21.pbi.net> for hackers@freebsd.org; Sat, 31 May 2003 12:46:31 -0700 (PDT) Date: Sat, 31 May 2003 12:46:31 -0700 (PDT) From: =?ISO-8859-1?Q?Mikko_Ty=F6l=E4j=E4rvi?= In-reply-to: <20030530213533.E229-100000@mammoth.eat.frenchfries.net> X-X-Sender: mikko@atlas.home To: Paul Herman Message-id: <20030531122701.H326@atlas.home> MIME-version: 1.0 Content-type: TEXT/PLAIN; charset=US-ASCII Content-transfer-encoding: 7BIT References: <20030530213533.E229-100000@mammoth.eat.frenchfries.net> cc: hackers@freebsd.org Subject: Re: Proper behaviour for wait()? X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 31 May 2003 19:46:32 -0000 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 > #include > #include > #include > #include > > 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" >