why is SIGALRM being set to SIG_DFL then back to perl's signal handler each time the local %SIG is set?
It's easy to think of "local $var = $val;" one operation, but there are two. "local" and "=" are separate operations.
local saves the current value of the variable, changes the value to undef and returns the variable as an lvalue. For $SIG{...}, the second step translates to switching to the default handler.
Then the assignment to the lvalue returned by local occurs, changing the signal handler to the custom handler.
The following code illustrates this clearly:
use strict; use warnings; BEGIN { package Testing; use Tie::Scalar qw( ); BEGIN { our @ISA = qw(Tie::StdScalar); } sub STORE { my ($self, $val) = @_; print("STORE ", defined($val) ? "[$val]" : 'undef', "\n"); shift->SUPER::STORE(@_) } } { our $s; tie $s, 'Testing'; { print("pre\n"); local $s; print("post\n"); } print("\n"); { print("pre\n"); local $s = 'a'; print("post\n"); } }
pre STORE undef # local post STORE undef # local unroll pre STORE undef # local STORE [a] # assignment post STORE undef # local unroll
Here's a solution:
use Sub::ScopeFinalizer qw( scope_finalizer ); sub local_sassign { my $r = \($_[0]); my $sentry = scope_finalizer { $$r = $_[0] } { args => [ $$r ] }; $$r = $_[1]; return $sentry; } sub f { my $sentry = local_sassign $SIG{ALRM}, \&alarm_handler; ... }
In reply to Re^2: Setting signal handlers considered unsafe? (local assigns undef)
by ikegami
in thread Setting signal handlers considered unsafe?
by gnosek
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |