LPM: Neat alarm trick
Frank Price
fprice at upended.org
Wed Oct 4 13:06:50 CDT 2000
Hi Lexpm:
I found a neat trick and a related question. First the trick: I have
a script which does rcp system calls. Sometimes the other server is
screwed up and the system call just hangs for a long time. I wanted a
away to time it out after a certain amount of time.
The solution is to use alarm(). Alarm sends an ALRM signal to any
children, which works since system() forks a child. You wrap this in
an eval block, and set a ALRM signal handler. Outside the eval, you
can test for $@ and take action.
Example:
eval {
local $SIG{'ALRM'} = sub {
local $SIG{'TERM'} = 'IGNORE';
kill TERM => -$$;
die 'Caught alarm signal';
};
alarm(10);
print "starting system call ...\n";
system("cp /dev/zero /dev/null");
alarm(0);
};
if ($@) {
if ($@ =~ /Caught alarm signal/) {
die ("system call blocked!!!");
} else { die }
}
Here's the question: since I want to kill the system call if the
alarm goes off, looks like I have to explicitly send it a TERM signal.
That's why the $SIG{'ALRM'} does 'kill TERM => -$$' (this sends a TERM
to everything in the process group). First I ignore TERM for this
process so the script doesn't get killed off. But I really just want
to kil the system() child; however I couldn't find a good way to find
it's PID. Is there a better way?
Thanks,
-Frank.
--
Frank Price | fprice at upended.org | www.upended.org/fprice/
GPG key: www.upended.org/fprice/gpg.asc | E Pluribus Unix
More information about the Lexington-pm
mailing list