#!/usr/bin/perl
#
use POSIX qw(:signal_h :sys_wait_h);
$SIG{CHLD} = \&handler;
# hold SIGCHLD here
my $sigset = POSIX::SigSet->new;
my $blockset = POSIX::SigSet->new(SIGCHLD);
sigprocmask(SIG_BLOCK, $blockset, $sigset) || die "ERROR: could not block SIGCHLD: $!\n";
my $pid = fork();
if(! defined($pid)) { # failed fork()
die "ERROR: fork() failed: $!\n";
} elsif($pid == 0) { # child
# do stuff
exit(0);
}
# parent
print STDERR "DEBUG: in parent after first fork(), pid == $pid\n" if $debug;
# release SIGCHLD here
sigprocmask(SIG_SETMASK, $sigset) ||
die "ERROR: could not restore SIGCHLD signal: $!\n";
exit 0;
sub handler {
my $signame = shift;
my $pid;
print STDERR "DEBUG: received SIG$signame\n" if $debug;
if($signame eq "CHLD") {
while(($pid = waitpid(-1, &WNOHANG)) > 0) {
# do cleanup stuff
}
} # might want to handle sigTERM and shutdown children here
# don't forget to waitpid() on any children that you kill
}