Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

How to force a timeout on a system call?

by Xxaxx (Monk)
on Jun 21, 2001 at 23:37 UTC ( [id://90508]=perlquestion: print w/replies, xml ) Need Help??

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

I have a Perl script called by crontab once a day.
Within this script I make a system call to whois. Such as:
#!/usr/bin/perl -wT use strict; ## [snipped for brevity] my $resultin = `whois $dom`;
Every now and then I'll take a peek at the current processes using "ps -aux" and I'll notice a stuck "whois" running along with a script waiting its output.

I'm sure there is a simple strategy to wrap this system call so that I can either kill it or at least move on.

Any clues would be appreciated.

Claude

Replies are listed 'Best First'.
Re: How to force a timeout on a system call?
by maverick (Curate) on Jun 21, 2001 at 23:56 UTC
    Try this.
    eval { local $SIG{'ALRM'} = sub { die "timed out\n" }; alarm(10); system("sleep 30; echo 'I made it'") && die "system call faile +d\n"; alarm(0); }; if ($@) { if ($@ eq "timed out\n") { print "I timed out\n"; } else { print "something else went boom\n"; } } else { print "I didn't time out\n"; }
    In ten seconds you should get output that reads "I timed out". This is almost exactly the eval timeout out example from the 'perlfunc' perldoc page. I modified it a little to have print statements for what happened where.

    /\/\averick

    Updated:

    bluto is quite right. here is my updated code. This seems to work fine under Linux. The only problem I have with Dominus solution is requiring the external program (you should be able to get it to work in one piece of code IMHO ;) )

    -- first.pl -- #!/usr/bin/perl use strict; my $pid; eval { local $SIG{'ALRM'} = sub { die "timed out\n" }; alarm(10); $pid = fork; if ($pid == 0) { exec("./second.pl"); } else { wait; } alarm(0); }; if ($@) { if ($@ eq "timed out\n") { kill(15,$pid); print "I timed out\n"; } else { print "something else went boom\n"; } } else { print "I didn't time out\n"; } -- second.pl -- #!/usr/bin/perl while(1) { print "alive\n"; sleep(1); }
    This produces this output on my system.
    darkstar:~>./first.pl alive alive alive alive alive alive alive alive alive alive I timed out darkstar:~>
      Much thanks for the update.
      Claude
      It doesn't do that on my system :
      I didn't time out I didn't time out
Re: How to force a timeout on a system call?
by bluto (Curate) on Jun 22, 2001 at 01:19 UTC
Re: How to force a timeout on a system call?
by tarjema (Initiate) on Jun 22, 2001 at 03:26 UTC
    I'd actually eliminate the problem sideways and use Net::XWhois:

    use Net::XWhois; my $whois = new Net::XWhois DOMAIN => $domain;

    Then do whatever you're after on the response. To get the name servers:

       @nservers = $whois->nameservers()

    --tarjema

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (3)
As of 2024-03-28 18:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found