This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Detect unsafe signals more reliably on BSD/Solaris
authorLeon Timmermans <fawaka@gmail.com>
Thu, 24 Feb 2011 21:34:40 +0000 (21:34 +0000)
committerChris 'BinGOs' Williams <chris@bingosnet.co.uk>
Thu, 24 Feb 2011 21:34:40 +0000 (21:34 +0000)
Previous versions of the Posix spec allowed the struct siginfo_t*
parameter passed to the signal handler to be NULL in certain cases. More
recent Posix specifications (SUSv3) have rescinded this: Now this
parameter is required always to be non-NULL. However we use this
parameter to differentiate between safe and unsafe signals, as in the
former it will always be NULL and in the latter case it should have been
non-NULL.

This patch fixes this issue by also relying on the ucontext_t*
parameter.  This should reliably be non-NULL when using unsafe signals
handlers.

Signed-off-by: Chris 'BinGOs' Williams <chris@bingosnet.co.uk>
mg.c
t/op/sigdispatch.t

diff --git a/mg.c b/mg.c
index 6f82001..7b5fdf5 100644 (file)
--- a/mg.c
+++ b/mg.c
@@ -3001,7 +3001,7 @@ Perl_whichsig(pTHX_ const char *sig)
 
 Signal_t
 #if defined(HAS_SIGACTION) && defined(SA_SIGINFO)
-Perl_sighandler(int sig, siginfo_t *sip, void *uap PERL_UNUSED_DECL)
+Perl_sighandler(int sig, siginfo_t *sip, void *uap)
 #else
 Perl_sighandler(int sig)
 #endif
@@ -3113,7 +3113,7 @@ Perl_sighandler(int sig)
         */
 #ifdef HAS_SIGPROCMASK
 #if defined(HAS_SIGACTION) && defined(SA_SIGINFO)
-       if (sip)
+       if (sip || uap)
 #endif
        {
            sigset_t set;
index 3a0138a..3d92a39 100644 (file)
@@ -9,7 +9,7 @@ BEGIN {
 use strict;
 use Config;
 
-plan tests => 13;
+plan tests => 15;
 
 watchdog(10);
 
@@ -39,7 +39,7 @@ eval {
 is($@, "Alarm!\n", 'after the second loop');
 
 SKIP: {
-    skip('We can\'t test blocking without sigprocmask', 9) if $ENV{PERL_CORE_MINITEST} || !$Config{d_sigprocmask};
+    skip('We can\'t test blocking without sigprocmask', 11) if $ENV{PERL_CORE_MINITEST} || !$Config{d_sigprocmask};
 
     require POSIX;
     my $new = POSIX::SigSet->new(&POSIX::SIGUSR1);
@@ -74,6 +74,12 @@ SKIP: {
     # test unsafe signal handlers in combination with exceptions
     my $action = POSIX::SigAction->new(sub { $gotit--, die }, POSIX::SigSet->new, 0);
     POSIX::sigaction(&POSIX::SIGALRM, $action);
-    eval { alarm 1; POSIX::sigsuspend(POSIX::SigSet->new) } for 1..2;
+    eval {
+        alarm 1;
+        my $set = POSIX::SigSet->new;
+        POSIX::sigprocmask(&POSIX::SIG_BLOCK, undef, $set);
+        is $set->ismember(&POSIX::SIGALRM), 0, "SIGALRM is not blocked on attempt $_";
+        POSIX::sigsuspend($set);
+    } for 1..2;
     is $gotit, 0, 'Received both signals';
 }