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

Hi everyone! So I'm trying to make sure NFS shares are properly mounted by using a small perl script, along side a much larger program. It uses utime(undef,undef,"/pathtoshare") to make sure the path is still accessible. I've tried to wrap the utime function in an alarmed eval without success. It seems alarm doesn't get signaled. Example: - Mount client to NFS share - run test.pl - OK - stop nfs service on server - run test.pl - flop without alarm (waits about 120 seconds) Here is the relevant portion of the code.
print "Evaluating... \n"; eval{ local $SIG{ALRM} = sub { $sys_check_mount{$mount_server} = 0; print "Alarm!"; exit(); }; alarm(5); print "Alarm Set... Trying system commands... \n"; if (-e $mount_server_check_path && utime(undef, undef, "$moun +t_server_check_path/mount_check")){ #print "OK\n"; $sys_check_mount{$mount_server} = 1; }else{ #print "Broken\n"; $sys_check_mount{$mount_server} = 0; push (@mount_server_broken,$mount_server); } alarm(0); print "Reset Alarm... \n"; } }
Ideally the script shouldn't exit, but rather return something from the eval but I'm not sure how to return from the local $SIG{ALRM}... Any help would be greatly appreciated :)

Replies are listed 'Best First'.
Re: Alarm and blocking I/O.
by BrowserUk (Patriarch) on May 29, 2010 at 17:36 UTC
      Hmm I am using perl 5.10.0, so perlio is used by default. I also tried setting the signal handler with use POSIX qw(SIGALRM);. No luck there either. The alarm eventually gets called but about a minute later, most likely when the NFS operation times out because of its mount options. Any help would be greatly appreciated :)
      It seems replacing the default signal is the cause of the alarm failing to go off. I do not understand why, even this simple replacement causes the alarm to not go off.
      $SIG{ALRM} = sub { die "alarm" };
      Without it, the alarm does fire. Anyone can clarify why this is?

        Sorry, my needs of alarm are relatively simple, which is just as well because as with anything signalish, simple is all you get on Win32.

        I've previously used the environment variable PERL_SIGNALS=unsafe, but recently discovered Perl::Unsafe::Signals which works for me and limits the scope. All I could do was pass on the information, as you're doing things I don't understand on a platform I don't use.


        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.
        Huh... To anyone curious on how it is now working: Not checking for the file's existence before touching it and not touching it with utime.
        if (system(qq~ touch "$mount_server_check_path/mount_check"; ~)){ ...
        Perl :p