If Ethereal performs a capture in a separate process under Red Hat 9,
when the capture finishes the kernel issues the message:
> application bug: ethereal(<pid>) has SIGCHLD set to SIG_IGN but calls
> wait(). (see the NOTES section of 'man 2 wait'). Workaround
> activated.
The Red Hat release notes at
http://www.redhat.com/docs/manuals/linux/RHL-9-Manual/release-notes/x86/
say:
> This message (which is displayed on the system console and/or in the
> system log files) indicates that the application is not completely
> standards compliant with respect to its handling of child processes.
> If you see this message, you should alert the application's
> developers.
The NOTES section of wait(2) says:
> The Single Unix Specification describes a flag SA_NOCLDWAIT (not sup-
> ported under Linux) such that if either this flag is set, or the
> action for SIGCHLD is set to SIG_IGN then children that exit do not
> become zombies and a call to wait() or waitpid() will block until all
> children have exited, and then fail with errno set to ECHILD.
>
> The original POSIX standard left the behaviour of setting SIGCHLD to
> SIG_IGN unspecified. Later standards, including SUSv2 and POSIX
> 1003.1-2001 specify the behaviour just described as an XSI-compliance
> option. Linux does not conform to the second of the two points just
> described: if a wait() or waitpid() call is made while SIGCHLD is
> being ignored, the call behaves just as though SIGCHLD were not being
> igored, that is, the call blocks until the next child terminates and
> then returns the PID and status of that child.
Since Ethereal calls wait() (in capture.c:wait_for_child) very soon
after the child process finishes, I think the best thing to do is not
to call signal() under a POSIX-compliant system. The attached patch
works under Red Hat 9, Mandrake 7.0 (2.2 kernel) and Solaris 7.
Graeme Hewson
--- capture.c.orig Thu Jan 23 09:04:54 2003
+++ capture.c Wed Apr 23 17:32:25 2003
@@ -449,7 +449,9 @@
/* Keep a copy for later evaluation by _cwait() */
child_process = fork_child;
#else
+#ifndef _POSIX_SOURCE
signal(SIGCHLD, SIG_IGN);
+#endif
if (pipe(sync_pipe) < 0) {
/* Couldn't create the pipe between parent and child. */
error = errno;