Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris

eval problem

by muad33b (Acolyte)
on Jan 09, 2007 at 05:11 UTC ( [id://593665]=perlquestion: print w/replies, xml ) Need Help??

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

The following code snippet does not time out:
Use Net:SSH2; <snip> $ssh2 = Net::SSH2->new(); <snip> $ssh2->connect($host,$port); <snip> $ssh2->auth_password($os_user,$os_pass); <snip> eval { local $SIG{ALRM} = sub { die "alarm\n"; }; alarm (10); $ssh2->scp_get($remote, $local); alarm (0); };
However, the following works just fine:
eval { local $SIG{ALRM} = sub { die "alarm\n"; }; alarm (10); $buf = <>; alarm (0); }; print "Timed out.\n" if ($@);
I've googled around and seen some reference to a change in perl's eval handling in 5.8.x, as well as some reference to eval failing to timeout blocks of code involving network copys, etc... Any ideas what I have to do to get eval to do it's job here, and time out? Thanks...

Replies are listed 'Best First'.
Re: eval problem
by ikegami (Patriarch) on Jan 09, 2007 at 07:39 UTC

    In Perl, signals no longer interrupt opcodes, except for Perl IO operations. Perl checks if a signal was received between executing opcodes. Net:SSH2 is a wrapper for C library libssh2. libssh2 doesn't know anything about Perl. All the IO is done using C IO, not Perl IO, so alarm will not interrupt Net::SSH2 while it waits for libssh2 to return data.

    The reason for this change (and how to switch to the dangerous old system) is documented in Deferred Signals in perlipc.

Re: eval problem
by diotalevi (Canon) on Jan 09, 2007 at 07:17 UTC

    Set the environment variable PERL_SIGNALS to "unsafe" to reenable the old behaviour. See perlipc for the scoop.

    ⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

Re: eval problem
by ysth (Canon) on Jan 09, 2007 at 07:58 UTC
      Ok, so after some more RTFM (thanks!) I ended up trying this option, as it seemed best, however, now when I try to implement Sys::SigAction's "timeout_call" - which gives the following example:
      use Sys::SigAction qw( timeout_call ); if ( timeout_call( 5 ,sub { $retval = DoSomething( @args ); } ) { print "DoSomething() timed out\n" ; }
      And I implemented this as, e.g.:
      177 eval { 178 if ( timeout_call( 10, sub { $ret = system($mnt_cmd) +; } ) 179 { 180 logit ("Couldn't get to $smbdest, and couldn' +t mount it running $mnt_cmd"); 181 return 1; 182 }
      I get the following error:
      [support@hydra script]$ ./ syntax error at ./ line 179, near ") {" syntax error at ./ line 186, near "}" Execution of ./ aborted due to compilation errors.
      What am I doing wrong syntactically? I've looged around, and this appears to be kosher?? TIA!

        You have a missing close paren ')', Missing close curly '}' and missing final semicolon ';':

        eval { if ( timeout_call( 10, sub { $ret = system($mnt_cmd); } ) # 1 2 2 ? { logit("Couldn't get to $smbdest, and couldn't mount it running $ +mnt_cmd"); return 1; # ?? missing '}' } ## <<< missing ;

        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.

Log In?

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

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (3)
As of 2024-07-25 06:21 GMT
Find Nodes?
    Voting Booth?

    No recent polls found

    erzuuli‥ 🛈The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.