# emulate default behaviors for the various signals.
package Signals::XSIG::Default;
## no critic (RequireLocalizedPunctuationVars)
use strict;
use warnings;
use Config;
use Carp;
use POSIX ();
use Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw(%DEFAULT_BEHAVIOR);
our %DEFAULT_BEHAVIOR;
our $VERSION = '0.12';
my @snam = split ' ', $Config{sig_name};
my @snum = split ' ', $Config{sig_num};
sub import {
my $ignore = 1;
while (<DATA>) {
next if /^#/;
next unless /\S/;
if (/^\[(.+)\]/) {
if ($1 eq 'default' || $1 eq $^O) {
$ignore = 0;
} else {
$ignore = 1;
}
} elsif (/\{(.+)\/(\d+)\}/) {
if ($1 eq $^O && $2 <= int($] * 1000)) {
$ignore = 0;
} else {
$ignore = 1;
}
} elsif (!$ignore) {
s/^\d+\. //;
s/^SIG//;
my ($sig, $num, $behavior) = /^(\w+)\s+\[(\d*)\]\s+=>\s+(.+)/;
if (defined $sig) {
$DEFAULT_BEHAVIOR{$sig} = $behavior;
}
}
}
return;
}
sub perform_default_behavior {
my ($signal, @args) = @_;
#print "XXXXXX performing default behavior for $signal ...\n";
my $funcname = 'default_SIG' . $signal;
if (defined &$funcname) {
no strict 'refs'; ## no critic (NoStrict)
return if $funcname->($signal, @args);
}
my $behavior = $DEFAULT_BEHAVIOR{$signal};
if (!defined $behavior) {
if ($signal =~ /^NUM(\d+)/) {
my $signum = 0 + $1;
$behavior = $DEFAULT_BEHAVIOR{"NUMxx"};
$behavior =~ s/xx/$signum/;
}
if (!defined $behavior) {
croak "Signals::XSIG: no default behavior is specified ",
"for SIG$signal. Terminating this program.\n";
}
}
if (ref($behavior) eq 'CODE') {
if (defined &$behavior) {
$behavior->($signal);
return;
} else {
carp "Signals::XSIG: Default behavior for SIG$signal ",
"is not set to a valid subroutine.";
return;
}
}
if ($behavior eq 'IGNORE') {
return;
}
if ($behavior eq 'SUSPEND') {
suspend($signal);
# ... then wait for the SIGCONT ...
return;
}
if ($behavior =~ /^ABORT/) {
untie %SIG;
%SIG = ();
$SIG{$signal} = $SIG{"ABRT"} = "DEFAULT";
killprog_with_signal("ABRT");
POSIX::abort();
croak "Abort\n";
}
if ($behavior =~ /^SIGSEGV/) {
killprog_with_signal('SEGV');
croak "Abort\n";
}
if ($behavior =~ /^EXIT (\d+)/) {
my $exit_code = $1;
exit($exit_code);
}
if ($behavior =~ /^TERMINATE/) {
my $number;
for (my $i=0; $i<@snum; $i++) {
$number = $snum[$i] if $signal eq $snam[$i];
}
killprog_with_signal($signal, $number);
croak "default behavior for SIG$signal should have killed script ",
"but for some reason it didn't :-(\n";
}
croak "Signals::XSIG: unknown behavior \"$behavior\" ",
"for SIG$signal. Terminating this program.\n";
}
sub killprog_with_signal {
my ($sig,$sig_no) = @_;
untie %SIG;
%SIG = ();
$SIG{$sig} = 'DEFAULT';
unless ($sig_no) {
my @sig_name = split ' ', $Config{sig_name};
($sig_no) = grep { $sig eq $sig_name[$_] } split ' ',$Config{sig_num};
}
kill $sig, $$;
sleep 1 if $^O eq 'MSWin32';
eval {
use POSIX ();
if ($sig_no) {
# this is needed for Linux
POSIX::sigaction($sig_no, &POSIX::SIG_DFL);
POSIX::sigprocmask(&POSIX::SIG_UNBLOCK,
POSIX::SigSet->new($sig_no));
}
} or ();
kill $sig, $$;
sleep 1 if $^O eq 'MSWin32';
my $miniprog = q[$SIG{'__SIGNAL__'}='DEFAULT';
kill '__SIGNAL__',$$;sleep 1+"MSWin32"eq$^O;die];
$miniprog =~ s/__SIGNAL__/$sig/g;
exec($^X, "-e", $miniprog);
}
# in principle, SIGSTOP cannot be trapped.
sub suspend {
if ($^O eq 'MSWin32') {
# MSWin32 doesn't have signals as such.
# Win32::API->SuspendProcess / SuspendThread ?
# Win32::Process->suspend ?
# Win32::Thread->suspend ?
if ($$ > 0) {
# suspend process
# enumerate all threads in process
# suspend each thread
} else {
# suspend thread
}
}
return kill 'STOP', $$;
}
##################################################################
# system specific and other special behaviors.
# Signals that don't fall into the terminate/suspend/ignore
# paradigm or that have other special needs can be implemented
# below.
# Return true if the signal is "handled" and no further
# processing is necessary.
sub default_SIG__WARN__ { ## no critic (Unpacking)
CORE::warn @_;
return 1;
}
sub default_SIG__DIE__ { ## no critic (Unpacking)
CORE::die @_;
return 1;
}
1;
=head1 NAME
Signals::XSIG::Default
=head1 DESCRIPTION
Module for emulating the default behavior for all
signals in your system. The emulator is used when you have
used L<Signals::XSIG> to register more than one
handler for a signal, and at least one of those
handlers is C<DEFAULT>.
See L<Signals::XSIG> for much more information.
=cut
# see spike/analyze_default_signal_behavior.pl
# for each new system that is available to us, run
# spike/analyze_default_signal_behavior.pl
# and include that data at the end of this file ...
#
# we can also infer behavior from CPAN tester results,
# see t/20-defaults.t
#
__DATA__
[default]
ABRT [] => ABORT
ALRM [] => TERMINATE
BREAK [] => TERMINATE
BUS [] => TERMINATE
CHLD [] => IGNORE
CLD [] => IGNORE
CONT [] => IGNORE
EMT [] => TERMINATE
FPE [] => TERMINATE
HUP [] => TERMINATE
ILL [] => TERMINATE
INT [] => TERMINATE
IO [] => TERMINATE
IOT [] => TERMINATE
KILL [] => TERMINATE
LOST [] => TERMINATE
NUMxx [] => TERMINATE xx
PIPE [] => TERMINATE
POLL [] => TERMINATE
PROF [] => TERMINATE
PWR [] => TERMINATE
QUIT [] => TERMINATE
SEGV [] => ABORT
STKFLT [] => TERMINATE
STOP [] => SUSPEND
SYS [] => TERMINATE
TERM [] => TERMINATE
TRAP [] => TERMINATE
TSTP [] => SUSPEND
TTIN [] => SUSPEND
TTOU [] => SUSPEND
URG [] => IGNORE
USR1 [] => TERMINATE
USR2 [] => TERMINATE
VTALRM [] => TERMINATE
WINCH [] => IGNORE
XCPU [] => TERMINATE
XFSZ [] => TERMINATE
ZERO [] => IGNORE
__DIE__ [] => IGNORE
__WARN__ [] => IGNORE
[MSWin32]
ABRT [22] => EXIT 22
ALRM [14] => EXIT 14
BREAK [21] => TERMINATE 21
CHLD [20] => EXIT 20
CLD [20] => EXIT 20
CONT [25] => EXIT 25
FPE [8] => EXIT 8
HUP [1] => EXIT 1
ILL [4] => EXIT 4
INT [2] => IGNORE
KILL [9] => EXIT 9
NUMxx [] => EXIT xx
PIPE [13] => EXIT 13
QUIT [21] => IGNORE
SEGV [11] => EXIT 11
STOP [23] => EXIT 23
TERM [15] => IGNORE
ZERO [] => IGNORE
__DIE__ [] => IGNORE
__WARN__ [] => IGNORE
[linux]
ABRT [6] => TERMINATE 6
ALRM [14] => TERMINATE 14
BUS [7] => TERMINATE 7
CHLD [17] => IGNORE
CLD [17] => IGNORE
CONT [18] => IGNORE
FPE [8] => TERMINATE 8
HUP [1] => TERMINATE 1
ILL [4] => TERMINATE 4
INT [2] => TERMINATE 2
IO [29] => TERMINATE 29
IOT [6] => TERMINATE 6
KILL [9] => TERMINATE 9
NUMxx [] => TERMINATE xx
PIPE [13] => TERMINATE 13
POLL [29] => TERMINATE 29
PROF [27] => TERMINATE 27
PWR [30] => TERMINATE 30
QUIT [3] => TERMINATE 3
RTMAX [64] => TERMINATE 64
RTMIN [34] => TERMINATE 34
SEGV [11] => TERMINATE 11
STKFLT [16] => TERMINATE 16
STOP [19] => SUSPEND
SYS [31] => TERMINATE 31
TERM [15] => TERMINATE 15
TRAP [5] => TERMINATE 5
TSTP [20] => SUSPEND
TTIN [21] => SUSPEND
TTOU [22] => SUSPEND
UNUSED [31] => TERMINATE 31
URG [23] => IGNORE
USR1 [10] => TERMINATE 10
USR2 [12] => TERMINATE 12
VTALRM [26] => TERMINATE 26
WINCH [28] => IGNORE
XCPU [24] => TERMINATE 24
XFSZ [25] => TERMINATE 25
ZERO [0] => IGNORE
__DIE__ [] => IGNORE
__WARN__ [] => IGNORE
[cygwin]
ABRT [6] => TERMINATE 134
ALRM [14] => TERMINATE 14
BUS [10] => TERMINATE 10
CHLD [20] => IGNORE
CLD [20] => IGNORE
CONT [19] => IGNORE
EMT [7] => TERMINATE 7
FPE [8] => TERMINATE 8
HUP [1] => TERMINATE 1
ILL [4] => TERMINATE 4
INT [2] => TERMINATE 2
IO [23] => IGNORE
KILL [9] => TERMINATE 9
LOST [29] => TERMINATE 29
PIPE [13] => TERMINATE 13
POLL [23] => IGNORE
PROF [27] => TERMINATE 27
PWR [29] => TERMINATE 29
QUIT [3] => TERMINATE 131
RTMAX [32] => TERMINATE 32
RTMIN [32] => TERMINATE 32
SEGV [11] => TERMINATE 11
STOP [17] => SUSPEND
SYS [12] => TERMINATE 12
TERM [15] => TERMINATE 15
TRAP [5] => TERMINATE 5
TSTP [18] => SUSPEND
TTIN [21] => SUSPEND
TTOU [22] => SUSPEND
URG [16] => IGNORE
USR1 [30] => TERMINATE 30
USR2 [31] => TERMINATE 31
VTALRM [26] => TERMINATE 26
WINCH [28] => IGNORE
XCPU [24] => TERMINATE 24
XFSZ [25] => TERMINATE 25
ZERO [] => IGNORE
__DIE__ [] => IGNORE
__WARN__ [] => IGNORE
# www.cpantesters.org/cpan/report/4d60a820-e5c2-11df-bf62-5eb33ef6c52e
[darwin]
ABRT [6] => TERMINATE 6
EMT [7] => TERMINATE 7
SEGV [11] => TERMINATE 11
IO [] => IGNORE
IOT [6] => TERMINATE 6
# www.cpantesters.org/cpan/report/4b99dd2a-e60f-11df-bb29-ad544afd17af
[dragonfly]
ABRT [6] => TERMINATE 134
EMT [7] => TERMINATE 135
SEGV [11] => TERMINATE 139
IO [] => IGNORE
IOT [] => TERMINATE 134
# www.cpantesters.org/cpan/report/62d0832e-e621-11df-858d-e879df34a846a
[freebsd]
ABRT [6] => TERMINATE 134
EMT [7] => TERMINATE 135
SEGV [11] => TERMINATE 139
IO [] => IGNORE
IOT [] => TERMINATE 134
[gnukfreebsd]
ABRT [6] => TERMINATE 134
EMT [7] => TERMINATE 135
SEGV [11] => TERMINATE 139
IO [] => IGNORE
IOT [] => TERMINATE 134
# www.cpantesters.org/cpan/report/c8635a72-e5d6-11df-a833-d9c7245fd73a
[irix]
ABRT [6] => TERMINATE 134
EMT [7] => TERMINATE 135
SEGV [11] => TERMINATE 139
RTMIN [49] => TERMINATE 49
RTMAX [64] => TERMINATE 64
IOT [] => TERMINATE 134
# www.cpantesters.org/cpan/report/209fd0b6-e61e-11df-bb29-ad544afd17af
[netbsd]
ABRT [6] => TERMINATE 134
EMT [7] => TERMINATE 135
SEGV [11] => TERMINATE 139
IO [] => IGNORE
IOT [6] = TERMINATE 134
[openbsd]
ILL [4] => TERMINATE 132
ABRT [6] => TERMINATE 134
EMT [7] => TERMINATE 135
BUS [10] => TERMINATE 138
SEGV [11] => TERMINATE 139
IO [] => IGNORE
[mirbsd]
ILL [4] => TERMINATE 132
BUS [10] => TERMINATE 138
SEGV [11] => TERMINATE 139
IO [] => IGNORE
[solaris]
ABRT [6] => TERMINATE 134
ALRM [14] => TERMINATE 14
BUS [10] => TERMINATE 138
CANCEL [36] => IGNORE
CHLD [18] => IGNORE
CLD [18] => IGNORE
CONT [25] => IGNORE
EMT [7] => TERMINATE 135
FPE [8] => TERMINATE 136
FREEZE [34] => IGNORE
HUP [1] => TERMINATE 1
ILL [4] => TERMINATE 132
INT [2] => TERMINATE 2
IO [22] => TERMINATE 22
IOT [6] => TERMINATE 134
JVM1 [39] => IGNORE
JVM2 [40] => IGNORE
KILL [9] => TERMINATE 9
LOST [37] => TERMINATE 37
LWP [33] => IGNORE
NUMxx [42] => TERMINATE xx
PIPE [13] => TERMINATE 13
POLL [22] => TERMINATE 22
PROF [29] => TERMINATE 29
PWR [19] => IGNORE
QUIT [3] => TERMINATE 131
RTMAX [48] => TERMINATE 48
RTMIN [41] => TERMINATE 41
SEGV [11] => TERMINATE 139
STOP [23] => SUSPEND
SYS [12] => TERMINATE 140
TERM [15] => TERMINATE 15
THAW [35] => IGNORE
TRAP [5] => TERMINATE 5
TSTP [24] => SUSPEND
TTIN [26] => SUSPEND
TTOU [27] => SUSPEND
URG [21] => IGNORE
USR1 [16] => TERMINATE 16
USR2 [17] => TERMINATE 17
VTALRM [28] => TERMINATE 28
WAITING [32] => IGNORE
WINCH [20] => IGNORE
XCPU [30] => TERMINATE 30
XFSZ [31] => TERMINATE 159
XRES [38] => IGNORE
ZERO [] => IGNORE
__DIE__ [] => IGNORE
__WARN__ [] => IGNORE