New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
%SIG handlers BLOCK/UNBLOCK signals rather than BLOCK+save / restore #11025
Comments
From @leonerdCreated by @leonerdWhen running the code in a $SIG{CHLD} slot, Perl does the following: rt_sigprocmask(SIG_BLOCK, [CHLD], NULL, 8) = 0 My process is running with SIGCHLD blocked (set by POSIX::sigprocmask()); and Problem is, the first time a SIGCHLD is recieved, the above sequence manages Instead, the mask should be saved by the first call, and restored by the rt_sigprocmask(SIG_BLOCK, [CHLD], [CHLD], 8) = 0 Perl Info
|
From zefram@fysh.orgPaul LeoNerd Evans wrote:
Restore the whole mask? What if you want to change the blocking status -zefram |
The RT System itself - Status changed from 'new' to 'open' |
From @LeontOn Tue, Jan 11, 2011 at 1:23 PM, Zefram <zefram@fysh.org> wrote:
How about this? int was_blocked; sigemptyset(&new); sigprocmask(SIG_BLOCK, &new, &old) = 0; Signals can't block themselves that way, but they couldn't do that Leon |
From @leonerdOn Tue, Jan 11, 2011 at 01:55:34PM +0100, Leon Timmermans wrote:
Ah, an excellent point.
That looks much better yes. Is there a plan for fixing this? Does anyone want to have a stab at -- leonerd@leonerd.org.uk |
From @LeontOn Wed, Jan 12, 2011 at 5:23 PM, Paul LeoNerd Evans
I attached a quick patch, but haven't written tests yet. I've skipped On a related issue, most uses of sigprocmask (not just this one) Leon |
From @Leontsigproc.patchdiff --git a/mg.c b/mg.c
index a6912a0..31caf08 100644
--- a/mg.c
+++ b/mg.c
@@ -1443,15 +1443,25 @@ Perl_despatch_signals(pTHX)
for (sig = 1; sig < SIG_SIZE; sig++) {
if (PL_psig_pend[sig]) {
dSAVE_ERRNO;
- PERL_BLOCKSIG_ADD(set, sig);
+#if defined PERL_BLOCK_SIGNALS
+ int was_blocked;
+ sigset_t new, old;
+
+ sigemptyset(&new);
+ sigaddset(&new, sig);
+ sigprocmask(SIG_BLOCK, &new, &old);
+ was_blocked = sigismember(&old, sig);
+#endif
PL_psig_pend[sig] = 0;
- PERL_BLOCKSIG_BLOCK(set);
#if defined(HAS_SIGACTION) && defined(SA_SIGINFO)
(*PL_sighandlerp)(sig, NULL, NULL);
#else
(*PL_sighandlerp)(sig);
#endif
- PERL_BLOCKSIG_UNBLOCK(set);
+#ifdef PERL_BLOCK_SIGNALS
+ if (!was_blocked)
+ sigprocmask(SIG_UNBLOCK, &new, NULL);
+#endif
RESTORE_ERRNO;
}
}
|
From @nwc10On Wed, Jan 12, 2011 at 06:45:58PM +0100, Leon Timmermans wrote:
They aren't used anywhere else: $ ack PERL_BLOCKSIG_ `cat ../PERL_BLOCKSIG_ ` perl/mg.c perl/perl.h Git blame shows that they were moved to perl.h by 16bd9a8, Reducing levels of indirection (that don't otherwise add anything) good, [I've not really been following the ramifications of the rest of this thread] Nicholas Clark |
From @LeontOn Wed, Jan 12, 2011 at 6:45 PM, Leon Timmermans <fawaka@gmail.com> wrote:
I've attached new patches. A fixed version of the previous patch (so Leon |
From @Leont0001-Conditionally-unblock-after-signal-handler-82040.patchFrom 43240ceed35119fe0d77fe0d05a12fd1e6686649 Mon Sep 17 00:00:00 2001
From: Leon Timmermans <fawaka@gmail.com>
Date: Thu, 13 Jan 2011 18:30:29 +0100
Subject: [PATCH 1/2] Conditionally unblock after signal handler[#82040]
Only unblock signal after a safe-signal handler is executed if that signal was
also unblocked before the handler.
---
mg.c | 23 ++++++++++++++++++++---
1 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/mg.c b/mg.c
index a6912a0..6d2b2d7 100644
--- a/mg.c
+++ b/mg.c
@@ -1443,15 +1443,32 @@ Perl_despatch_signals(pTHX)
for (sig = 1; sig < SIG_SIZE; sig++) {
if (PL_psig_pend[sig]) {
dSAVE_ERRNO;
- PERL_BLOCKSIG_ADD(set, sig);
+#if defined(HAS_SIGPROCMASK)
+ /* From sigaction(2) (FreeBSD man page):
+ * | Signal routines normally execute with the signal that
+ * | caused their invocation blocked, but other signals may
+ * | yet occur.
+ * Emulation of this behavior (from within Perl) is enabled
+ * using sigprocmask
+ */
+ int was_blocked;
+ sigset_t newset, oldset;
+
+ sigemptyset(&newset);
+ sigaddset(&newset, sig);
+ sigprocmask(SIG_BLOCK, &newset, &oldset);
+ was_blocked = sigismember(&oldset, sig);
+#endif
PL_psig_pend[sig] = 0;
- PERL_BLOCKSIG_BLOCK(set);
#if defined(HAS_SIGACTION) && defined(SA_SIGINFO)
(*PL_sighandlerp)(sig, NULL, NULL);
#else
(*PL_sighandlerp)(sig);
#endif
- PERL_BLOCKSIG_UNBLOCK(set);
+#if defined(HAS_SIGPROCMASK)
+ if (!was_blocked)
+ sigprocmask(SIG_UNBLOCK, &newset, NULL);
+#endif
RESTORE_ERRNO;
}
}
--
1.7.1
|
From @Leont0002-Remove-obsolete-macros.patchFrom 33bf137de0e6074034dd6507ed3df4291025836e Mon Sep 17 00:00:00 2001
From: Leon Timmermans <fawaka@gmail.com>
Date: Thu, 13 Jan 2011 18:30:59 +0100
Subject: [PATCH 2/2] Remove obsolete macros
---
perl.h | 30 ------------------------------
1 files changed, 0 insertions(+), 30 deletions(-)
diff --git a/perl.h b/perl.h
index 567150d..36da020 100644
--- a/perl.h
+++ b/perl.h
@@ -6089,36 +6089,6 @@ extern void moncontrol(int);
#define PERL_SIGNALS_UNSAFE_FLAG 0x0001
-/* From sigaction(2) (FreeBSD man page):
- * | Signal routines normally execute with the signal that
- * | caused their invocation blocked, but other signals may
- * | yet occur.
- * Emulation of this behavior (from within Perl) is enabled
- * by defining PERL_BLOCK_SIGNALS.
- */
-#define PERL_BLOCK_SIGNALS
-
-#if defined(HAS_SIGPROCMASK) && defined(PERL_BLOCK_SIGNALS)
-# define PERL_BLOCKSIG_ADD(set,sig) \
- sigset_t set; sigemptyset(&(set)); sigaddset(&(set), sig)
-# define PERL_BLOCKSIG_BLOCK(set) \
- sigprocmask(SIG_BLOCK, &(set), NULL)
-# define PERL_BLOCKSIG_UNBLOCK(set) \
- sigprocmask(SIG_UNBLOCK, &(set), NULL)
-#endif /* HAS_SIGPROCMASK && PERL_BLOCK_SIGNALS */
-
-/* How about the old style of sigblock()? */
-
-#ifndef PERL_BLOCKSIG_ADD
-# define PERL_BLOCKSIG_ADD(set, sig) NOOP
-#endif
-#ifndef PERL_BLOCKSIG_BLOCK
-# define PERL_BLOCKSIG_BLOCK(set) NOOP
-#endif
-#ifndef PERL_BLOCKSIG_UNBLOCK
-# define PERL_BLOCKSIG_UNBLOCK(set) NOOP
-#endif
-
/* Use instead of abs() since abs() forces its argument to be an int,
* but also beware since this evaluates its argument twice, so no x++. */
#define PERL_ABS(x) ((x) < 0 ? -(x) : (x))
--
1.7.1
|
From @LeontOn Thu, Jan 13, 2011 at 6:54 PM, Leon Timmermans <fawaka@gmail.com> wrote:
Added a few tests. I've never written tests for core before, so I hope Leon |
From @Leont0003-Added-tests-for-conditional-unblocking.patchFrom 2d6d161011c767d1148cd2e03ab415a9d9b893e4 Mon Sep 17 00:00:00 2001
From: Leon Timmermans <fawaka@gmail.com>
Date: Mon, 17 Jan 2011 16:29:11 +0100
Subject: [PATCH 3/3] Added tests for conditional unblocking
---
t/op/sigdispatch.t | 23 ++++++++++++++++++++++-
1 files changed, 22 insertions(+), 1 deletions(-)
diff --git a/t/op/sigdispatch.t b/t/op/sigdispatch.t
index 5d9908e..657ff98 100644
--- a/t/op/sigdispatch.t
+++ b/t/op/sigdispatch.t
@@ -7,8 +7,9 @@ BEGIN {
}
use strict;
+use Config;
-plan tests => 4;
+plan tests => 7;
watchdog(10);
@@ -36,3 +37,23 @@ eval {
};
is($@, "Alarm!\n", 'after the second loop');
+
+SKIP: {
+ skip('We can\'t test blocking without sigprocmask', 3) if $ENV{PERL_CORE_MINITEST} || !$Config{d_sigprocmask};
+
+ require POSIX;
+ my $new = POSIX::SigSet->new(&POSIX::SIGUSR1);
+ POSIX::sigprocmask(&POSIX::SIG_BLOCK, $new);
+
+ my $gotit = 0;
+ $SIG{USR1} = sub { $gotit++ };
+ kill SIGUSR1, $$;
+ is $gotit, 0, 'Haven\'t received signal yet';
+
+ my $old = POSIX::SigSet->new();
+ POSIX::sigsuspend($old);
+ is $gotit, 1, 'Received signal';
+
+ POSIX::sigprocmask(&POSIX::SIG_BLOCK, undef, $old);
+ ok $old->ismember(&POSIX::SIGUSR1), 'SIGUSR1 is still blocked';
+}
--
1.7.1
|
From @LeontImproved the tests patch, and a small documentation update for Leon |
From @Leont0003-Added-tests-for-conditional-unblocking.patchFrom 622727478dd68c5824a721bab1da15045ab884b0 Mon Sep 17 00:00:00 2001
From: Leon Timmermans <fawaka@gmail.com>
Date: Mon, 17 Jan 2011 16:29:11 +0100
Subject: [PATCH 3/4] Added tests for conditional unblocking
---
t/op/sigdispatch.t | 26 +++++++++++++++++++++++++-
1 files changed, 25 insertions(+), 1 deletions(-)
diff --git a/t/op/sigdispatch.t b/t/op/sigdispatch.t
index 5d9908e..a86861e 100644
--- a/t/op/sigdispatch.t
+++ b/t/op/sigdispatch.t
@@ -7,8 +7,9 @@ BEGIN {
}
use strict;
+use Config;
-plan tests => 4;
+plan tests => 9;
watchdog(10);
@@ -36,3 +37,26 @@ eval {
};
is($@, "Alarm!\n", 'after the second loop');
+
+SKIP: {
+ skip('We can\'t test blocking without sigprocmask', 3) if $ENV{PERL_CORE_MINITEST} || !$Config{d_sigprocmask};
+
+ require POSIX;
+ my $new = POSIX::SigSet->new(&POSIX::SIGUSR1);
+ POSIX::sigprocmask(&POSIX::SIG_BLOCK, $new);
+
+ my $gotit = 0;
+ $SIG{USR1} = sub { $gotit++ };
+ kill SIGUSR1, $$;
+ is $gotit, 0, 'Haven\'t third received signal yet';
+
+ my $old = POSIX::SigSet->new();
+ POSIX::sigsuspend($old);
+ is $gotit, 1, 'Received third signal';
+
+ kill SIGUSR1, $$;
+ is $gotit, 1, 'Haven\'t fourth received signal yet';
+ POSIX::sigprocmask(&POSIX::SIG_UNBLOCK, $new, $old);
+ ok $old->ismember(&POSIX::SIGUSR1), 'SIGUSR1 was still blocked';
+ is $gotit, 2, 'Received fourth signal';
+}
--
1.7.1
|
From @Leont0004-Clarify-limitation-in-safe-signals.patchFrom 24dadeebe63036ac4e0de0e929ec4134cbb48c67 Mon Sep 17 00:00:00 2001
From: Leon Timmermans <fawaka@gmail.com>
Date: Mon, 17 Jan 2011 17:59:33 +0100
Subject: [PATCH 4/4] Clarify limitation in safe signals.
---
ext/POSIX/lib/POSIX.pod | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/ext/POSIX/lib/POSIX.pod b/ext/POSIX/lib/POSIX.pod
index 64852e9..9df0cde 100644
--- a/ext/POSIX/lib/POSIX.pod
+++ b/ext/POSIX/lib/POSIX.pod
@@ -1196,6 +1196,10 @@ Synopsis:
Returns C<undef> on failure.
+Note that you can't reliably block or unblock a signal from its own signal
+handler if you're using safe signals. Other signals can be blocked or unblocked
+reliably.
+
=item sigsetjmp
C<sigsetjmp()> is C-specific: use C<eval {}> instead,
--
1.7.1
|
From @tamiasOn Mon, Jan 17, 2011 at 06:07:06PM +0100, Leon Timmermans wrote:
Those should be: is $gotit, 0, 'Haven\'t received third signal yet'; is $gotit, 1, 'Haven\'t received fourth signal yet'; I presume. Ronald |
From @LeontOn Mon, Jan 17, 2011 at 8:14 PM, Ronald J Kimball <rjk@tamias.net> wrote:
Yeah, I evidently wasn't paying attention when I added that :-| Leon |
From @cpansproutOn Thu Jan 13 09:55:03 2011, LeonT wrote:
On Mon Jan 17 09:07:28 2011, LeonT wrote:
Thank you. Applied as: |
@cpansprout - Status changed from 'open' to 'resolved' |
From @leonerdOn Wed, Jan 12, 2011 at 06:45:58PM +0100, Leon Timmermans wrote:
Thanks, that looks just right for what I had in mind. :) Now all I have to do is work out a workaround for older perls... -- leonerd@leonerd.org.uk |
From @LeontOn Tue, Jan 18, 2011 at 7:34 AM, Father Chrysostomos via RT
Seems I missed the special case of a signal handler that throws an Leon |
From @Leont0001-Also-unblock-signal-handlers-throwing-an-exception.patchFrom 8d341ae1dd4e083920e7f02e27695d90ecbcd94b Mon Sep 17 00:00:00 2001
From: Leon Timmermans <fawaka@gmail.com>
Date: Tue, 18 Jan 2011 16:40:07 +0100
Subject: [PATCH] Also unblock signal handlers throwing an exception
Also handle and test the edge case of a signal handler throwing an
exception
---
mg.c | 31 +++++++++++++++++++------------
t/op/sigdispatch.t | 21 ++++++++++++++++-----
2 files changed, 35 insertions(+), 17 deletions(-)
diff --git a/mg.c b/mg.c
index f51cd47..cc13531 100644
--- a/mg.c
+++ b/mg.c
@@ -1434,6 +1434,14 @@ Perl_csighandler_init(void)
}
#endif
+#if defined HAS_SIGPROCMASK
+static void
+unblock_sigmask(pTHX_ void* newset)
+{
+ sigprocmask(SIG_UNBLOCK, (sigset_t*)newset, NULL);
+}
+#endif
+
void
Perl_despatch_signals(pTHX)
{
@@ -1443,7 +1451,7 @@ Perl_despatch_signals(pTHX)
for (sig = 1; sig < SIG_SIZE; sig++) {
if (PL_psig_pend[sig]) {
dSAVE_ERRNO;
-#if defined(HAS_SIGPROCMASK)
+#ifdef HAS_SIGPROCMASK
/* From sigaction(2) (FreeBSD man page):
* | Signal routines normally execute with the signal that
* | caused their invocation blocked, but other signals may
@@ -1458,6 +1466,12 @@ Perl_despatch_signals(pTHX)
sigaddset(&newset, sig);
sigprocmask(SIG_BLOCK, &newset, &oldset);
was_blocked = sigismember(&oldset, sig);
+ if (!was_blocked) {
+ SV* save_sv = newSVpvn((char *)(&newset), sizeof(sigset_t));
+ ENTER;
+ SAVEFREESV(save_sv);
+ SAVEDESTRUCTOR_X(unblock_sigmask, SvPV_nolen(save_sv));
+ }
#endif
PL_psig_pend[sig] = 0;
#if defined(HAS_SIGACTION) && defined(SA_SIGINFO)
@@ -1465,9 +1479,9 @@ Perl_despatch_signals(pTHX)
#else
(*PL_sighandlerp)(sig);
#endif
-#if defined(HAS_SIGPROCMASK)
+#ifdef HAS_SIGPROCMASK
if (!was_blocked)
- sigprocmask(SIG_UNBLOCK, &newset, NULL);
+ LEAVE;
#endif
RESTORE_ERRNO;
}
@@ -3092,22 +3106,15 @@ Perl_sighandler(int sig)
POPSTACK;
if (SvTRUE(ERRSV)) {
-#ifndef PERL_MICRO
-#ifdef HAS_SIGPROCMASK
+#if !defined(PERL_MICRO) && !defined(HAS_SIGPROCMASK)
/* Handler "died", for example to get out of a restart-able read().
* Before we re-do that on its behalf re-enable the signal which was
* blocked by the system when we entered.
*/
- sigset_t set;
- sigemptyset(&set);
- sigaddset(&set,sig);
- sigprocmask(SIG_UNBLOCK, &set, NULL);
-#else
/* Not clear if this will work */
(void)rsignal(sig, SIG_IGN);
(void)rsignal(sig, PL_csighandlerp);
-#endif
-#endif /* !PERL_MICRO */
+#endif /* !PERL_MICRO && !HAS_SIGPROCMASK*/
die_sv(ERRSV);
}
cleanup:
diff --git a/t/op/sigdispatch.t b/t/op/sigdispatch.t
index a86861e..e3c8fdb 100644
--- a/t/op/sigdispatch.t
+++ b/t/op/sigdispatch.t
@@ -9,7 +9,7 @@ BEGIN {
use strict;
use Config;
-plan tests => 9;
+plan tests => 12;
watchdog(10);
@@ -39,7 +39,7 @@ eval {
is($@, "Alarm!\n", 'after the second loop');
SKIP: {
- skip('We can\'t test blocking without sigprocmask', 3) if $ENV{PERL_CORE_MINITEST} || !$Config{d_sigprocmask};
+ skip('We can\'t test blocking without sigprocmask', 8) if $ENV{PERL_CORE_MINITEST} || !$Config{d_sigprocmask};
require POSIX;
my $new = POSIX::SigSet->new(&POSIX::SIGUSR1);
@@ -48,15 +48,26 @@ SKIP: {
my $gotit = 0;
$SIG{USR1} = sub { $gotit++ };
kill SIGUSR1, $$;
- is $gotit, 0, 'Haven\'t third received signal yet';
+ is $gotit, 0, 'Haven\'t received third signal yet';
my $old = POSIX::SigSet->new();
POSIX::sigsuspend($old);
is $gotit, 1, 'Received third signal';
+ {
+ kill SIGUSR1, $$;
+ local $SIG{USR1} = sub { die "FAIL\n" };
+ POSIX::sigprocmask(&POSIX::SIG_BLOCK, undef, $old);
+ ok $old->ismember(&POSIX::SIGUSR1), 'SIGUSR1 is blocked';
+ eval { POSIX::sigsuspend(POSIX::SigSet->new) };
+ is $@, "FAIL\n", 'Exception is thrown, so received fourth signal';
+ POSIX::sigprocmask(&POSIX::SIG_BLOCK, undef, $old);
+ ok $old->ismember(&POSIX::SIGUSR1), 'SIGUSR1 is still blocked';
+ }
+
kill SIGUSR1, $$;
- is $gotit, 1, 'Haven\'t fourth received signal yet';
+ is $gotit, 1, 'Haven\'t received fifth signal yet';
POSIX::sigprocmask(&POSIX::SIG_UNBLOCK, $new, $old);
ok $old->ismember(&POSIX::SIGUSR1), 'SIGUSR1 was still blocked';
- is $gotit, 2, 'Received fourth signal';
+ is $gotit, 2, 'Received fifth signal';
}
--
1.7.1
|
From @cpansproutOn Tue Jan 18 07:43:33 2011, LeonT wrote:
Thank you. Applied as 7fe50b8. |
From @Leontribasushi discovered an issue in this patch. It breaks unsafe signal When an exception is thrown in a signal handler that results in a call a) Reinstate the old unblocking code for unsafe signals Both behaviors are buggy in my mind, but hey, we're talking about Leon |
From @leonerdOn Tue, Jan 25, 2011 at 11:11:30PM +0100, Leon Timmermans wrote:
Purely from my perspective, I'd be OK with this one. I wasn't using an -- leonerd@leonerd.org.uk |
From @LeontOn Tue, Jan 25, 2011 at 11:11 PM, Leon Timmermans <fawaka@gmail.com> wrote:
Patch doing option a attached. Not extensively tested though. Leon |
From @Leont0001-Unblock-signal-mask-on-error-for-unsafe-signals.patchFrom 2b14040da489ea1d784fa12fadbcf1e3d8666940 Mon Sep 17 00:00:00 2001
From: Leon Timmermans <fawaka@gmail.com>
Date: Sat, 12 Feb 2011 22:19:57 +0100
Subject: [PATCH] Unblock signal-mask on error for unsafe signals
---
mg.c | 16 ++++++++++++++--
1 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/mg.c b/mg.c
index cc13531..6a6473a 100644
--- a/mg.c
+++ b/mg.c
@@ -3106,15 +3106,27 @@ Perl_sighandler(int sig)
POPSTACK;
if (SvTRUE(ERRSV)) {
-#if !defined(PERL_MICRO) && !defined(HAS_SIGPROCMASK)
+#ifndef PERL_MICRO
/* Handler "died", for example to get out of a restart-able read().
* Before we re-do that on its behalf re-enable the signal which was
* blocked by the system when we entered.
*/
+#ifdef HAS_SIGPROCMASK
+#ifdef HAS_SIGACTION
+ if (sip)
+#endif
+ {
+ sigset_t set;
+ sigemptyset(&set);
+ sigaddset(&set,sig);
+ sigprocmask(SIG_UNBLOCK, &set, NULL);
+ }
+#else
/* Not clear if this will work */
(void)rsignal(sig, SIG_IGN);
(void)rsignal(sig, PL_csighandlerp);
-#endif /* !PERL_MICRO && !HAS_SIGPROCMASK*/
+#endif
+#endif /* !PERL_MICRO */
die_sv(ERRSV);
}
cleanup:
--
1.7.1
|
From @cpansproutOn Sat Feb 12 13:22:51 2011, LeonT wrote:
Not understanding this area very well (you know it far better than I), I |
From @LeontOn Sun, Feb 13, 2011 at 10:31 PM, Father Chrysostomos via RT
Here's a new patch that includes a test.
That breakage is due to a bug in that module's unit test, it's not Leon |
From @Leont0001-Unblock-signal-mask-on-error-for-unsafe-signals.patchFrom 2bc6c1aad7f99917ffec0ae188e9b775e1b660a7 Mon Sep 17 00:00:00 2001
From: Leon Timmermans <fawaka@gmail.com>
Date: Sat, 12 Feb 2011 22:19:57 +0100
Subject: [PATCH] Unblock signal-mask on error for unsafe signals
---
mg.c | 16 ++++++++++++++--
t/op/sigdispatch.t | 8 +++++++-
2 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/mg.c b/mg.c
index cc13531..6a6473a 100644
--- a/mg.c
+++ b/mg.c
@@ -3106,15 +3106,27 @@ Perl_sighandler(int sig)
POPSTACK;
if (SvTRUE(ERRSV)) {
-#if !defined(PERL_MICRO) && !defined(HAS_SIGPROCMASK)
+#ifndef PERL_MICRO
/* Handler "died", for example to get out of a restart-able read().
* Before we re-do that on its behalf re-enable the signal which was
* blocked by the system when we entered.
*/
+#ifdef HAS_SIGPROCMASK
+#ifdef HAS_SIGACTION
+ if (sip)
+#endif
+ {
+ sigset_t set;
+ sigemptyset(&set);
+ sigaddset(&set,sig);
+ sigprocmask(SIG_UNBLOCK, &set, NULL);
+ }
+#else
/* Not clear if this will work */
(void)rsignal(sig, SIG_IGN);
(void)rsignal(sig, PL_csighandlerp);
-#endif /* !PERL_MICRO && !HAS_SIGPROCMASK*/
+#endif
+#endif /* !PERL_MICRO */
die_sv(ERRSV);
}
cleanup:
diff --git a/t/op/sigdispatch.t b/t/op/sigdispatch.t
index e3c8fdb..5a5fc14 100644
--- a/t/op/sigdispatch.t
+++ b/t/op/sigdispatch.t
@@ -9,7 +9,7 @@ BEGIN {
use strict;
use Config;
-plan tests => 12;
+plan tests => 13;
watchdog(10);
@@ -70,4 +70,10 @@ SKIP: {
POSIX::sigprocmask(&POSIX::SIG_UNBLOCK, $new, $old);
ok $old->ismember(&POSIX::SIGUSR1), 'SIGUSR1 was still blocked';
is $gotit, 2, 'Received fifth signal';
+
+ # test unsafe signal handlers in combination with exceptions
+ my $action = POSIX::SigAction->new(sub { $gotit--, die }, POSIX::SigSet->new, 0);
+ POSIX::sigaction(&POSIX::SIGUSR1, $action);
+ eval { kill SIGUSR1, $$ } for 1..2;
+ is $gotit, 0, 'Received both signals';
}
--
1.7.1
|
From @cpansproutOn Thu Feb 17 10:16:58 2011, LeonT wrote:
Thank you. I’ve just applied it as c22d665. |
Migrated from rt.perl.org#82040 (status was 'resolved')
Searchable as RT82040$
The text was updated successfully, but these errors were encountered: