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

I am trying to catch the exit code of a shell script executed by my script. I used a friends code to 'daemonize' and then mask for signals with the 'POSIX' module.

The problem that I now have is once the following piece of code is run '$?' is always '-1' regardless of the exit from the last command run in (``)'s.

I have read that once a new sigchld is installed the $? cannot be trusted.

My question, is there any way to retain the '$?' or like behavior after messing with sigchld?



# START_SUB sub setSigDisposition() { my ($sighandler,$snum); # # The set of signals to mask # my $sigset = POSIX::SigSet->new; $sigset->fillset(); # # Don't mask these signals because wouldn't want to continue # if one these sent, even in critical section(s). # $sigset->delset( &POSIX::SIGILL ); $sigset->delset( &POSIX::SIGSEGV ); $sigset->delset( &POSIX::SIGFPE ); $sigset->delset( &POSIX::SIGINT ); foreach $snum( split(' ', $Config{sig_num}) ){ $SIG{CHLD} = 'IGNORE'; if( $snum == &POSIX::SIGILL || $snum == &POSIX::SIGSEGV || $snum = += &POSIX::SIGFPE || $snum == &POSIX::SIGINT ){ $sighandler = "main::death"; } # elsif( $snum == &POSIX::SIGTERM ){ # $sighandler = "main::shutdown"; # } else{ $sighandler = "main::reaper"; } # Set signal disposition ... POSIX::sigaction( $snum, POSIX::SigAction->new( $sighandler, POSIX::SigSet->new, &POSIX::SA_NOCLDSTOP ), POSIX::SigAction->new( $sighandler, POSIX::SigSet->new, &POSIX::SA_NOCLDSTOP ) ); } return $sigset; } # END_SUB
Thanks! -Bryan

Replies are listed 'Best First'.
Re: sigchild and $?
by bluto (Curate) on Sep 30, 2003 at 22:29 UTC
    Is there a reason you don't use something like waitpid()?

    FWIW, I've had -1 returned for $? in the past when I've set up SIGCHLD and then used perl's builtin fork/exec stuff (i.e. backticks, system(), qx()). I'm assuming perl (or the C library) sets up it's own waitpid() and/or sighandler for these expecting to reap the process and then I come along and screw things up with my SIGCHLD handler. Maybe someone with more wisdom can figure out how to do this right, but I tend to avoid setting up SIGCHLD and generally find that I don't need to.

    bluto

      I would love to say I had a reason for not using waitpid(), but that might be a stretch. I will play around with that a bit. I did find a work around - if interested:
      @ScriptMSG=`/run/some/script;/usr/echo "\$?"`; chomp(@ScriptMSG); $ExitCode=$ScriptMsg[$#ScriptMsg];
      -Bryan
        I wasn't thinking straight -- forget my comment about waitpid() which you would need if you did your own fork/exec. You don't need it with backticks. Basically backticks sets $? so you can check it directly (by using this code ripped from 'perldoc -f system'...
        $exit_value = $? >> 8; $signal_num = $? & 127; $dumped_core = $? & 128;
        bluto