What is the difference between these settings?
$SIG{CHLD} = 'IGNORE'
$SIG{CHLD} = 'DEFAULT'
$SIG{CHLD} = ''
$SIG{CHLD} = undef
According to "Advanced Programming in the UNIX Environment, 2nd edition", figure 10.1 the default value of SIGCHLD is "ignore."
If "ignore" meant "SIG_IGN", then no child would ever be a zombie, and that's not the case.
It doesn't get much more clear from there:
If the process specifically sets its disposition to SIG_IGN, children
of the calling process will not generate zombie processes. Note that
this is different from its default action (SIG_DFL), which from Figure
10.1 is to be ignored. Instead, on termination, the status of these child processes
is discarded.
I'm having a hard time groking what the impact of the various values (or undefined non-value) are. So far, the solution has been to rotate through those choices until I get the desired behavior, and I'd rather understand exactly how each value defines the behavior of the signal.
The behavior: a child process is calling "system" or using backticks which create another child, and the signal would normally be caught by the wrong (parent) handler. Setting a local handler can work, but I don't understand which value is most appropriate if I want the signal from the grand-child to do nothing.
Could someone please illuminate me?
UPDATE:
Based on ikegami's feedback, I did some specific testing. The behavior is, at least partially, platform specific.
Consider the following fragment:
$SIG{CHLD} = sub {
while( ( my $child = waitpid( -1, &WNOHANG ) ) > 0 ) {
print "SIGNAL CHLD $child
";
}
};
my $pid = fork();
if( ! $pid ) {
system( 'echo Grandchild PID = $$' );
sleep 2;
exit;
}
print "Child PID = $pid
";
sleep 5;
Perl 5.8.6 on Solaris 10 will display "SIGNAL CHLD" messages for the PID of the system() call. Doing anything, even as trivial as
local $SIG{CHLD};
in the child will suppress those messages.
On every other flavor I tried, the reaper never sees the child.
See Question&Answers more detail:
os