Some time ago I had problems with $SIG{WINCH}
because I loaded two module which were both using $SIG{WINCH}
Problems with $SIG{WINCH} when using it in a module.
Now I have tried to reconstruct this case but this time I put in one module the $SIG{WINCH}
within a subroutine.
use warnings;
use strict;
package My_Package;
use Exporter 'import';
our @EXPORT = qw(choose);
sub choose {
# ...
my $size_changed;
local $SIG{WINCH} = sub { $size_changed = 1; }; # edit: added "local"
while ( 1 ) {
my $c = getch();
if ( $size_changed ) {
write_screen();
$size_changed = 0;
next;
}
# ...
}
}
Now it looks like it is working.
Am I save if I localize $SIG{WINCH}
this way or did I forget something when reconstructing?
This works because your code immediately enters a while
loop after setting the signal handler, so no other code gets to run (or set a new handler). When the while loop exits, your handler is unset and the old one is restored automatically thanks to local
.
For more resilient code I would check to see if an existing signal handler exists, and call that. Otherwise any other module that has a SIGWINCH handler will be broken. E.g.
my $orig_sigwinch = $SIG{WINCH};
local $SIG{WINCH} = sub {
$orig_sigwinch->() if $orig_sigwinch && ref $orig_sigwinch eq 'CODE';
$size_changed = 1;
}
Note that this doesn't consider the case where $orig_sigwinch
is a function name rather than a code reference.