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

Greetings monks and other religious dignateries,

I'm working on a .pm module that needs to execute code and had the following problem. First, I use

$pid = open (H, "$command |");

to get the results and use $? to get the return code.

The problem is, I set SIG{CHLD} = 'IGNORE' in order for the process to not zombie. If I don't set SIGCHLD, then the return codes come back grandly and all I have to do is $? >> 8. But with SIGCHLD set, I get "-1" back always if the child exits cleanly.

My question is, is there a way to get that executed child's return code with SIGCHLD set to IGNORE???

Thanks in advance!

Replies are listed 'Best First'.
(sacked) Re: SIGCHLD and return codes
by sacked (Hermit) on Nov 16, 2001 at 22:14 UTC
    From perlipc:
    On most Unix platforms, the `CHLD' (sometimes also known as `CLD') signal has special behavior with respect to a value of `'IGNORE''. Setting `$SIG{CHLD}' to `'IGNORE'' on such a platform has the effect of not creating zombie processes when the parent process fails to `wait()' on its child processes (i.e. child processes are automatically reaped). Calling `wait()' with `$SIG{CHLD}' set to `'IGNORE'' usually returns `-1' on such platforms.
    I would install a signal handler that calls wait to reap the child process and get its exit status, as in this excerpt, adapted from perlipc:
    sub REAPER { $waitedpid = wait; # now status is in $? print "reaped pid $waitedpid, exited with status ", $? >> 8, "\n"; # loathe sysV: it makes us not only reinstate # the handler, but place it after the wait $SIG{CHLD} = \&REAPER; } $SIG{CHLD} = \&REAPER;


    --sacked
      Looks like that works but how do I return $? from the handler?
        Use a hash:
        # once again, adapted from perlipc use vars qw( %status ); # our, if you prefer sub REAPER { $waitedpid = wait; # now status is in $? $status{ $waitedpid } = $? >> 8; # loathe sysV: it makes us not only reinstate # the handler, but place it after the wait $SIG{CHLD} = \&REAPER; } $SIG{CHLD} = \&REAPER; while ( my ($k,$v) = each %status ) { print "pid $k\tstatus $v\n" }

        --sacked