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;
