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)
use warnings;
use strict;
use feature 'say';
$SIG{INT} = sub { say "Got $_[0]" };
#sleep 10;
say "done";
END { say "END, runs last" }
END {
say "END, runs next to last. Sleep then print";
sleep 10;
say "Woke up.";
}
# Executed first in END phase. The sole purpose: to reinstall the handler
END {
$SIG{INT} = sub { say "In END block, got $_[0]" };
}
When started and Ctrl-C-ed after a few seconds this prints
done. END, runs next to last. Sleep then print ^CIn END block, got INT Woke up. END, runs last
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 the END block that is executed first.
perldoc perlmod says:
An "END" code block is executed as late as possible, that is, after
perlhas finished running the program and just before the interpreter is being exited, even if it is exiting as a result of adie()function. (But not if it's morphing into another program via "exec", or being blown out of the water by a signal--you have to trap that yourself (if you can).)
I expect signal handlers to have been removed just before the interpreter is being exited. Therefore, I am not quite able to see what is surprising or unanticipated.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With