Fork in perl but get exit status from a system call in the child process
What I do:
- Make an ajax call to a cgi script.
- Cgi script forks but the parent returns right away with a response msg.
- The child does a system call but needs the exit code and any error messages.
Pseudo-code:
$SIG{CHLD} = ‘IGNORE’; # or waitpid($pid,0开发者_运维技巧) in the parent process
$pid = fork();
if($pid == 0)
{
close STDOUT; # So that the parent sends the response to the client right away.
@errorMsgs = qx(tar up big directories over 50G…); # This can go on for a few minutes.
if($? ==0) { Send a ‘success’ email } # Is always false ($? == -1)
else { Send a ‘failure’ email }
}
elsif($pid){ sendResponse; waitpid($pid,0) if $SIG{CHLD} != 'IGNORE'; exit;}
My problem:
Trouble getting a correct return code ($?) and any error messages from qx() as it is set to -1 due to ($SIG{CHLD} = 'IGNORE'). If I remove $SIG{CHLD} statement, the client web page does not receive a response msg from the parent until after the child is reaped.
You're getting a -1 because you're setting $SIG{CHLD}
to IGNORE
. By doing that, you're killing qx
's ability to capture the exit code of tar
... it will die without notifying the parent (your child process).
It's simple enough to test out:
perl -e '$SIG{CHLD} = "IGNORE"; system("ps"); print "Finished with $?\n";
This gives -1.
perl -e 'system("ps"); print "Finished with $?\n";
This gives 0.
If you really need the $SIG{CHLD} = 'IGNORE'
, then just $SIG{CHLD} = 'DEFAULT'
before your qx
call.
Also, make sure you're using the full path to tar
(e.g. /bin/tar
) just in case you don't have /bin
in your path, and it's failing to execute. However, I'm assuming that's OK since you didn't say anything about your tar file not being created.
Well, if you reset $SIG{CHLD}
to undef
in the child section (i.e. after $pid == 0
), it won't affect the parent process, right?
精彩评论