Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

perl alarms not working as expected

by kavkazi (Initiate)
on Oct 15, 2012 at 20:53 UTC ( #999179=perlquestion: print w/ replies, xml ) Need Help??
kavkazi has asked for the wisdom of the Perl Monks concerning the following question:

I have a simple perl script that calls a shell script which for whatever reason "hangs". I want to simply force a time out after 20 seconds. I did a lot of research and was brought to perl Alarms. It works when I test with sleep(), but when running the shell script the alarm doesn't kick in. Can someone please help???? Here is my code. Thanks in Advance.

#!/bin/perl use strict; use warnings; use CGI; my $q = new CGI; print $q->header; eval { local %SIG; $SIG{ALRM}= sub{ die "timeout reached, after 20 seconds!\n"; }; alarm 20; #sleep (60); system("/opt/bea/domain/fsa/scripts/start.sh"); alarm 0; }; alarm 0; if($@) { print "Error: $@\n"; } exit(0);

Comment on perl alarms not working as expected
Download Code
Re: perl alarms not working as expected
by betterworld (Deacon) on Oct 15, 2012 at 21:23 UTC

    Well, it works for me when I run it in the shell. However I see that you seem to be running it as a CGI script. The web server is probably waiting for that shell script to finish, because the shell script still has an open file handle to your standard output.

    You should try killing the other script from your signal handler.

      That's exactly what's happening. Can you please tell me how do I kill the other script from the signal handler. What is a signal handler? Please provide the code as I am a newbie :)

        The signal handler is that sub{} that you stored in $SIG{ALRM}.

        To kill the other script, you'd have to get its pid. Unfortunately I don't know any way to this without any ugly hacks. Maybe someone else does.

        So for instance, you can use this temporary file handle hack:

        #!/usr/bin/perl use strict; use warnings; use CGI; use File::Temp; my $q = new CGI; print $q->header; my $tmp = File::Temp->new(UNLINK => 0); my $tmpnam = $tmp->filename; eval { local %SIG; $SIG{ALRM}= sub{ $tmp->close; system("fuser", "-sk", "-TERM", $tmpnam); unlink $tmpnam; die "timeout reached, after 20 seconds!\n"; }; alarm 3; #sleep (60); system("sleep 10 3>$tmpnam"); alarm 0; }; alarm 0; if($@) { print "Error: $@\n"; } exit(0);

        This requires the "fuser" command, which is shipped with most Linux distros.

        If this does not make the other script die, then leave out the "-TERM".

        I replaced the name of your shell script with "sleep 10", otherwise I can't test it. I also replaced 20 with 3 because I did not want to wait 20 seconds.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://999179]
Approved by betterworld
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (5)
As of 2014-07-25 04:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (167 votes), past polls