There is a lot of confusion on $SIG{CHLD} in perl. There are three ways to go and they all have side effects. This document is not the answer, but the question - answers still to be discovered.
$SIG{CHLD} undefined
If you now do a fork directly, on unix systems at least, you will end up with Zombie Processes. Processes that sit in the memory space waiting to return their signal to the parent, until the parent is terminated.
This is BAD if you want to use fork.
$SIG{CHLD} = 'ignore'
A handy method for ignoring the return signals but still being there to listen (that is what is all about). No more zombie process.
But now.. you can't get your error from a SYSTEM call.
system("sleep 20");
print "LOCAL = $?\n";
Fails !
local $SIG{CHLD} = undef
It is tempting to think of $SIG{CHLD} like you would $SIG{_DIE_} - which is you can set a local one for a block.
{
local $SIG{CHLD} = undef;
system("sleep 20");
print "LOCAL = $?\n";
}
This seems on the surface ok, but it is very bad - because now you miss signals that happen during your system call. Unlike internals like DIE, CHLD is a one slot unix signal handler.
perlipc example
use POSIX ":sys_wait_h";
sub REAPER {
my $child;
while (($waitedpid = waitpid(-1,WNOHANG)) > 0) {
logmsg "reaped $waitedpid" . ($? ? " with exit $?" : '');
}
$SIG{CHLD} = \&REAPER; # loathe sysV
}
$SIG{CHLD} = \&REAPER;
This example happily catches the output of all the dead children, but what about our system call and return value inside $?
Well that is still a problem. The only real solution I know of is to keep the return values in the reaper and then check those after the system call...
CPAN
The answer is probably in CPAN - somewhere there is a module that does system without depending on the $SIG{CHLD}, but I can't find it?
- Arduino Static Strings (Mon, 09 Aug 2010 00:56:37 GMT)
- Arduino (Sun, 08 Aug 2010 07:30:58 GMT)
- Rainbow House 4 (Sat, 07 Aug 2010 00:07:01 GMT)
