From: Leon Timmermans Date: Thu, 24 Feb 2011 21:34:40 +0000 (+0000) Subject: Detect unsafe signals more reliably on BSD/Solaris X-Git-Tag: accepted/trunk/20130322.191538~5318 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b3dbdd48ca2da90bce7f16d545cca54c3dc58f35;p=platform%2Fupstream%2Fperl.git Detect unsafe signals more reliably on BSD/Solaris 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 --- diff --git a/mg.c b/mg.c index 6f82001..7b5fdf5 100644 --- 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; diff --git a/t/op/sigdispatch.t b/t/op/sigdispatch.t index 3a0138a..3d92a39 100644 --- a/t/op/sigdispatch.t +++ b/t/op/sigdispatch.t @@ -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'; }