I have a script for downloading bunch of data from some servers.
For each server I start ssh via IPC::Open2 like this:
my $pid = open2($rfh, $wfh, "ssh $opts $hostspec $cmd");
Then I download all data in loop via select() (4 arg version). When some ssh dies, I need to modify some program structures (same applies for INT/TERM signal). So I decided I will do it right after select() via self-pipe trick (described in NOTES in linux select(2) manpage).
### Self-pipe init. pipe(SIGRD, SIGWR); # Make SIGRD non-blocking. vec($rin, fileno SIGRD, 1) = 1;
CHLD handler does just this (INT/TERM handlers sets $term variable in addition):
my $byte = 1; syswrite(SIGWR, $byte, 1);
This is top of the main while loop.
my $nfound = select($rout = $rin, $wout = $win, undef, undef); # Check $nfound for errors. if(vec($rout, fileno SIGRD, 1)) { my $byte; while(sysread(SIGRD, $byte, 1)) { if($term) { # INT/TERM arrived, kill sshs, modify some data, ... $term = 0; } else { # CHLD arrived, do waitpid(), modify some data, ... } }
After I do waitpid() I need to check $? if ssh exited with error. However in description of $? in perlvar is stated: If you have installed a signal handler for "SIGCHLD", the value of $? will usually be wrong outside that handler. My question is why it will be wrong when I will use it just after waitpid()? Thank you.
In reply to $? outside SIGCHLD handler by kenshin
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |