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...
>
> _______________________________________________
> [EMAIL PROTECTED] mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
> To unsubscribe, send any mail to "[EMAIL PROTECTED]"
>
_______________________________________________
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to