#!/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 }