gcbenison
gcbenison

Reputation: 11963

Die reliably in response to a signal

The following code is supposed to time out after a certain period, due to arrival of SIGALRM -

sub sig_alrm_handler() { die "Timed out, sorry" }

$SIG{ALRM} = \&sig_alrm_handler;
main();

Usually this approach works, except sometimes main() includes a Try::Tiny 'try' block which intercepts the "die" from sig_alrm_handler, effectively ignoring the timeout. How can this approach be changed so that SIGALRM will reliably terminate the program, even when main() catches exceptions?

Upvotes: 1

Views: 75

Answers (1)

hmatt1
hmatt1

Reputation: 5129

If you want to end your program, you can call exit from your signal function. If you have an END block, it will still execute that.

Here's a code example. I used SIGINT for it, but SIGALRM works the same way.

#!/usr/bin/perl
use strict;
use warnings;
use Try::Tiny;

sub sig_int_handler() {
#   die "Dying from SIGINT\n";
    warn "Exiting from SIGINT\n";
    exit(128 | 2);   # 2 = SIGINT
};

$SIG{INT} = \&sig_int_handler;
my $i = 0;
try {
    while (1) {

    }
} catch {
    print "caught exception\n";
};

print "continuing execution\n";

In this example, if you hit ctrl-c while it is running, it will exit without printing the two print statements. However if you uncomment the line with die on it in the sig_int_handler subroutine, it will print them both when you send the INT signal.

Upvotes: 3

Related Questions