This works as expected since Perl 5.10.1: SIGINTs are trapped.
#!/usr/bin/perl
use strict;
use warnings;
$SIG{INT} = sub { die "Caught a sigint $!" };
sleep(20);
But here SIGINTs are not trapped.
#!/usr/bin/perl
use strict;
use warnings;
$SIG{INT} = sub { die "Caught a sigint $!" };
END {
sleep(20);
}
This can be fixed by setting the handler again in the END
block, like so:
END {
$SIG{INT} = sub { die "Caught a sigint $!" };
sleep(20);
}
But that won't work if you have more than one block: handlers must be set again for every block.
I've tried to figure this out and I can't find an explanation at perldoc. The only mention of this behaviour I can find is a footnote from Practical Perl Programming A D Marshall 1999-2005
Note Signals that are sent to your script can bypass the END blocks.
Would someone explain this?
This works for me: Re-install the handler in the END block that runs first (last in code)
When started and Ctrl-C-ed after a few seconds this prints
So you need to add an
END
block, last in the code,END { $SIG{INT} = 'IGNORE' }
.The change to
END
${^GLOBAL_PHASE}, which comes after the runtime (RUN
phase) finished, apparently removes/disables signal handlers. I can't find this in documentation.But once the handler is re-installed in the
END
phase it is effective throughout. It's cleanest of course to do that in theEND
block that is executed first.