diff options
author | Todd Rinaldo <toddr@cpan.org> | 2020-01-30 11:53:31 -0600 |
---|---|---|
committer | Todd Rinaldo <toddr@cpan.org> | 2020-02-04 13:32:37 -0600 |
commit | 92d4124ba4c1d1465a3a7cd6ae35bb0ad116b073 (patch) | |
tree | 1427fddfc0334132cd9162dbfed1ecc3a3096806 | |
parent | 34d254cefc451e5ab438acf22a51d7b557c05a0e (diff) | |
download | perl-92d4124ba4c1d1465a3a7cd6ae35bb0ad116b073.tar.gz |
Pass the canonical signal name to the signal handler when it is invoked.
Prior to this change, when a signal handler was invoked, the signame passed
into the sub would be the name of the signal that was defined first via {}.
This meant that the handler had to either be aware of the duplicates and
handle things appropriately or it would be at the mercy of action at a
distance the handler might be unaware of.
This change assures a consistent signal name for now on. It should be
the first signal listed in $Config{sig_name}. Duplicates are listed
at the end.
-rw-r--r-- | MANIFEST | 1 | ||||
-rw-r--r-- | mg.c | 3 | ||||
-rw-r--r-- | t/op/signame_canonical.t | 74 |
3 files changed, 77 insertions, 1 deletions
@@ -5918,6 +5918,7 @@ t/op/runlevel.t See if die() works from perl_call_*() t/op/select.t See if 0- and 1-argument select works t/op/setpgrpstack.t See if setpgrp works t/op/sigdispatch.t See if signals are always dispatched +t/op/signame_canonical.t See if duplicate signal names always use the canonical name when the handler is invoked. t/op/signatures.t See if sub signatures work t/op/sigsystem.t See if system and SIGCHLD handlers play together nicely t/op/sleep.t See if sleep works @@ -1753,7 +1753,8 @@ Perl_magic_setsig(pTHX_ SV *sv, MAGIC *mg) Ideally we'd find some way of making SVs at (C) compile time, or at least, doing most of the work. */ if (!PL_psig_name[i]) { - PL_psig_name[i] = newSVpvn(s, len); + const char* name = PL_sig_name[i]; + PL_psig_name[i] = newSVpvn(name, strlen(name)); SvREADONLY_on(PL_psig_name[i]); } } else { diff --git a/t/op/signame_canonical.t b/t/op/signame_canonical.t new file mode 100644 index 0000000000..abd77328fa --- /dev/null +++ b/t/op/signame_canonical.t @@ -0,0 +1,74 @@ +#!perl -w + +# We assume that TestInit has been used. + +BEGIN { + chdir 't' if -d 't'; + require './test.pl'; +} + +use strict; +use warnings; + +use Config; +use Data::Dumper; +$Data::Dumper::Sortkeys = 1; + +# Windows doesn't seem to be able to test signals. +skip_all("Signals lock up tests on $^O") if $^O =~ /MSWin32/; + +$| = 1; + +# Extract the signals from %Config. +my @SIGNAMES = split /\s+/, $Config{sig_name}; +my @SIGNUMS = split /\s+/, $Config{sig_num}; + +my %SIG_MAP; +foreach my $i ( 0 .. ( scalar @SIGNAMES - 1 ) ) { + $SIG_MAP{ $SIGNAMES[$i] } = $SIGNUMS[$i]; +} + +# Find the canonical (first) signal names. +my %CANONICAL_SIG; +my @duplicate_signals; +foreach my $sig (@SIGNAMES) { + my $signum = $SIG_MAP{$sig}; + $CANONICAL_SIG{$signum} //= $sig; + push @duplicate_signals, $sig if $CANONICAL_SIG{$signum} ne $sig; +} + +plan tests => scalar @duplicate_signals * 5; +watchdog(25); + +# Define the duplicate signal handlers. +my $sent = ''; + +sub handler_is { + my $signame = shift; + my $signum = $SIG_MAP{$signame}; + + my $canonical = $CANONICAL_SIG{$signum}; + + is( $signame, $canonical, "Signal name for $sent is recieved as the canonical '$canonical' name." ); + + return; +} + +foreach my $dupe (@duplicate_signals) { + my $canonical_name = $CANONICAL_SIG{ $SIG_MAP{$dupe} }; + note "Testing $dupe / $canonical_name signal pair"; + { + local $SIG{$dupe} = \&handler_is; + is( $SIG{$dupe}, $SIG{$canonical_name}, "Both handlers for $canonical_name/$dupe are set" ); + + $sent = $dupe; + kill $dupe, $$; + + $sent = $canonical_name; + kill $canonical_name, $$; + } + + is( $SIG{$dupe}, undef, "The signal $dupe is cleared after local goes out of scope." ); + is( $SIG{$canonical_name}, undef, "The signal $canonical_name is cleared after local goes out of scope." ); +} + |