diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | hurd/catch-signal.c | 13 |
2 files changed, 14 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog index ff43445170..0d93e03af9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2012-05-10 Samuel Thibault <samuel.thibault@ens-lyon.org> + + * hurd/catch-signal.c (hurd_catch_signal): Use sigsetjmp/siglongjmp + instead of setjmp/longjmp to restore the signal mask. Call sigsetjmp + when handler == SIG_ERR, not when handler != SIG_ERR. + 2012-05-10 Thomas Schwinge <thomas@schwinge.name> * sysdeps/mach/hurd/bits/socket.h: New file, copy from the bsd4.4 one. diff --git a/hurd/catch-signal.c b/hurd/catch-signal.c index 50cd36600d..3f946e1033 100644 --- a/hurd/catch-signal.c +++ b/hurd/catch-signal.c @@ -1,5 +1,5 @@ /* Convenience function to catch expected signals during an operation. - Copyright (C) 1996 Free Software Foundation, Inc. + Copyright (C) 1996-2012 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -27,9 +27,12 @@ hurd_catch_signal (sigset_t sigset, error_t (*operate) (struct hurd_signal_preemptor *), sighandler_t handler) { - jmp_buf buf; + /* We need to restore the signal mask, because otherwise the + signal-handling code will have blocked the caught signal and for + instance calling hurd_catch_signal again would then dump core. */ + sigjmp_buf buf; void throw (int signo, long int sigcode, struct sigcontext *scp) - { longjmp (buf, scp->sc_error ?: EGRATUITOUS); } + { siglongjmp (buf, scp->sc_error ?: EGRATUITOUS); } struct hurd_signal_preemptor preemptor = { @@ -40,12 +43,12 @@ hurd_catch_signal (sigset_t sigset, struct hurd_sigstate *const ss = _hurd_self_sigstate (); error_t error; - if (handler == SIG_ERR) + if (handler != SIG_ERR) /* Not our handler; don't bother saving state. */ error = 0; else /* This returns again with nonzero value when we preempt a signal. */ - error = setjmp (buf); + error = sigsetjmp (buf, 1); if (error == 0) { |