verbose
verbose

Reputation: 7917

Perl: passing argument to signal handler causes handler to run immediately

Short version: I'm trying to pass an argument to a signal handler. When I do so, however, the handler runs as soon as the program is launched. Why is this happening, and how can I correct it?

Details: I have the following line in my code: $SIG{ALRM} = \&timesup($number);. The signal handler itself is:

sub timesup {
    my $num = shift;
    die "Time ran out.\nNumber was: $num\n"
}

When I run the program, it immediately runs the signal handler and dies with the specified message. I tested by generating a random value for $number just before the $SIG{ALRM} line. The swan song message on dying does print the random value, so I think the argument itself is being passed correctly. But the output is immediate:

bassoon:$ ./myscript.pl

Time ran out.
Number was: 4

If I take away the argument and simply have $SIG{ALRM} = \&timesup;, then the program works as expected. However, in that case I have no way of passing the argument to the subroutine, and have to use a global, which I'd rather not do.

What am I doing wrong? Thanks for your help.

Upvotes: 4

Views: 1220

Answers (2)

amon
amon

Reputation: 57590

The \&timesup($number) calls the timesup sub (&timesup($number)) and then takes a reference to the return value (\). Calling a sub with & should be avoided because this bypasses prototypes and can have certain other effects.

The solution is to wrap your timesup application like this:

$SIG{ALRM} = sub { timesup($number) };

This is effectively partial application.

Upvotes: 8

amaslenn
amaslenn

Reputation: 805

You should set signal handler as follow: $SIG{ALRM} = 'timesup'

Upvotes: -3

Related Questions