bayruds has asked for the wisdom of the Perl Monks concerning the following question:

I am trying to get the exit status of the child process.
If the Child exitted abruptly, then the parent must exit too
Here is a sample code:
$SIG{CHLD} =\&reaper; my ($pid, $child_pid); if ($pid = fork) { print "[In Parent] After Fork\n"; # $SIG{CHLD} =\&reaper; } else { die "Unable to Fork: $!\n" unless(defined $pid); if ($child_pid = fork) { print "[In Child-Parent]\n"; my $cmd = ` <COMMAND! GOES HERE>`; if ($? eq 0) { print "@err\n"; print "[In Child-parent] Exitting\n"; exit(1); } # $SIG{CHLD} =\&reaper_sub; } else { print "[In Child-Child]\n"; my $cmd2 = `<COMMAND2 GOES HERE>`; if ($? eq 0) { print "Error in [Child]: Exitting\n"; exit(1); } } #End of child-child print "[In Child] End of Child\n"; } #End of Child
How do I ensure that the parent quits if its child/grand children exit.

update (broquaint): added formatting + <code> tags

Replies are listed 'Best First'.
Re: Perl IPC: Checking Exit Status of Child Process
by perlplexer (Hermit) on May 18, 2003 at 23:57 UTC
    You could waitpid() in parent and then check the return value stored in $?
    my $pid = fork(); die "Can't fork() : $!\n" unless defined $pid; if ($pid){ if (waitpid($pid, 0) > 0); my ($rc, $sig, $core) = ($? >> 8, $? & 127, $? & 128); if ($core){ print "$pid dumped core\n"; }elsif($sig == 9){ print "$pid was murdered!\n"; }else{ print "$pid returned $rc"; print ($sig?" after receiving signal $sig":"\n"); } }else{ print "$pid... um... disappeared...\n"; } }else{ unless (run_code()){ exit 1; } exit 0; }
    --perlplexer
      Sorry for necroposting, just pointing out that if (waitpid($pid, 0) > 0); should be: if (waitpid($pid, 0) > 0){

      Here is the same code, with an additional timeout option from the parent:

      #!/usr/bin/perl use strict; use warnings; my $timeout = 10; my $parent_pid = $$; my $child_pid = fork(); die "Can't fork() : $!\n" unless defined $child_pid; if ($child_pid){ # parent eval { local $SIG{ALRM} = sub { die "timed-out\n" }; alarm $timeout; if (waitpid($child_pid, 0) > 0){ my ($rc, $sig, $core) = ($? >> 8, $? & 127, $? & 128); if ($core){ print "$child_pid dumped core\n"; }elsif($sig == 9){ print "$child_pid was murdered!\n"; }else{ print "$child_pid returned $rc"; print ($sig?" after receiving signal $sig":"\n"); } }else{ print "$child_pid... um... disappeared...\n"; } alarm 0; }; if($@ eq "timed-out\n"){ print "$child_pid... parent got bored waiting for it...\n"; }else{ print "$child_pid ran SUCCESSFULLY!!!\n"; }; }else{ # child unless (run_code()){ exit 1; } exit 0; }

      Thanks for replying back. I had a question though:

      How do I create a fan of n children out of the same parent.

      That is, 1 parent with n children.

      Thanks a lot for replying back.
        Just call fork() as many times as you need...
        # Create 10 child processes for (1..10){ my $pid = fork(); last unless defined $pid; # Too many processes already? unless($pid){ # Child code here exit; } } # wait() for kids while(($pid = wait()) > 0){ # Check $? here }
        --perlplexer
        Here's an example of one parent forking multiple children.

        The Perl Cookbook has great examples about this topic.

        You'd really want to make sure you're looping around the fork() and keeping track of the number of living children you have at the moment. Other than that and IPC, it's mostly just everyday programming.

        Christopher E. Stith
        use coffee;
Re: Perl IPC: Checking Exit Status of Child Process
by pzbagel (Chaplain) on May 18, 2003 at 23:09 UTC
    Please use <code> </code> tags to enclose your code and preview, preview, preview your postings before submitting! Especially when posting new SOPW questions as you can't edit them once you post them.

    Cheers