I am trying to write a socket server that forks for every connection. I have been successful except for one small caveat: my child processes use Net:OpenSSH->capture2() which requires that $SIG{CHLD} not be set to IGNORE or to a custom signal handler. How can I reap my children without setting the signal handler or slowing down the parent process with wait or waitpid?
Here is my server code:
my $sock = new IO::Socket::INET (
LocalHost => 'localhost',
LocalPort => '1337',
Proto => 'tcp',
Listen => SOMAXCONN,
Reuse => 1,
);
die "Could not create socket: $!\n" unless $sock;
my $new_client, $pid;
while($new_client = $sock->accept()){
next if $pid = fork;
die "fork: $!" unless defined $pid;
close $sock;
while(<$new_client> ) {
#do Net::OpenSSH stuff
}
exit;
} continue {
close $new_client;
}
If I use the code as shown above, everything works but I end up with a bunch of zombie processes. If I add
local $SIG{CHLD} = 'IGNORE';
the zombies are reaped, but the Net::OpenSSH->capture2() method call has a messed up return code. I'm presuming my signal handler is interfering with some custom handler that Net::OpenSSH needs to work properly?
waitpid
outside of aSIGCHLD
handler is also effective at getting rid of zombies – Malapropos