Question

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?

Était-ce utile?

La solution

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top