How to use SIG{ALRM} in Perl for time out?

Hi,
I have a Perl code and I want to use SIG{ALRM} to time out the process if it hangs. Also, I want to continue the rest of the process if it fails.

I can;t use CPAN TIME::OUT module due to limitations.

Does the code below look ok? If not can you please give me suggestions? If possible with the code itself.

Here is the sudo code:

SOME CODE

    eval {
          local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required
          alarm 60;


         MYCODE. It has a system call in it. And I assume system call may hang or fail.

         alarm 0;
    }; #eval

    if ($@) {
            die unless $@ eq "alarm\n";   # propagate unexpected errors timed out
         CustomSendMail('help@domain.com', 'aaa@domain.com', 'Timed out', "System call interrupted due to time out");
            }
    if ($? == -1) {
    #send email from aaa to HELP
    CustomSendMail('help@domain.com', 'aaa@domain.com', 'Failed', "Failed to execute: $!\n");
    } elsif ($? & 127) {
    printf "Child died with signal %d, %s coredump\n",
    ($? & 127),  ($? & 128) ? 'with' : 'without';
    my $signal = ($? & 127);
    my $woCodedump = ($? & 128) ? 'with' : 'without';
    #send email from aaa to HELP
    CustomSendMail('help@domain.com', 'aaa@domain.com', 'Failed', "Child died with signal $signal, $woCodedump coredump\n");
    }


SOME MORE CODE

Open in new window



Thanks,
TolgarAsked:
Who is Participating?
 
codefluxCommented:
You don't need `local` when making an alarm - once you call `alarm 0`, the SIG handler is reset.  Also, you may want to `die $@` to truly propagate.  And lastly, you should be handling the system() errors within the eval{}.

Alternatively, you can use /usr/bin/timeout (part of coreutils RPM) to time out the program you execute in `system` - I've had great success with it.
eval {
        $SIG{ALRM} = sub { die "alarm\n" };    # NB: \n required
        alarm 60; 

        # ------- MYCODE . It has a system call in it . And I assume system call may hang or fail .

        if ($? == -1) {
            #send email from aaa to HELP
            CustomSendMail('help@domain.com', 'aaa@domain.com', 'Failed', "Failed to execute: $!\n");
        } elsif ($? & 127) {
            printf "Child died with signal %d, %s coredump\n", ($? & 127), ($? & 128) ? 'with' : 'without';
            my $signal = ($? & 127);
            my $woCodedump = ($? & 128) ? 'with' : 'without';
            #send email from aaa to HELP
            CustomSendMail('help@domain.com', 'aaa@domain.com', 'Failed', "Child died with signal $signal, $woCodedump coredump\n");
        }

        alarm 0;
    };    #eval

    if ($@) {
        die $@ unless $@ eq "alarm\n";    # propagate unexpected errors timed out 
        CustomSendMail('help@domain.com', 'aaa@domain.com', 'Timed out', "System call interrupted due to time out");
    }

Open in new window

0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.