r5169 - in glibc-package/trunk/debian/patches: . hurd-i386
Author: sthibault
Date: 2012-02-21 01:58:20 +0000 (Tue, 21 Feb 2012)
New Revision: 5169
Added:
glibc-package/trunk/debian/patches/hurd-i386/local-hurdsig-global-dispositions-version.diff
glibc-package/trunk/debian/patches/hurd-i386/tg-hurdsig-SA_SIGINFO.diff
glibc-package/trunk/debian/patches/hurd-i386/tg-hurdsig-fixes-2.diff
glibc-package/trunk/debian/patches/hurd-i386/tg-hurdsig-fixes.diff
glibc-package/trunk/debian/patches/hurd-i386/tg-hurdsig-global-dispositions.diff
glibc-package/trunk/debian/patches/hurd-i386/tg-no-hp-timing.diff
Removed:
glibc-package/trunk/debian/patches/hurd-i386/submitted-hurdsig-SA_SIGINFO.diff
glibc-package/trunk/debian/patches/hurd-i386/submitted-hurdsig-fixes-2.diff
glibc-package/trunk/debian/patches/hurd-i386/submitted-hurdsig-fixes.diff
glibc-package/trunk/debian/patches/hurd-i386/submitted-hurdsig-global-dispositions.diff
glibc-package/trunk/debian/patches/hurd-i386/unsubmitted-no-hp-timing.diff
Modified:
glibc-package/trunk/debian/patches/series
Log:
patches/hurd-i386/{submitted,unsubmitted}-*: Rename to tg-* according to
integration in upstream tg repository.
Copied: glibc-package/trunk/debian/patches/hurd-i386/local-hurdsig-global-dispositions-version.diff (from rev 5168, glibc-package/trunk/debian/patches/hurd-i386/submitted-hurdsig-global-dispositions.diff)
===================================================================
--- glibc-package/trunk/debian/patches/hurd-i386/local-hurdsig-global-dispositions-version.diff (rev 0)
+++ glibc-package/trunk/debian/patches/hurd-i386/local-hurdsig-global-dispositions-version.diff 2012-02-21 01:58:20 UTC (rev 5169)
@@ -0,0 +1,35 @@
+jkoenig's work on signals
+
+This dates when the global signal disposition call was added.
+
+diff --git a/Versions.def b/Versions.def
+index 98c2800..d20b95c 100644
+--- a/Versions.def
++++ b/Versions.def
+@@ -39,6 +39,7 @@ libc {
+ GCC_3.0
+ %endif
+ GLIBC_PRIVATE
++ GLIBC_2.13_DEBIAN_19
+ }
+ libcrypt {
+ GLIBC_2.0
+diff --git a/hurd/Versions b/hurd/Versions
+index 83c8ab1..b697019 100644
+--- a/hurd/Versions
++++ b/hurd/Versions
+@@ -156,6 +156,14 @@ libc {
+ # functions used in macros & inline functions
+ __errno_location;
+ }
++ GLIBC_2.13_DEBIAN_19 {
++ # functions used by libpthread and <hurd/signal.h>
++ _hurd_sigstate_set_global_rcv;
++ _hurd_sigstate_lock;
++ _hurd_sigstate_pending;
++ _hurd_sigstate_unlock;
++ _hurd_sigstate_delete;
++ }
+
+ %if !SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
+ HURD_CTHREADS_0.3 {
Deleted: glibc-package/trunk/debian/patches/hurd-i386/submitted-hurdsig-SA_SIGINFO.diff
===================================================================
--- glibc-package/trunk/debian/patches/hurd-i386/submitted-hurdsig-SA_SIGINFO.diff 2012-02-20 19:22:27 UTC (rev 5168)
+++ glibc-package/trunk/debian/patches/hurd-i386/submitted-hurdsig-SA_SIGINFO.diff 2012-02-21 01:58:20 UTC (rev 5169)
@@ -1,535 +0,0 @@
-jkoenig's work on signals
-
-No topgit branch
-
-NOTE: this includes a merge of submitted-posix2008 fix for sigaction.h!
-
-diff --git a/hurd/hurd/signal.h b/hurd/hurd/signal.h
-index 1c4733a..cc96f21 100644
---- a/hurd/hurd/signal.h
-+++ b/hurd/hurd/signal.h
-@@ -264,6 +264,11 @@ extern void _hurd_raise_signal (struct hurd_sigstate *ss, int signo,
- extern void _hurd_exception2signal (struct hurd_signal_detail *detail,
- int *signo);
-
-+/* Translate a Mach exception into a signal with a legacy sigcode. */
-+
-+extern void _hurd_exception2signal_legacy (struct hurd_signal_detail *detail,
-+ int *signo);
-+
-
- /* Make the thread described by SS take the signal described by SIGNO and
- DETAIL. If the process is traced, this will in fact stop with a SIGNO
-diff --git a/hurd/hurdinit.c b/hurd/hurdinit.c
-index 259f8a3..97d3460 100644
---- a/hurd/hurdinit.c
-+++ b/hurd/hurdinit.c
-@@ -176,7 +176,7 @@ _hurd_new_proc_init (char **argv,
- /* This process is "traced", meaning it should stop on signals or exec.
- We are all set up now to handle signals. Stop ourselves, to inform
- our parent (presumably a debugger) that the exec has completed. */
-- __msg_sig_post (_hurd_msgport, SIGTRAP, 0, __mach_task_self ());
-+ __msg_sig_post (_hurd_msgport, SIGTRAP, TRAP_TRACE, __mach_task_self ());
- }
-
- #include <shlib-compat.h>
-diff --git a/sysdeps/mach/hurd/bits/sigaction.h b/sysdeps/mach/hurd/bits/sigaction.h
-new file mode 100644
-index 0000000..4528b38
---- /dev/null
-+++ b/sysdeps/mach/hurd/bits/sigaction.h
-@@ -0,0 +1,81 @@
-+/* Copyright (C) 1991,92,96,97,98,2001 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
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, write to the Free
-+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+ 02111-1307 USA. */
-+
-+#ifndef _SIGNAL_H
-+# error "Never include <bits/sigaction.h> directly; use <signal.h> instead."
-+#endif
-+
-+/* These definitions match those used by the 4.4 BSD kernel.
-+ If the operating system has a `sigaction' system call that correctly
-+ implements the POSIX.1 behavior, there should be a system-dependent
-+ version of this file that defines `struct sigaction' and the `SA_*'
-+ constants appropriately. */
-+
-+/* Structure describing the action to be taken when a signal arrives. */
-+struct sigaction
-+ {
-+ /* Signal handler. */
-+#ifdef __USE_POSIX199309
-+ union
-+ {
-+ /* Used if SA_SIGINFO is not set. */
-+ __sighandler_t sa_handler;
-+ /* Used if SA_SIGINFO is set. */
-+ void (*sa_sigaction) (int, siginfo_t *, void *);
-+ }
-+ __sigaction_handler;
-+# define sa_handler __sigaction_handler.sa_handler
-+# define sa_sigaction __sigaction_handler.sa_sigaction
-+#else
-+ __sighandler_t sa_handler;
-+#endif
-+
-+ /* Additional set of signals to be blocked. */
-+ __sigset_t sa_mask;
-+
-+ /* Special flags. */
-+ int sa_flags;
-+ };
-+
-+/* Bits in `sa_flags'. */
-+#if defined __USE_UNIX98 || defined __USE_MISC
-+# define SA_ONSTACK 0x0001 /* Take signal on signal stack. */
-+#endif
-+#if defined __USE_UNIX98 || defined __USE_MISC || defined __USE_XOPEN2K8
-+# define SA_RESTART 0x0002 /* Restart syscall on signal return. */
-+# define SA_NODEFER 0x0010 /* Don't automatically block the signal when
-+ its handler is being executed. */
-+# define SA_RESETHAND 0x0004 /* Reset to SIG_DFL on entry to handler. */
-+# define SA_SIGINFO 0x0040 /* Signal handler with SA_SIGINFO args */
-+#endif
-+#define SA_NOCLDSTOP 0x0008 /* Don't send SIGCHLD when children stop. */
-+
-+#ifdef __USE_MISC
-+# define SA_INTERRUPT 0 /* Historical no-op ("not SA_RESTART"). */
-+
-+/* Some aliases for the SA_ constants. */
-+# define SA_NOMASK SA_NODEFER
-+# define SA_ONESHOT SA_RESETHAND
-+# define SA_STACK SA_ONSTACK
-+#endif
-+
-+
-+/* Values for the HOW argument to `sigprocmask'. */
-+#define SIG_BLOCK 1 /* Block signals. */
-+#define SIG_UNBLOCK 2 /* Unblock signals. */
-+#define SIG_SETMASK 3 /* Set the set of blocked signals. */
-diff --git a/sysdeps/mach/hurd/i386/bits/sigcontext.h b/sysdeps/mach/hurd/i386/bits/sigcontext.h
-index a78dd2f..1956d41 100644
---- a/sysdeps/mach/hurd/i386/bits/sigcontext.h
-+++ b/sysdeps/mach/hurd/i386/bits/sigcontext.h
-@@ -96,6 +96,10 @@ struct sigcontext
- #define sc_ps sc_efl
-
-
-+/* The deprecated sigcode values below are passed as an extra, non-portable
-+ argument to regular signal handlers. You should use SA_SIGINFO handlers
-+ instead, which use the standard POSIX signal codes. */
-+
- /* Codes for SIGFPE. */
- #define FPE_INTOVF_TRAP 0x1 /* integer overflow */
- #define FPE_INTDIV_FAULT 0x2 /* integer divide by zero */
-diff --git a/sysdeps/mach/hurd/i386/exc2signal.c b/sysdeps/mach/hurd/i386/exc2signal.c
-index a6bf750..7ffeb5f 100644
---- a/sysdeps/mach/hurd/i386/exc2signal.c
-+++ b/sysdeps/mach/hurd/i386/exc2signal.c
-@@ -24,8 +24,8 @@
- /* Translate the Mach exception codes, as received in an `exception_raise' RPC,
- into a signal number and signal subcode. */
-
--void
--_hurd_exception2signal (struct hurd_signal_detail *detail, int *signo)
-+static void
-+exception2signal (struct hurd_signal_detail *detail, int *signo, int posix)
- {
- detail->error = 0;
-
-@@ -37,44 +37,62 @@ _hurd_exception2signal (struct hurd_signal_detail *detail, int *signo)
- break;
-
- case EXC_BAD_ACCESS:
-- if (detail->exc_code == KERN_INVALID_ADDRESS
-- || detail->exc_code == KERN_PROTECTION_FAILURE
-- || detail->exc_code == KERN_WRITE_PROTECTION_FAILURE)
-- *signo = SIGSEGV;
-- else
-- *signo = SIGBUS;
-- detail->code = detail->exc_subcode;
-+ switch (detail->exc_code)
-+ {
-+ case KERN_INVALID_ADDRESS:
-+ case KERN_MEMORY_FAILURE:
-+ *signo = SIGSEGV;
-+ detail->code = posix ? SEGV_MAPERR : detail->exc_subcode;
-+ break;
-+
-+ case KERN_PROTECTION_FAILURE:
-+ case KERN_WRITE_PROTECTION_FAILURE:
-+ *signo = SIGSEGV;
-+ detail->code = posix ? SEGV_ACCERR : detail->exc_subcode;
-+ break;
-+
-+ default:
-+ *signo = SIGBUS;
-+ detail->code = 0;
-+ break;
-+ }
- detail->error = detail->exc_code;
- break;
-
- case EXC_BAD_INSTRUCTION:
- *signo = SIGILL;
-- if (detail->exc_code == EXC_I386_INVOP)
-- detail->code = ILL_INVOPR_FAULT;
-- else if (detail->exc_code == EXC_I386_STKFLT)
-- detail->code = ILL_STACK_FAULT;
-- else
-- detail->code = 0;
-+ switch (detail->exc_code)
-+ {
-+ case EXC_I386_INVOP:
-+ detail->code = posix ? ILL_ILLOPC : ILL_INVOPR_FAULT;
-+ break;
-+
-+ case EXC_I386_STKFLT:
-+ detail->code = posix ? ILL_BADSTK : ILL_STACK_FAULT;
-+ break;
-+
-+ default:
-+ detail->code = 0;
-+ break;
-+ }
- break;
-
- case EXC_ARITHMETIC:
-+ *signo = SIGFPE;
- switch (detail->exc_code)
- {
- case EXC_I386_DIV: /* integer divide by zero */
-- *signo = SIGFPE;
-- detail->code = FPE_INTDIV_FAULT;
-+ detail->code = posix ? FPE_INTDIV : FPE_INTDIV_FAULT;
- break;
-
- case EXC_I386_INTO: /* integer overflow */
-- *signo = SIGFPE;
-- detail->code = FPE_INTOVF_TRAP;
-+ detail->code = posix ? FPE_INTOVF : FPE_INTOVF_TRAP;
- break;
-
- /* These aren't anywhere documented or used in Mach 3.0. */
- case EXC_I386_NOEXT:
- case EXC_I386_EXTOVR:
- default:
-- *signo = SIGFPE;
- detail->code = 0;
- break;
-
-@@ -83,51 +101,43 @@ _hurd_exception2signal (struct hurd_signal_detail *detail, int *signo)
- Give an error code corresponding to the first bit set. */
- if (detail->exc_subcode & FPS_IE)
- {
-- *signo = SIGILL;
-- detail->code = ILL_FPEOPR_FAULT;
-+ /* NB: We used to send SIGILL here but we can't distinguish
-+ POSIX vs. legacy with respect to what signal we send. */
-+ detail->code = posix ? FPE_FLTINV : 0 /*ILL_FPEOPR_FAULT*/;
- }
- else if (detail->exc_subcode & FPS_DE)
- {
-- *signo = SIGFPE;
-- detail->code = FPE_FLTDNR_FAULT;
-+ detail->code = posix ? FPE_FLTUND : FPE_FLTDNR_FAULT;
- }
- else if (detail->exc_subcode & FPS_ZE)
- {
-- *signo = SIGFPE;
-- detail->code = FPE_FLTDIV_FAULT;
-+ detail->code = posix ? FPE_FLTDIV : FPE_FLTDIV_FAULT;
- }
- else if (detail->exc_subcode & FPS_OE)
- {
-- *signo = SIGFPE;
-- detail->code = FPE_FLTOVF_FAULT;
-+ detail->code = posix ? FPE_FLTOVF : FPE_FLTOVF_FAULT;
- }
- else if (detail->exc_subcode & FPS_UE)
- {
-- *signo = SIGFPE;
-- detail->code = FPE_FLTUND_FAULT;
-+ detail->code = posix ? FPE_FLTUND : FPE_FLTUND_FAULT;
- }
- else if (detail->exc_subcode & FPS_PE)
- {
-- *signo = SIGFPE;
-- detail->code = FPE_FLTINX_FAULT;
-+ detail->code = posix ? FPE_FLTRES : FPE_FLTINX_FAULT;
- }
- else
- {
-- *signo = SIGFPE;
- detail->code = 0;
- }
- break;
-
- /* These two can only be arithmetic exceptions if we
-- are in V86 mode, which sounds like emulation to me.
-- (See Mach 3.0 i386/trap.c.) */
-+ are in V86 mode. (See Mach 3.0 i386/trap.c.) */
- case EXC_I386_EMERR:
-- *signo = SIGFPE;
-- detail->code = FPE_EMERR_FAULT;
-+ detail->code = posix ? 0 : FPE_EMERR_FAULT;
- break;
- case EXC_I386_BOUND:
-- *signo = SIGFPE;
-- detail->code = FPE_EMBND_FAULT;
-+ detail->code = posix ? FPE_FLTSUB : FPE_EMBND_FAULT;
- break;
- }
- break;
-@@ -144,7 +154,7 @@ _hurd_exception2signal (struct hurd_signal_detail *detail, int *signo)
- if (detail->exc_code == EXC_I386_BOUND)
- {
- *signo = SIGFPE;
-- detail->code = FPE_SUBRNG_FAULT;
-+ detail->code = posix ? FPE_FLTSUB : FPE_SUBRNG_FAULT;
- }
- else
- {
-@@ -155,12 +165,33 @@ _hurd_exception2signal (struct hurd_signal_detail *detail, int *signo)
-
- case EXC_BREAKPOINT:
- *signo = SIGTRAP;
-- if (detail->exc_code == EXC_I386_SGL)
-- detail->code = DBG_SINGLE_TRAP;
-- else if (detail->exc_code == EXC_I386_BPT)
-- detail->code = DBG_BRKPNT_FAULT;
-- else
-- detail->code = 0;
-+ switch (detail->exc_code)
-+ {
-+ case EXC_I386_SGL:
-+ detail->code = posix ? TRAP_BRKPT : DBG_SINGLE_TRAP;
-+ break;
-+
-+ case EXC_I386_BPT:
-+ detail->code = posix ? TRAP_BRKPT : DBG_BRKPNT_FAULT;
-+ break;
-+
-+ default:
-+ detail->code = 0;
-+ break;
-+ }
- break;
- }
- }
-+
-+void
-+_hurd_exception2signal (struct hurd_signal_detail *detail, int *signo)
-+{
-+ exception2signal (detail, signo, 1);
-+}
-+
-+void
-+_hurd_exception2signal_legacy (struct hurd_signal_detail *detail, int *signo)
-+{
-+ exception2signal (detail, signo, 0);
-+}
-+
-diff --git a/sysdeps/mach/hurd/i386/trampoline.c b/sysdeps/mach/hurd/i386/trampoline.c
-index ec52847..5abd33d 100644
---- a/sysdeps/mach/hurd/i386/trampoline.c
-+++ b/sysdeps/mach/hurd/i386/trampoline.c
-@@ -21,13 +21,66 @@
- #include <hurd/signal.h>
- #include <hurd/userlink.h>
- #include <thread_state.h>
-+#include <mach/exception.h>
- #include <mach/machine/eflags.h>
- #include <assert.h>
- #include <errno.h>
- #include "hurdfault.h"
- #include <intr-msg.h>
-+#include <sys/ucontext.h>
-
-
-+/* Fill in a siginfo_t structure for SA_SIGINFO-enabled handlers. */
-+static void fill_siginfo (siginfo_t *si, int signo,
-+ const struct hurd_signal_detail *detail,
-+ const struct machine_thread_all_state *state)
-+{
-+ si->si_signo = signo;
-+ si->si_errno = detail->error;
-+ si->si_code = detail->code;
-+
-+ /* XXX We would need a protocol change for sig_post to include
-+ * this information. */
-+ si->si_pid = -1;
-+ si->si_uid = -1;
-+
-+ /* Address of the faulting instruction or memory access. */
-+ if (detail->exc == EXC_BAD_ACCESS)
-+ si->si_addr = (void *) detail->exc_subcode;
-+ else
-+ si->si_addr = (void *) state->basic.eip;
-+
-+ /* XXX On SIGCHLD, this should be the exit status of the child
-+ * process. We would need a protocol change for the proc server
-+ * to send this information along with the signal. */
-+ si->si_status = 0;
-+
-+ si->si_band = 0; /* SIGPOLL is not supported yet. */
-+ si->si_value.sival_int = 0; /* sigqueue() is not supported yet. */
-+}
-+
-+/* Fill in a ucontext_t structure SA_SIGINFO-enabled handlers. */
-+static void fill_ucontext (ucontext_t *uc, const struct sigcontext *sc)
-+{
-+ uc->uc_flags = 0;
-+ uc->uc_link = NULL;
-+ uc->uc_sigmask = sc->sc_mask;
-+ uc->uc_stack.ss_sp = (__ptr_t) sc->sc_esp;
-+ uc->uc_stack.ss_size = 0;
-+ uc->uc_stack.ss_flags = 0;
-+
-+ /* Registers. */
-+ memcpy (&uc->uc_mcontext.gregs[REG_GS], &sc->sc_gs,
-+ (REG_TRAPNO - REG_GS) * sizeof (int));
-+ uc->uc_mcontext.gregs[REG_TRAPNO] = 0;
-+ uc->uc_mcontext.gregs[REG_ERR] = 0;
-+ memcpy (&uc->uc_mcontext.gregs[REG_EIP], &sc->sc_eip,
-+ (NGREG - REG_EIP) * sizeof (int));
-+
-+ /* XXX FPU state. */
-+ memset (&uc->uc_mcontext.fpregs, 0, sizeof (fpregset_t));
-+}
-+
- struct sigcontext *
- _hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
- int signo, struct hurd_signal_detail *detail,
-@@ -40,18 +93,37 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
- extern const void _hurd_intr_rpc_msg_in_trap;
- extern const void _hurd_intr_rpc_msg_cx_sp;
- extern const void _hurd_intr_rpc_msg_sp_restored;
-+ struct sigaction *action;
- void *volatile sigsp;
- struct sigcontext *scp;
- struct
- {
- int signo;
-- long int sigcode;
-- struct sigcontext *scp; /* Points to ctx, below. */
-+ union
-+ {
-+ /* Extra arguments for traditional signal handlers */
-+ struct
-+ {
-+ long int sigcode;
-+ struct sigcontext *scp; /* Points to ctx, below. */
-+ } legacy;
-+
-+ /* Extra arguments for SA_SIGINFO handlers */
-+ struct
-+ {
-+ siginfo_t *siginfop; /* Points to siginfo, below. */
-+ ucontext_t *uctxp; /* Points to uctx, below. */
-+ } posix;
-+ };
- void *sigreturn_addr;
- void *sigreturn_returns_here;
- struct sigcontext *return_scp; /* Same; arg to sigreturn. */
-+
-+ /* NB: sigreturn assumes link is next to ctx. */
- struct sigcontext ctx;
- struct hurd_userlink link;
-+ ucontext_t ucontext;
-+ siginfo_t siginfo;
- } *stackframe;
-
- if (ss->context)
-@@ -143,15 +215,9 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
- = &stackframe->link.thread.next;
- ss->active_resources = &stackframe->link;
-
-- /* Set up the arguments for the signal handler. */
-- stackframe->signo = signo;
-- stackframe->sigcode = detail->code;
-- stackframe->scp = stackframe->return_scp = scp = &stackframe->ctx;
-- stackframe->sigreturn_addr = &__sigreturn;
-- stackframe->sigreturn_returns_here = firewall; /* Crash on return. */
--
- /* Set up the sigcontext from the current state of the thread. */
-
-+ scp = &stackframe->ctx;
- scp->sc_onstack = ss->sigaltstack.ss_flags & SS_ONSTACK ? 1 : 0;
-
- /* struct sigcontext is laid out so that starting at sc_gs mimics a
-@@ -165,6 +231,35 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
- &state->fpu, &scp->sc_i386_float_state,
- sizeof (state->fpu));
-
-+ /* Set up the arguments for the signal handler. */
-+ stackframe->signo = signo;
-+ if (action->sa_flags & SA_SIGINFO)
-+ {
-+ stackframe->posix.siginfop = &stackframe->siginfo;
-+ stackframe->posix.uctxp = &stackframe->ucontext;
-+ fill_siginfo (&stackframe->siginfo, signo, detail, state);
-+ fill_ucontext (&stackframe->ucontext, scp);
-+ }
-+ else
-+ {
-+ if (detail->exc)
-+ {
-+ int nsigno;
-+ _hurd_exception2signal_legacy (detail, &nsigno);
-+ assert (nsigno == signo);
-+ }
-+ else
-+ detail->code = 0;
-+
-+ stackframe->legacy.sigcode = detail->code;
-+ stackframe->legacy.scp = &stackframe->ctx;
-+ }
-+
-+ /* Set up the bottom of the stack. */
-+ stackframe->sigreturn_addr = &__sigreturn;
-+ stackframe->sigreturn_returns_here = firewall; /* Crash on return. */
-+ stackframe->return_scp = &stackframe->ctx;
-+
- _hurdsig_end_catch_fault ();
-
- if (! ok)
-diff --git a/sysdeps/mach/hurd/kill.c b/sysdeps/mach/hurd/kill.c
-index a9946e0..ac7ffc7 100644
---- a/sysdeps/mach/hurd/kill.c
-+++ b/sysdeps/mach/hurd/kill.c
-@@ -65,7 +65,7 @@ __kill (pid_t pid, int sig)
- {
- if (msgport != MACH_PORT_NULL)
- /* Send a signal message to his message port. */
-- return __msg_sig_post (msgport, sig, 0, refport);
-+ return __msg_sig_post (msgport, sig, SI_USER, refport);
-
- /* The process has no message port. Perhaps try direct
- frobnication of the task. */
-diff --git a/sysdeps/mach/hurd/setitimer.c b/sysdeps/mach/hurd/setitimer.c
-index fec64a8..c82bfcd 100644
---- a/sysdeps/mach/hurd/setitimer.c
-+++ b/sysdeps/mach/hurd/setitimer.c
-@@ -105,7 +105,7 @@ timer_thread (void)
- __msg_sig_post_request (_hurd_msgport,
- _hurd_itimer_port,
- MACH_MSG_TYPE_MAKE_SEND_ONCE,
-- SIGALRM, 0, __mach_task_self ());
-+ SIGALRM, SI_TIMER, __mach_task_self ());
- break;
-
- case MACH_RCV_INTERRUPTED:
Deleted: glibc-package/trunk/debian/patches/hurd-i386/submitted-hurdsig-fixes-2.diff
===================================================================
--- glibc-package/trunk/debian/patches/hurd-i386/submitted-hurdsig-fixes-2.diff 2012-02-20 19:22:27 UTC (rev 5168)
+++ glibc-package/trunk/debian/patches/hurd-i386/submitted-hurdsig-fixes-2.diff 2012-02-21 01:58:20 UTC (rev 5169)
@@ -1,48 +0,0 @@
-jkoenig's work on signals
-
-No topgit branch
-
-diff --git a/hurd/hurdsig.c b/hurd/hurdsig.c
-index 67037e8..44e067c 100644
---- a/hurd/hurdsig.c
-+++ b/hurd/hurdsig.c
-@@ -859,9 +859,7 @@ post_signal (struct hurd_sigstate *ss,
- }
-
- /* Handle receipt of a blocked signal, or any signal while stopped. */
-- if (act != ignore && /* Signals ignored now are forgotten now. */
-- __sigismember (&blocked, signo) ||
-- (signo != SIGKILL && _hurd_stopped))
-+ if (__sigismember (&blocked, signo) || (signo != SIGKILL && _hurd_stopped))
- {
- mark_pending ();
- act = ignore;
-diff --git a/sysdeps/mach/hurd/fork.c b/sysdeps/mach/hurd/fork.c
-index a4f3055..c74998d 100644
---- a/sysdeps/mach/hurd/fork.c
-+++ b/sysdeps/mach/hurd/fork.c
-@@ -648,8 +648,10 @@ __fork (void)
- err = __USEPORT (PROC, __proc_getpids (port, &_hurd_pid, &_hurd_ppid,
- &_hurd_orphaned));
-
-- /* Forking clears the trace flag. */
-+ /* Forking clears the trace flag and pending masks. */
- __sigemptyset (&_hurdsig_traced);
-+ __sigemptyset (&_hurd_global_sigstate->pending);
-+ __sigemptyset (&ss->pending);
-
- /* Run things that want to run in the child task to set up. */
- RUN_HOOK (_hurd_fork_child_hook, ());
-diff --git a/sysdeps/mach/hurd/spawni.c b/sysdeps/mach/hurd/spawni.c
-index 373da8d..2442e6f 100644
---- a/sysdeps/mach/hurd/spawni.c
-+++ b/sysdeps/mach/hurd/spawni.c
-@@ -241,7 +241,7 @@ __spawni (pid_t *pid, const char *file,
-
- _hurd_sigstate_lock (ss);
- ints[INIT_SIGMASK] = ss->blocked;
-- ints[INIT_SIGPENDING] = _hurd_sigstate_pending (ss); /* XXX really? */
-+ ints[INIT_SIGPENDING] = 0;
- ints[INIT_SIGIGN] = 0;
- /* Unless we were asked to reset all handlers to SIG_DFL,
- pass down the set of signals that were set to SIG_IGN. */
Deleted: glibc-package/trunk/debian/patches/hurd-i386/submitted-hurdsig-fixes.diff
===================================================================
--- glibc-package/trunk/debian/patches/hurd-i386/submitted-hurdsig-fixes.diff 2012-02-20 19:22:27 UTC (rev 5168)
+++ glibc-package/trunk/debian/patches/hurd-i386/submitted-hurdsig-fixes.diff 2012-02-21 01:58:20 UTC (rev 5169)
@@ -1,356 +0,0 @@
-jkoenig's work on signals
-
-No topgit branch
-
-diff --git a/hurd/hurdsig.c b/hurd/hurdsig.c
-index 7a6b1d5..74a01a6 100644
---- a/hurd/hurdsig.c
-+++ b/hurd/hurdsig.c
-@@ -1,4 +1,4 @@
--/* Copyright (C) 1991,92,93,94,95,96,97,98,99,2000,2001,2002,2005,2008
-+/* Copyright (C) 1991,92,93,94,95,96,97,98,99,2000,2001,2002,2005,2008,2011
- Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
-@@ -443,6 +443,30 @@ abort_all_rpcs (int signo, struct machine_thread_all_state *state, int live)
- }
- }
-
-+/* Wake up any sigsuspend call that is blocking SS->thread. SS must be
-+ locked. */
-+static void
-+wake_sigsuspend (struct hurd_sigstate *ss)
-+{
-+ error_t err;
-+ mach_msg_header_t msg;
-+
-+ if (ss->suspended == MACH_PORT_NULL)
-+ return;
-+
-+ /* There is a sigsuspend waiting. Tell it to wake up. */
-+ msg.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_MAKE_SEND, 0);
-+ msg.msgh_remote_port = ss->suspended;
-+ msg.msgh_local_port = MACH_PORT_NULL;
-+ /* These values do not matter. */
-+ msg.msgh_id = 8675309; /* Jenny, Jenny. */
-+ ss->suspended = MACH_PORT_NULL;
-+ err = __mach_msg (&msg, MACH_SEND_MSG, sizeof msg, 0,
-+ MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE,
-+ MACH_PORT_NULL);
-+ assert_perror (err);
-+}
-+
- struct hurd_signal_preemptor *_hurdsig_preemptors = 0;
- sigset_t _hurdsig_preempted_set;
-
-@@ -453,35 +477,18 @@ weak_alias (_hurdsig_preemptors, _hurdsig_preempters)
- #define STOPSIGS (sigmask (SIGTTIN) | sigmask (SIGTTOU) | \
- sigmask (SIGSTOP) | sigmask (SIGTSTP))
-
--/* Deliver a signal. SS is not locked. */
--void
--_hurd_internal_post_signal (struct hurd_sigstate *ss,
-- int signo, struct hurd_signal_detail *detail,
-- mach_port_t reply_port,
-- mach_msg_type_name_t reply_port_type,
-- int untraced)
-+/* Actual delivery of a single signal. Called with SS unlocked. When
-+ the signal is delivered, return 1 with SS locked. If the signal is
-+ being traced, return 0 with SS unlocked. */
-+static int
-+post_signal (struct hurd_sigstate *ss,
-+ int signo, struct hurd_signal_detail *detail,
-+ int untraced, void (*reply) (void))
- {
-- error_t err;
- struct machine_thread_all_state thread_state;
- enum { stop, ignore, core, term, handle } act;
-- sighandler_t handler;
-- sigset_t pending;
- int ss_suspended;
-
-- /* Reply to this sig_post message. */
-- __typeof (__msg_sig_post_reply) *reply_rpc
-- = (untraced ? __msg_sig_post_untraced_reply : __msg_sig_post_reply);
-- void reply (void)
-- {
-- error_t err;
-- if (reply_port == MACH_PORT_NULL)
-- return;
-- err = (*reply_rpc) (reply_port, reply_port_type, 0);
-- reply_port = MACH_PORT_NULL;
-- if (err != MACH_SEND_INVALID_DEST) /* Ignore dead reply port. */
-- assert_perror (err);
-- }
--
- /* Mark the signal as pending. */
- void mark_pending (void)
- {
-@@ -545,19 +552,23 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
- ss_suspended = 1;
- }
-
-+ error_t err;
-+ sighandler_t handler;
-+
- if (signo == 0)
- {
- if (untraced)
-- /* This is PTRACE_CONTINUE. */
-- resume ();
-+ {
-+ /* This is PTRACE_CONTINUE. */
-+ act = ignore;
-+ resume ();
-+ }
-
- /* This call is just to check for pending signals. */
- __spin_lock (&ss->lock);
-- goto check_pending_signals;
-+ return 1;
- }
-
-- post_signal:
--
- thread_state.set = 0; /* We know nothing. */
-
- __spin_lock (&ss->lock);
-@@ -620,7 +631,7 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
- suspend ();
- __spin_unlock (&ss->lock);
- reply ();
-- return;
-+ return 0;
- }
-
- handler = ss->actions[signo].sa_handler;
-@@ -863,7 +874,7 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
- as a unit. */
- crit ? 0 : signo, 1,
- &thread_state, &state_changed,
-- &reply)
-+ reply)
- != MACH_PORT_NULL);
-
- if (crit)
-@@ -949,6 +960,9 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
- && signo != SIGILL && signo != SIGTRAP)
- ss->actions[signo].sa_handler = SIG_DFL;
-
-+ /* Any sigsuspend call must return after the handler does. */
-+ wake_sigsuspend (ss);
-+
- /* Start the thread running the handler (or possibly waiting for an
- RPC reply before running the handler). */
- err = __thread_set_state (ss->thread, MACHINE_THREAD_STATE_FLAVOR,
-@@ -962,95 +976,129 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
- }
- }
-
-- /* The signal has either been ignored or is now being handled. We can
-- consider it delivered and reply to the killer. */
-- reply ();
-+ return 1;
-+}
-
-- /* We get here unless the signal was fatal. We still hold SS->lock.
-- Check for pending signals, and loop to post them. */
-- {
-- /* Return nonzero if SS has any signals pending we should worry about.
-- We don't worry about any pending signals if we are stopped, nor if
-- SS is in a critical section. We are guaranteed to get a sig_post
-- message before any of them become deliverable: either the SIGCONT
-- signal, or a sig_post with SIGNO==0 as an explicit poll when the
-- thread finishes its critical section. */
-- inline int signals_pending (void)
-- {
-- if (_hurd_stopped || __spin_lock_locked (&ss->critical_section_lock))
-- return 0;
-- return pending = ss->pending & ~ss->blocked;
-- }
-+/* Return the set of pending signals in SS which should be delivered. */
-+static sigset_t
-+pending_signals (struct hurd_sigstate *ss)
-+{
-+ /* We don't worry about any pending signals if we are stopped, nor if
-+ SS is in a critical section. We are guaranteed to get a sig_post
-+ message before any of them become deliverable: either the SIGCONT
-+ signal, or a sig_post with SIGNO==0 as an explicit poll when the
-+ thread finishes its critical section. */
-+ if (_hurd_stopped || __spin_lock_locked (&ss->critical_section_lock))
-+ return 0;
-
-- check_pending_signals:
-- untraced = 0;
-+ return ss->pending & ~ss->blocked;
-+}
-
-- if (signals_pending ())
-- {
-- for (signo = 1; signo < NSIG; ++signo)
-- if (__sigismember (&pending, signo))
-- {
-- deliver_pending:
-- __sigdelset (&ss->pending, signo);
-- *detail = ss->pending_data[signo];
-- __spin_unlock (&ss->lock);
-- goto post_signal;
-- }
-- }
-+/* Post the specified pending signals in SS and return 1. If one of
-+ them is traced, abort immediately and return 0. SS must be locked on
-+ entry and will be unlocked in all cases. */
-+static int
-+post_pending (struct hurd_sigstate *ss, sigset_t pending, void (*reply) (void))
-+{
-+ int signo;
-+ struct hurd_signal_detail detail;
-
-- /* No pending signals left undelivered for this thread.
-- If we were sent signal 0, we need to check for pending
-- signals for all threads. */
-- if (signo == 0)
-- {
-- __spin_unlock (&ss->lock);
-- __mutex_lock (&_hurd_siglock);
-- for (ss = _hurd_sigstates; ss != NULL; ss = ss->next)
-- {
-- __spin_lock (&ss->lock);
-- for (signo = 1; signo < NSIG; ++signo)
-- if (__sigismember (&ss->pending, signo)
-- && (!__sigismember (&ss->blocked, signo)
-- /* We "deliver" immediately pending blocked signals whose
-- action might be to ignore, so that if ignored they are
-- dropped right away. */
-- || ss->actions[signo].sa_handler == SIG_IGN
-- || ss->actions[signo].sa_handler == SIG_DFL))
-- {
-- mutex_unlock (&_hurd_siglock);
-- goto deliver_pending;
-- }
-- __spin_unlock (&ss->lock);
-- }
-- __mutex_unlock (&_hurd_siglock);
-- }
-- else
-+ for (signo = 1; signo < NSIG; ++signo)
-+ if (__sigismember (&pending, signo))
- {
-- /* No more signals pending; SS->lock is still locked.
-- Wake up any sigsuspend call that is blocking SS->thread. */
-- if (ss->suspended != MACH_PORT_NULL)
-- {
-- /* There is a sigsuspend waiting. Tell it to wake up. */
-- error_t err;
-- mach_msg_header_t msg;
-- msg.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_MAKE_SEND, 0);
-- msg.msgh_remote_port = ss->suspended;
-- msg.msgh_local_port = MACH_PORT_NULL;
-- /* These values do not matter. */
-- msg.msgh_id = 8675309; /* Jenny, Jenny. */
-- ss->suspended = MACH_PORT_NULL;
-- err = __mach_msg (&msg, MACH_SEND_MSG, sizeof msg, 0,
-- MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE,
-- MACH_PORT_NULL);
-- assert_perror (err);
-- }
-+ __sigdelset (&ss->pending, signo);
-+ detail = ss->pending_data[signo];
- __spin_unlock (&ss->lock);
-+
-+ /* Will reacquire the lock, except if the signal is traced. */
-+ if (! post_signal (ss, signo, &detail, 0, reply))
-+ return 0;
- }
-- }
-
-- /* All pending signals delivered to all threads.
-- Now we can send the reply message even for signal 0. */
-- reply ();
-+ /* No more signals pending; SS->lock is still locked. */
-+ __spin_unlock (&ss->lock);
-+
-+ return 1;
-+}
-+
-+/* Post all the pending signals of all threads and return 1. If a traced
-+ signal is encountered, abort immediately and return 0. */
-+static int
-+post_all_pending_signals (void (*reply) (void))
-+{
-+ struct hurd_sigstate *ss;
-+ sigset_t pending;
-+
-+ for (;;)
-+ {
-+ __mutex_lock (&_hurd_siglock);
-+ for (ss = _hurd_sigstates; ss != NULL; ss = ss->next)
-+ {
-+ __spin_lock (&ss->lock);
-+
-+ pending = pending_signals (ss);
-+ if (pending)
-+ /* post_pending() below will unlock SS. */
-+ break;
-+
-+ __spin_unlock (&ss->lock);
-+ }
-+ __mutex_unlock (&_hurd_siglock);
-+
-+ if (! pending)
-+ return 1;
-+ if (! post_pending (ss, pending, reply))
-+ return 0;
-+ }
-+}
-+
-+/* Deliver a signal. SS is not locked. */
-+void
-+_hurd_internal_post_signal (struct hurd_sigstate *ss,
-+ int signo, struct hurd_signal_detail *detail,
-+ mach_port_t reply_port,
-+ mach_msg_type_name_t reply_port_type,
-+ int untraced)
-+{
-+ /* Reply to this sig_post message. */
-+ __typeof (__msg_sig_post_reply) *reply_rpc
-+ = (untraced ? __msg_sig_post_untraced_reply : __msg_sig_post_reply);
-+ void reply (void)
-+ {
-+ error_t err;
-+ if (reply_port == MACH_PORT_NULL)
-+ return;
-+ err = (*reply_rpc) (reply_port, reply_port_type, 0);
-+ reply_port = MACH_PORT_NULL;
-+ if (err != MACH_SEND_INVALID_DEST) /* Ignore dead reply port. */
-+ assert_perror (err);
-+ }
-+
-+ if (! post_signal (ss, signo, detail, untraced, reply))
-+ return;
-+
-+ /* The signal was neither fatal nor traced. We still hold SS->lock. */
-+ if (signo != 0)
-+ {
-+ /* The signal has either been ignored or is now being handled. We can
-+ consider it delivered and reply to the killer. */
-+ reply ();
-+
-+ /* Post any pending signals for this thread. */
-+ if (! post_pending (ss, pending_signals (ss), reply))
-+ return;
-+ }
-+ else
-+ {
-+ /* We need to check for pending signals for all threads. */
-+ __spin_unlock (&ss->lock);
-+ if (! post_all_pending_signals (reply))
-+ return;
-+
-+ /* All pending signals delivered to all threads.
-+ Now we can send the reply message even for signal 0. */
-+ reply ();
-+ }
- }
-
- /* Decide whether REFPORT enables the sender to send us a SIGNO signal.
Deleted: glibc-package/trunk/debian/patches/hurd-i386/submitted-hurdsig-global-dispositions.diff
===================================================================
--- glibc-package/trunk/debian/patches/hurd-i386/submitted-hurdsig-global-dispositions.diff 2012-02-20 19:22:27 UTC (rev 5168)
+++ glibc-package/trunk/debian/patches/hurd-i386/submitted-hurdsig-global-dispositions.diff 2012-02-21 01:58:20 UTC (rev 5169)
@@ -1,1236 +0,0 @@
-jkoenig's work on signals
-
-No topgit branch
-
-diff --git a/Versions.def b/Versions.def
-index 98c2800..d20b95c 100644
---- a/Versions.def
-+++ b/Versions.def
-@@ -39,6 +39,7 @@ libc {
- GCC_3.0
- %endif
- GLIBC_PRIVATE
-+ GLIBC_2.13_DEBIAN_19
- }
- libcrypt {
- GLIBC_2.0
-diff --git a/hurd/Versions b/hurd/Versions
-index 83c8ab1..b697019 100644
---- a/hurd/Versions
-+++ b/hurd/Versions
-@@ -156,6 +156,14 @@ libc {
- # functions used in macros & inline functions
- __errno_location;
- }
-+ GLIBC_2.13_DEBIAN_19 {
-+ # functions used by libpthread and <hurd/signal.h>
-+ _hurd_sigstate_set_global_rcv;
-+ _hurd_sigstate_lock;
-+ _hurd_sigstate_pending;
-+ _hurd_sigstate_unlock;
-+ _hurd_sigstate_delete;
-+ }
-
- %if !SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
- HURD_CTHREADS_0.3 {
-diff --git a/hurd/ctty-input.c b/hurd/ctty-input.c
-index ef8395a..4da33c7 100644
---- a/hurd/ctty-input.c
-+++ b/hurd/ctty-input.c
-@@ -1,5 +1,5 @@
- /* _hurd_ctty_input -- Do an input RPC and generate SIGTTIN if necessary.
-- Copyright (C) 1995,97,99 Free Software Foundation, Inc.
-+ Copyright (C) 1995,97,99,2011 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
-@@ -44,12 +44,15 @@ _hurd_ctty_input (io_t port, io_t ctty, error_t (*rpc) (io_t))
- else
- {
- struct hurd_sigstate *ss = _hurd_self_sigstate ();
-- __spin_lock (&ss->lock);
-+ struct sigaction *actions;
-+
-+ _hurd_sigstate_lock (ss);
-+ actions = _hurd_sigstate_actions (ss);
- if (__sigismember (&ss->blocked, SIGTTIN) ||
-- ss->actions[SIGTTIN].sa_handler == SIG_IGN)
-+ actions[SIGTTIN].sa_handler == SIG_IGN)
- /* We are blocking or ignoring SIGTTIN. Just fail. */
- err = EIO;
-- __spin_unlock (&ss->lock);
-+ _hurd_sigstate_unlock (ss);
-
- if (err == EBACKGROUND)
- {
-@@ -66,10 +69,11 @@ _hurd_ctty_input (io_t port, io_t ctty, error_t (*rpc) (io_t))
- SIGTTIN or resumed after being stopped. Now this is
- still a "system call", so check to see if we should
- restart it. */
-- __spin_lock (&ss->lock);
-- if (!(ss->actions[SIGTTIN].sa_flags & SA_RESTART))
-+ _hurd_sigstate_lock (ss);
-+ actions = _hurd_sigstate_actions (ss);
-+ if (!(actions[SIGTTIN].sa_flags & SA_RESTART))
- err = EINTR;
-- __spin_unlock (&ss->lock);
-+ _hurd_sigstate_unlock (ss);
- }
- }
- }
-diff --git a/hurd/ctty-output.c b/hurd/ctty-output.c
-index 92ab95a..6e4bd74 100644
---- a/hurd/ctty-output.c
-+++ b/hurd/ctty-output.c
-@@ -1,5 +1,5 @@
- /* _hurd_ctty_output -- Do an output RPC and generate SIGTTOU if necessary.
-- Copyright (C) 1995,97,99 Free Software Foundation, Inc.
-+ Copyright (C) 1995,97,99,2011 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
-@@ -35,16 +35,19 @@ _hurd_ctty_output (io_t port, io_t ctty, error_t (*rpc) (io_t))
-
- do
- {
-+ struct sigaction *actions;
-+
- /* Don't use the ctty io port if we are blocking or ignoring
- SIGTTOU. We redo this check at the top of the loop in case
- the signal handler changed the state. */
-- __spin_lock (&ss->lock);
-+ _hurd_sigstate_lock (ss);
-+ actions = _hurd_sigstate_actions (ss);
- if (__sigismember (&ss->blocked, SIGTTOU) ||
-- ss->actions[SIGTTOU].sa_handler == SIG_IGN)
-+ actions[SIGTTOU].sa_handler == SIG_IGN)
- err = EIO;
- else
- err = 0;
-- __spin_unlock (&ss->lock);
-+ _hurd_sigstate_unlock (ss);
-
- if (err)
- return (*rpc) (port);
-@@ -71,10 +74,11 @@ _hurd_ctty_output (io_t port, io_t ctty, error_t (*rpc) (io_t))
- SIGTTOU or resumed after being stopped. Now this is
- still a "system call", so check to see if we should
- restart it. */
-- __spin_lock (&ss->lock);
-- if (!(ss->actions[SIGTTOU].sa_flags & SA_RESTART))
-+ _hurd_sigstate_lock (ss);
-+ actions = _hurd_sigstate_actions (ss);
-+ if (!(actions[SIGTTOU].sa_flags & SA_RESTART))
- err = EINTR;
-- __spin_unlock (&ss->lock);
-+ _hurd_sigstate_unlock (ss);
- }
- }
- /* If the last RPC generated a SIGTTOU, loop to try it again. */
-diff --git a/hurd/hurd/signal.h b/hurd/hurd/signal.h
-index 21e30c5..1c4733a 100644
---- a/hurd/hurd/signal.h
-+++ b/hurd/hurd/signal.h
-@@ -1,5 +1,5 @@
- /* Implementing POSIX.1 signals under the Hurd.
-- Copyright (C) 1993,94,95,96,98,99,2002,2007,2008
-+ Copyright (C) 1993,94,95,96,98,99,2002,2007,2008,2011
- Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
-@@ -71,7 +71,13 @@ struct hurd_sigstate
-
- sigset_t blocked; /* What signals are blocked. */
- sigset_t pending; /* Pending signals, possibly blocked. */
-+
-+ /* Signal handlers. ACTIONS[0] is used to mark the threads with POSIX
-+ semantics: if sa_handler is SIG_IGN instead of SIG_DFL, this thread
-+ will receive global signals and use the process-wide action vector
-+ instead of this one. */
- struct sigaction actions[NSIG];
-+
- struct sigaltstack sigaltstack;
-
- /* Chain of thread-local signal preemptors; see <hurd/sigpreempt.h>.
-@@ -127,6 +133,26 @@ extern struct hurd_sigstate *_hurd_self_sigstate (void)
- by different threads. */
- __attribute__ ((__const__));
-
-+/* Process-wide signal state. */
-+
-+extern struct hurd_sigstate *_hurd_global_sigstate;
-+
-+/* Mark the given thread as a process-wide signal receiver. */
-+
-+extern void _hurd_sigstate_set_global_rcv (struct hurd_sigstate *ss);
-+
-+/* A thread can either use its own action vector and pending signal set
-+ or use the global ones, depending on wether it has been marked as a
-+ global receiver. The accessors below take that into account. */
-+
-+extern void _hurd_sigstate_lock (struct hurd_sigstate *ss);
-+extern struct sigaction *_hurd_sigstate_actions (struct hurd_sigstate *ss);
-+extern sigset_t _hurd_sigstate_pending (const struct hurd_sigstate *ss);
-+extern void _hurd_sigstate_unlock (struct hurd_sigstate *ss);
-+
-+/* Used by libpthread to remove stale sigstate structures. */
-+extern void _hurd_sigstate_delete (thread_t thread);
-+
- #ifndef _HURD_SIGNAL_H_EXTERN_INLINE
- #define _HURD_SIGNAL_H_EXTERN_INLINE __extern_inline
- #endif
-@@ -150,12 +176,6 @@ extern thread_t _hurd_msgport_thread;
-
- extern mach_port_t _hurd_msgport;
-
--
--/* Thread to receive process-global signals. */
--
--extern thread_t _hurd_sigthread;
--
--
- /* Resource limit on core file size. Enforced by hurdsig.c. */
- extern int _hurd_core_limit;
-
-@@ -203,10 +223,10 @@ _hurd_critical_section_unlock (void *our_lock)
- /* It was us who acquired the critical section lock. Unlock it. */
- struct hurd_sigstate *ss = our_lock;
- sigset_t pending;
-- __spin_lock (&ss->lock);
-+ _hurd_sigstate_lock (ss);
- __spin_unlock (&ss->critical_section_lock);
-- pending = ss->pending & ~ss->blocked;
-- __spin_unlock (&ss->lock);
-+ pending = _hurd_sigstate_pending(ss) & ~ss->blocked;
-+ _hurd_sigstate_unlock (ss);
- if (! __sigisemptyset (&pending))
- /* There are unblocked signals pending, which weren't
- delivered because we were in the critical section.
-diff --git a/hurd/hurdexec.c b/hurd/hurdexec.c
-index beae869..ee3162f 100644
---- a/hurd/hurdexec.c
-+++ b/hurd/hurdexec.c
-@@ -1,4 +1,4 @@
--/* Copyright (C) 1991,92,93,94,95,96,97,99,2001,02
-+/* Copyright (C) 1991,92,93,94,95,96,97,99,2001,2002,2011
- Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
-@@ -109,12 +109,13 @@ _hurd_exec (task_t task, file_t file,
- assert (! __spin_lock_locked (&ss->critical_section_lock));
- __spin_lock (&ss->critical_section_lock);
-
-- __spin_lock (&ss->lock);
-+ _hurd_sigstate_lock (ss);
-+ struct sigaction *actions = _hurd_sigstate_actions (ss);
- ints[INIT_SIGMASK] = ss->blocked;
-- ints[INIT_SIGPENDING] = ss->pending;
-+ ints[INIT_SIGPENDING] = _hurd_sigstate_pending (ss);
- ints[INIT_SIGIGN] = 0;
- for (i = 1; i < NSIG; ++i)
-- if (ss->actions[i].sa_handler == SIG_IGN)
-+ if (actions[i].sa_handler == SIG_IGN)
- ints[INIT_SIGIGN] |= __sigmask (i);
-
- /* We hold the sigstate lock until the exec has failed so that no signal
-@@ -125,7 +126,7 @@ _hurd_exec (task_t task, file_t file,
- critical section flag avoids anything we call trying to acquire the
- sigstate lock. */
-
-- __spin_unlock (&ss->lock);
-+ _hurd_sigstate_unlock (ss);
-
- /* Pack up the descriptor table to give the new program. */
- __mutex_lock (&_hurd_dtable_lock);
-diff --git a/hurd/hurdmsg.c b/hurd/hurdmsg.c
-index ffcce61..fdc7551 100644
---- a/hurd/hurdmsg.c
-+++ b/hurd/hurdmsg.c
-@@ -1,4 +1,5 @@
--/* Copyright (C) 1992, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
-+/* Copyright (C) 1992, 1994, 1995, 1996, 1997, 2011
-+ 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
-@@ -122,17 +123,9 @@ get_int (int which, int *value)
- case INIT_UMASK:
- *value = _hurd_umask;
- return 0;
-- case INIT_SIGMASK:
-- {
-- struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread);
-- __spin_lock (&ss->lock);
-- *value = ss->blocked;
-- __spin_unlock (&ss->lock);
-- return 0;
-- }
- case INIT_SIGPENDING:
- {
-- struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread);
-+ struct hurd_sigstate *ss = _hurd_global_sigstate;
- __spin_lock (&ss->lock);
- *value = ss->pending;
- __spin_unlock (&ss->lock);
-@@ -140,7 +133,7 @@ get_int (int which, int *value)
- }
- case INIT_SIGIGN:
- {
-- struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread);
-+ struct hurd_sigstate *ss = _hurd_global_sigstate;
- sigset_t ign;
- int sig;
- __spin_lock (&ss->lock);
-@@ -208,17 +201,9 @@ set_int (int which, int value)
- return 0;
-
- /* These are pretty odd things to do. But you asked for it. */
-- case INIT_SIGMASK:
-- {
-- struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread);
-- __spin_lock (&ss->lock);
-- ss->blocked = value;
-- __spin_unlock (&ss->lock);
-- return 0;
-- }
- case INIT_SIGPENDING:
- {
-- struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread);
-+ struct hurd_sigstate *ss = _hurd_global_sigstate;
- __spin_lock (&ss->lock);
- ss->pending = value;
- __spin_unlock (&ss->lock);
-@@ -226,7 +211,7 @@ set_int (int which, int value)
- }
- case INIT_SIGIGN:
- {
-- struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread);
-+ struct hurd_sigstate *ss = _hurd_global_sigstate;
- int sig;
- const sigset_t ign = value;
- __spin_lock (&ss->lock);
-diff --git a/hurd/hurdsig.c b/hurd/hurdsig.c
-index 74a01a6..67037e8 100644
---- a/hurd/hurdsig.c
-+++ b/hurd/hurdsig.c
-@@ -44,9 +44,6 @@ mach_port_t _hurd_msgport;
- /* Thread listening on it. */
- thread_t _hurd_msgport_thread;
-
--/* Thread which receives task-global signals. */
--thread_t _hurd_sigthread;
--
- /* These are set up by _hurdsig_init. */
- unsigned long int __hurd_sigthread_stack_base;
- unsigned long int __hurd_sigthread_stack_end;
-@@ -55,6 +52,9 @@ unsigned long int *__hurd_sigthread_variables;
- /* Linked-list of per-thread signal state. */
- struct hurd_sigstate *_hurd_sigstates;
-
-+/* Sigstate for the task-global signals. */
-+struct hurd_sigstate *_hurd_global_sigstate;
-+
- /* Timeout for RPC's after interrupt_operation. */
- mach_msg_timeout_t _hurd_interrupted_rpc_timeout = 3000;
-
-@@ -83,7 +83,7 @@ _hurd_thread_sigstate (thread_t thread)
- {
- ss = malloc (sizeof (*ss));
- if (ss == NULL)
-- __libc_fatal ("hurd: Can't allocate thread sigstate\n");
-+ __libc_fatal ("hurd: Can't allocate sigstate\n");
- ss->thread = thread;
- __spin_lock_init (&ss->lock);
-
-@@ -96,16 +96,19 @@ _hurd_thread_sigstate (thread_t thread)
- ss->intr_port = MACH_PORT_NULL;
- ss->context = NULL;
-
-- /* Initialize the sigaction vector from the default signal receiving
-- thread's state, and its from the system defaults. */
-- if (thread == _hurd_sigthread)
-- default_sigaction (ss->actions);
-+ if (thread == MACH_PORT_NULL)
-+ {
-+ /* Process-wide sigstate, use the system defaults. */
-+ default_sigaction (ss->actions);
-+
-+ /* The global sigstate is not added to the _hurd_sigstates list.
-+ It is created with _hurd_thread_sigstate (MACH_PORT_NULL)
-+ but should be accessed through _hurd_global_sigstate. */
-+ }
- else
- {
-- struct hurd_sigstate *s;
-- for (s = _hurd_sigstates; s != NULL; s = s->next)
-- if (s->thread == _hurd_sigthread)
-- break;
-+ /* Use the global actions as a default for new threads. */
-+ struct hurd_sigstate *s = _hurd_global_sigstate;
- if (s)
- {
- __spin_lock (&s->lock);
-@@ -114,14 +117,108 @@ _hurd_thread_sigstate (thread_t thread)
- }
- else
- default_sigaction (ss->actions);
-- }
-
-- ss->next = _hurd_sigstates;
-- _hurd_sigstates = ss;
-+ ss->next = _hurd_sigstates;
-+ _hurd_sigstates = ss;
-+ }
- }
- __mutex_unlock (&_hurd_siglock);
- return ss;
- }
-+
-+/* Destroy a sigstate structure. Called by libpthread just before the
-+ * corresponding thread is terminated (the kernel thread port must remain valid
-+ * until this function is called.) */
-+void
-+_hurd_sigstate_delete (thread_t thread)
-+{
-+ struct hurd_sigstate **ssp, *ss;
-+
-+ __mutex_lock (&_hurd_siglock);
-+ for (ssp = &_hurd_sigstates; *ssp; ssp = &(*ssp)->next)
-+ if ((*ssp)->thread == thread)
-+ break;
-+
-+ ss = *ssp;
-+ if (ss)
-+ *ssp = ss->next;
-+
-+ __mutex_unlock (&_hurd_siglock);
-+ if (ss)
-+ free (ss);
-+}
-+
-+/* Make SS a global receiver, with pthread signal semantics. */
-+void
-+_hurd_sigstate_set_global_rcv (struct hurd_sigstate *ss)
-+{
-+ assert (ss->thread != MACH_PORT_NULL);
-+ ss->actions[0].sa_handler = SIG_IGN;
-+}
-+
-+/* Check whether SS is a global receiver. */
-+static int
-+sigstate_is_global_rcv (const struct hurd_sigstate *ss)
-+{
-+ return ss->actions[0].sa_handler == SIG_IGN;
-+}
-+
-+/* Lock/unlock a hurd_sigstate structure. If the accessors below require
-+ it, the global sigstate will be locked as well. */
-+void
-+_hurd_sigstate_lock (struct hurd_sigstate *ss)
-+{
-+ if (sigstate_is_global_rcv (ss))
-+ __spin_lock (&_hurd_global_sigstate->lock);
-+ __spin_lock (&ss->lock);
-+}
-+void
-+_hurd_sigstate_unlock (struct hurd_sigstate *ss)
-+{
-+ __spin_unlock (&ss->lock);
-+ if (sigstate_is_global_rcv (ss))
-+ __spin_unlock (&_hurd_global_sigstate->lock);
-+}
-+
-+/* Retreive a thread's full set of pending signals, including the global
-+ ones if appropriate. SS must be locked. */
-+sigset_t
-+_hurd_sigstate_pending (const struct hurd_sigstate *ss)
-+{
-+ sigset_t pending = ss->pending;
-+ if (sigstate_is_global_rcv (ss))
-+ __sigorset (&pending, &pending, &_hurd_global_sigstate->pending);
-+ return pending;
-+}
-+
-+/* Clear a pending signal and return the associated detailed
-+ signal information. SS must be locked, and must have signal SIGNO
-+ pending, either directly or through the global sigstate. */
-+static struct hurd_signal_detail
-+sigstate_clear_pending (struct hurd_sigstate *ss, int signo)
-+{
-+ if (sigstate_is_global_rcv (ss)
-+ && __sigismember (&_hurd_global_sigstate->pending, signo))
-+ {
-+ __sigdelset (&_hurd_global_sigstate->pending, signo);
-+ return _hurd_global_sigstate->pending_data[signo];
-+ }
-+
-+ assert (__sigismember (&ss->pending, signo));
-+ __sigdelset (&ss->pending, signo);
-+ return ss->pending_data[signo];
-+}
-+
-+/* Retreive a thread's action vector. SS must be locked. */
-+struct sigaction *
-+_hurd_sigstate_actions (struct hurd_sigstate *ss)
-+{
-+ if (sigstate_is_global_rcv (ss))
-+ return _hurd_global_sigstate->actions;
-+ else
-+ return ss->actions;
-+}
-+
-
- /* Signal delivery itself is on this page. */
-
-@@ -216,6 +313,8 @@ static void
- abort_thread (struct hurd_sigstate *ss, struct machine_thread_all_state *state,
- void (*reply) (void))
- {
-+ assert (ss->thread != MACH_PORT_NULL);
-+
- if (!(state->set & THREAD_ABORTED))
- {
- error_t err = __thread_abort (ss->thread);
-@@ -355,7 +454,7 @@ _hurdsig_abort_rpcs (struct hurd_sigstate *ss, int signo, int sigthread,
- call above will retry their RPCs unless we clear SS->intr_port.
- So we clear it for the thread taking a signal when SA_RESTART is
- clear, so that its call returns EINTR. */
-- if (! signo || !(ss->actions[signo].sa_flags & SA_RESTART))
-+ if (! signo || !(_hurd_sigstate_actions (ss) [signo].sa_flags & SA_RESTART))
- ss->intr_port = MACH_PORT_NULL;
- }
-
-@@ -478,9 +577,11 @@ weak_alias (_hurdsig_preemptors, _hurdsig_preempters)
- sigmask (SIGSTOP) | sigmask (SIGTSTP))
-
- /* Actual delivery of a single signal. Called with SS unlocked. When
-- the signal is delivered, return 1 with SS locked. If the signal is
-- being traced, return 0 with SS unlocked. */
--static int
-+ the signal is delivered, return SS, locked (or, if SS was originally
-+ _hurd_global_sigstate, the sigstate of the actual thread the signal
-+ was delivered to). If the signal is being traced, return NULL with
-+ SS unlocked. */
-+static struct hurd_sigstate *
- post_signal (struct hurd_sigstate *ss,
- int signo, struct hurd_signal_detail *detail,
- int untraced, void (*reply) (void))
-@@ -533,8 +634,12 @@ post_signal (struct hurd_sigstate *ss,
- assert_perror (err);
- for (i = 0; i < nthreads; ++i)
- {
-- if (threads[i] != _hurd_msgport_thread &&
-- (act != handle || threads[i] != ss->thread))
-+ if (act == handle && threads[i] == ss->thread)
-+ {
-+ /* The thread that will run the handler is kept suspended. */
-+ ss_suspended = 1;
-+ }
-+ else if (threads[i] != _hurd_msgport_thread)
- {
- err = __thread_resume (threads[i]);
- assert_perror (err);
-@@ -547,9 +652,6 @@ post_signal (struct hurd_sigstate *ss,
- (vm_address_t) threads,
- nthreads * sizeof *threads);
- _hurd_stopped = 0;
-- if (act == handle)
-- /* The thread that will run the handler is already suspended. */
-- ss_suspended = 1;
- }
-
- error_t err;
-@@ -565,13 +667,43 @@ post_signal (struct hurd_sigstate *ss,
- }
-
- /* This call is just to check for pending signals. */
-- __spin_lock (&ss->lock);
-- return 1;
-+ _hurd_sigstate_lock (ss);
-+ return ss;
- }
-
- thread_state.set = 0; /* We know nothing. */
-
-- __spin_lock (&ss->lock);
-+ _hurd_sigstate_lock (ss);
-+
-+ /* If this is a global signal, try to find a thread ready to accept
-+ it right away. This is especially important for untraced signals,
-+ since going through the global pending mask would de-untrace them. */
-+ if (ss->thread == MACH_PORT_NULL)
-+ {
-+ struct hurd_sigstate *rss;
-+
-+ __mutex_lock (&_hurd_siglock);
-+ for (rss = _hurd_sigstates; rss != NULL; rss = rss->next)
-+ {
-+ if (! sigstate_is_global_rcv (rss))
-+ continue;
-+
-+ /* The global sigstate is already locked. */
-+ __spin_lock (&rss->lock);
-+ if (! __sigismember (&rss->blocked, signo))
-+ {
-+ ss = rss;
-+ break;
-+ }
-+ __spin_unlock (&rss->lock);
-+ }
-+ __mutex_unlock (&_hurd_siglock);
-+ }
-+
-+ /* We want the preemptors to be able to update the blocking mask
-+ without affecting the delivery of this signal, so we save the
-+ current value to test against later. */
-+ sigset_t blocked = ss->blocked;
-
- /* Check for a preempted signal. Preempted signals can arrive during
- critical sections. */
-@@ -629,12 +761,12 @@ post_signal (struct hurd_sigstate *ss,
- mark_pending ();
- else
- suspend ();
-- __spin_unlock (&ss->lock);
-+ _hurd_sigstate_unlock (ss);
- reply ();
-- return 0;
-+ return NULL;
- }
-
-- handler = ss->actions[signo].sa_handler;
-+ handler = _hurd_sigstate_actions (ss) [signo].sa_handler;
-
- if (handler == SIG_DFL)
- /* Figure out the default action for this signal. */
-@@ -728,7 +860,7 @@ post_signal (struct hurd_sigstate *ss,
-
- /* Handle receipt of a blocked signal, or any signal while stopped. */
- if (act != ignore && /* Signals ignored now are forgotten now. */
-- __sigismember (&ss->blocked, signo) ||
-+ __sigismember (&blocked, signo) ||
- (signo != SIGKILL && _hurd_stopped))
- {
- mark_pending ();
-@@ -764,6 +896,7 @@ post_signal (struct hurd_sigstate *ss,
- now's the time to set it going. */
- if (ss_suspended)
- {
-+ assert (ss->thread != MACH_PORT_NULL);
- err = __thread_resume (ss->thread);
- assert_perror (err);
- ss_suspended = 0;
-@@ -808,6 +941,8 @@ post_signal (struct hurd_sigstate *ss,
- struct sigcontext *scp, ocontext;
- int wait_for_reply, state_changed;
-
-+ assert (ss->thread != MACH_PORT_NULL);
-+
- /* Stop the thread and abort its pending RPC operations. */
- if (! ss_suspended)
- {
-@@ -942,23 +1077,25 @@ post_signal (struct hurd_sigstate *ss,
- }
- }
-
-+ struct sigaction *action = & _hurd_sigstate_actions (ss) [signo];
-+
- /* Backdoor extra argument to signal handler. */
- scp->sc_error = detail->error;
-
- /* Block requested signals while running the handler. */
- scp->sc_mask = ss->blocked;
-- __sigorset (&ss->blocked, &ss->blocked, &ss->actions[signo].sa_mask);
-+ __sigorset (&ss->blocked, &ss->blocked, &action->sa_mask);
-
- /* Also block SIGNO unless we're asked not to. */
-- if (! (ss->actions[signo].sa_flags & (SA_RESETHAND | SA_NODEFER)))
-+ if (! (action->sa_flags & (SA_RESETHAND | SA_NODEFER)))
- __sigaddset (&ss->blocked, signo);
-
- /* Reset to SIG_DFL if requested. SIGILL and SIGTRAP cannot
- be automatically reset when delivered; the system silently
- enforces this restriction. */
-- if (ss->actions[signo].sa_flags & SA_RESETHAND
-+ if (action->sa_flags & SA_RESETHAND
- && signo != SIGILL && signo != SIGTRAP)
-- ss->actions[signo].sa_handler = SIG_DFL;
-+ action->sa_handler = SIG_DFL;
-
- /* Any sigsuspend call must return after the handler does. */
- wake_sigsuspend (ss);
-@@ -976,7 +1113,7 @@ post_signal (struct hurd_sigstate *ss,
- }
- }
-
-- return 1;
-+ return ss;
- }
-
- /* Return the set of pending signals in SS which should be delivered. */
-@@ -991,7 +1128,7 @@ pending_signals (struct hurd_sigstate *ss)
- if (_hurd_stopped || __spin_lock_locked (&ss->critical_section_lock))
- return 0;
-
-- return ss->pending & ~ss->blocked;
-+ return _hurd_sigstate_pending (ss) & ~ss->blocked;
- }
-
- /* Post the specified pending signals in SS and return 1. If one of
-@@ -1003,12 +1140,15 @@ post_pending (struct hurd_sigstate *ss, sigset_t pending, void (*reply) (void))
- int signo;
- struct hurd_signal_detail detail;
-
-+ /* Make sure SS corresponds to an actual thread, since we assume it won't
-+ change in post_signal. */
-+ assert (ss->thread != MACH_PORT_NULL);
-+
- for (signo = 1; signo < NSIG; ++signo)
- if (__sigismember (&pending, signo))
- {
-- __sigdelset (&ss->pending, signo);
-- detail = ss->pending_data[signo];
-- __spin_unlock (&ss->lock);
-+ detail = sigstate_clear_pending (ss, signo);
-+ _hurd_sigstate_unlock (ss);
-
- /* Will reacquire the lock, except if the signal is traced. */
- if (! post_signal (ss, signo, &detail, 0, reply))
-@@ -1016,7 +1156,7 @@ post_pending (struct hurd_sigstate *ss, sigset_t pending, void (*reply) (void))
- }
-
- /* No more signals pending; SS->lock is still locked. */
-- __spin_unlock (&ss->lock);
-+ _hurd_sigstate_unlock (ss);
-
- return 1;
- }
-@@ -1034,14 +1174,14 @@ post_all_pending_signals (void (*reply) (void))
- __mutex_lock (&_hurd_siglock);
- for (ss = _hurd_sigstates; ss != NULL; ss = ss->next)
- {
-- __spin_lock (&ss->lock);
-+ _hurd_sigstate_lock (ss);
-
- pending = pending_signals (ss);
- if (pending)
- /* post_pending() below will unlock SS. */
- break;
-
-- __spin_unlock (&ss->lock);
-+ _hurd_sigstate_unlock (ss);
- }
- __mutex_unlock (&_hurd_siglock);
-
-@@ -1074,11 +1214,12 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
- assert_perror (err);
- }
-
-- if (! post_signal (ss, signo, detail, untraced, reply))
-+ ss = post_signal (ss, signo, detail, untraced, reply);
-+ if (! ss)
- return;
-
- /* The signal was neither fatal nor traced. We still hold SS->lock. */
-- if (signo != 0)
-+ if (signo != 0 && ss->thread != MACH_PORT_NULL)
- {
- /* The signal has either been ignored or is now being handled. We can
- consider it delivered and reply to the killer. */
-@@ -1090,8 +1231,9 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
- }
- else
- {
-- /* We need to check for pending signals for all threads. */
-- __spin_unlock (&ss->lock);
-+ /* If this was a process-wide signal or a poll request, we need
-+ to check for pending signals for all threads. */
-+ _hurd_sigstate_unlock (ss);
- if (! post_all_pending_signals (reply))
- return;
-
-@@ -1217,9 +1359,10 @@ _S_msg_sig_post (mach_port_t me,
- d.code = sigcode;
- d.exc = 0;
-
-- /* Post the signal to the designated signal-receiving thread. This will
-- reply when the signal can be considered delivered. */
-- _hurd_internal_post_signal (_hurd_thread_sigstate (_hurd_sigthread),
-+ /* Post the signal to a global receiver thread (or mark it pending in
-+ the global sigstate). This will reply when the signal can be
-+ considered delivered. */
-+ _hurd_internal_post_signal (_hurd_global_sigstate,
- signo, &d, reply_port, reply_port_type,
- 0); /* Stop if traced. */
-
-@@ -1247,7 +1390,7 @@ _S_msg_sig_post_untraced (mach_port_t me,
-
- /* Post the signal to the designated signal-receiving thread. This will
- reply when the signal can be considered delivered. */
-- _hurd_internal_post_signal (_hurd_thread_sigstate (_hurd_sigthread),
-+ _hurd_internal_post_signal (_hurd_global_sigstate,
- signo, &d, reply_port, reply_port_type,
- 1); /* Untraced flag. */
-
-@@ -1258,8 +1401,8 @@ extern void __mig_init (void *);
-
- #include <mach/task_special_ports.h>
-
--/* Initialize the message port and _hurd_sigthread and start the signal
-- thread. */
-+/* Initialize the message port, _hurd_global_sigstate, and start the
-+ signal thread. */
-
- void
- _hurdsig_init (const int *intarray, size_t intarraysize)
-@@ -1282,27 +1425,34 @@ _hurdsig_init (const int *intarray, size_t intarraysize)
- MACH_MSG_TYPE_MAKE_SEND);
- assert_perror (err);
-
-+ /* Initialize the global signal state. */
-+ _hurd_global_sigstate = _hurd_thread_sigstate (MACH_PORT_NULL);
-+
-+ /* We block all signals, and let actual threads pull them from the
-+ pending mask. */
-+ __sigfillset(& _hurd_global_sigstate->blocked);
-+
- /* Initialize the main thread's signal state. */
- ss = _hurd_self_sigstate ();
-
-- /* Copy inherited values from our parent (or pre-exec process state)
-- into the signal settings of the main thread. */
-+ /* Mark it as a process-wide signal receiver. Threads in this set use
-+ the common action vector in _hurd_global_sigstate. */
-+ _hurd_sigstate_set_global_rcv (ss);
-+
-+ /* Copy inherited signal settings from our parent (or pre-exec process
-+ state) */
- if (intarraysize > INIT_SIGMASK)
- ss->blocked = intarray[INIT_SIGMASK];
- if (intarraysize > INIT_SIGPENDING)
-- ss->pending = intarray[INIT_SIGPENDING];
-+ _hurd_global_sigstate->pending = intarray[INIT_SIGPENDING];
- if (intarraysize > INIT_SIGIGN && intarray[INIT_SIGIGN] != 0)
- {
- int signo;
- for (signo = 1; signo < NSIG; ++signo)
- if (intarray[INIT_SIGIGN] & __sigmask(signo))
-- ss->actions[signo].sa_handler = SIG_IGN;
-+ _hurd_global_sigstate->actions[signo].sa_handler = SIG_IGN;
- }
-
-- /* Set the default thread to receive task-global signals
-- to this one, the main (first) user thread. */
-- _hurd_sigthread = ss->thread;
--
- /* Start the signal thread listening on the message port. */
-
- if (__hurd_threadvar_stack_mask == 0)
-diff --git a/sysdeps/mach/hurd/fork.c b/sysdeps/mach/hurd/fork.c
-index 3288f18..a4f3055 100644
---- a/sysdeps/mach/hurd/fork.c
-+++ b/sysdeps/mach/hurd/fork.c
-@@ -459,6 +459,7 @@ __fork (void)
- function, accounted for by mach_port_names (and which will thus be
- accounted for in the child below). This extra right gets consumed
- in the child by the store into _hurd_sigthread in the child fork. */
-+ /* XXX consumed? (_hurd_sigthread is no more) */
- if (thread_refs > 1 &&
- (err = __mach_port_mod_refs (newtask, ss->thread,
- MACH_PORT_RIGHT_SEND,
-@@ -616,10 +617,6 @@ __fork (void)
- for (i = 0; i < _hurd_nports; ++i)
- __spin_unlock (&_hurd_ports[i].lock);
-
-- /* We are one of the (exactly) two threads in this new task, we
-- will take the task-global signals. */
-- _hurd_sigthread = ss->thread;
--
- /* Claim our sigstate structure and unchain the rest: the
- threads existed in the parent task but don't exist in this
- task (the child process). Delay freeing them until later
-@@ -640,6 +637,10 @@ __fork (void)
- _hurd_sigstates = ss;
- __mutex_unlock (&_hurd_siglock);
-
-+ /* We are one of the (exactly) two threads in this new task, we
-+ will take the task-global signals. */
-+ _hurd_sigstate_set_global_rcv (ss);
-+
- /* Fetch our new process IDs from the proc server. No need to
- refetch our pgrp; it is always inherited from the parent (so
- _hurd_pgrp is already correct), and the proc server will send us a
-diff --git a/sysdeps/mach/hurd/i386/sigreturn.c b/sysdeps/mach/hurd/i386/sigreturn.c
-index 60b0d00..8cb92ef 100644
---- a/sysdeps/mach/hurd/i386/sigreturn.c
-+++ b/sysdeps/mach/hurd/i386/sigreturn.c
-@@ -1,4 +1,5 @@
--/* Copyright (C) 1991,92,94,95,96,97,98,2001 Free Software Foundation, Inc.
-+/* Copyright (C) 1991,92,94,95,96,97,98,2001,2011
-+ 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
-@@ -39,7 +40,7 @@ __sigreturn (struct sigcontext *scp)
- }
-
- ss = _hurd_self_sigstate ();
-- __spin_lock (&ss->lock);
-+ _hurd_sigstate_lock (ss);
-
- /* Remove the link on the `active resources' chain added by
- _hurd_setup_sighandler. Its purpose was to make sure
-@@ -51,19 +52,19 @@ __sigreturn (struct sigcontext *scp)
- ss->intr_port = scp->sc_intr_port;
-
- /* Check for pending signals that were blocked by the old set. */
-- if (ss->pending & ~ss->blocked)
-+ if (_hurd_sigstate_pending (ss) & ~ss->blocked)
- {
- /* There are pending signals that just became unblocked. Wake up the
- signal thread to deliver them. But first, squirrel away SCP where
- the signal thread will notice it if it runs another handler, and
- arrange to have us called over again in the new reality. */
- ss->context = scp;
-- __spin_unlock (&ss->lock);
-+ _hurd_sigstate_unlock (ss);
- __msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ());
- /* If a pending signal was handled, sig_post never returned.
- If it did return, the pending signal didn't run a handler;
- proceed as usual. */
-- __spin_lock (&ss->lock);
-+ _hurd_sigstate_lock (ss);
- ss->context = NULL;
- }
-
-@@ -74,7 +75,7 @@ __sigreturn (struct sigcontext *scp)
- abort ();
- }
- else
-- __spin_unlock (&ss->lock);
-+ _hurd_sigstate_unlock (ss);
-
- /* Destroy the MiG reply port used by the signal handler, and restore the
- reply port in use by the thread when interrupted. */
-diff --git a/sysdeps/mach/hurd/i386/trampoline.c b/sysdeps/mach/hurd/i386/trampoline.c
-index 99d9308..ec52847 100644
---- a/sysdeps/mach/hurd/i386/trampoline.c
-+++ b/sysdeps/mach/hurd/i386/trampoline.c
-@@ -1,5 +1,5 @@
- /* Set thread_state for sighandler, and sigcontext to recover. i386 version.
-- Copyright (C) 1994,1995,1996,1997,1998,1999,2005,2008
-+ Copyright (C) 1994,1995,1996,1997,1998,1999,2005,2008,2011
- Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
-@@ -77,7 +77,11 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
- interrupted RPC frame. */
- state->basic.esp = state->basic.uesp;
-
-- if ((ss->actions[signo].sa_flags & SA_ONSTACK) &&
-+ /* XXX what if handler != action->handler (for instance, if a signal
-+ * preemptor took over) ? */
-+ action = & _hurd_sigstate_actions (ss) [signo];
-+
-+ if ((action->sa_flags & SA_ONSTACK) &&
- !(ss->sigaltstack.ss_flags & (SS_DISABLE|SS_ONSTACK)))
- {
- sigsp = ss->sigaltstack.ss_sp + ss->sigaltstack.ss_size;
-diff --git a/sysdeps/mach/hurd/sigaction.c b/sysdeps/mach/hurd/sigaction.c
-index fe452e8..bedf14c 100644
---- a/sysdeps/mach/hurd/sigaction.c
-+++ b/sysdeps/mach/hurd/sigaction.c
-@@ -1,4 +1,4 @@
--/* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2002, 2007
-+/* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2002, 2007, 2011
- Free Software Foundation, Inc.
-
- This file is part of the GNU C Library.
-@@ -51,15 +51,15 @@ __sigaction (sig, act, oact)
- ss = _hurd_self_sigstate ();
-
- __spin_lock (&ss->critical_section_lock);
-- __spin_lock (&ss->lock);
-- old = ss->actions[sig];
-+ _hurd_sigstate_lock (ss);
-+ old = _hurd_sigstate_actions (ss) [sig];
- if (act != NULL)
-- ss->actions[sig] = a;
-+ _hurd_sigstate_actions (ss) [sig] = a;
-
- if (act != NULL && sig == SIGCHLD &&
- (a.sa_flags & SA_NOCLDSTOP) != (old.sa_flags & SA_NOCLDSTOP))
- {
-- __spin_unlock (&ss->lock);
-+ _hurd_sigstate_unlock (ss);
-
- /* Inform the proc server whether or not it should send us SIGCHLD for
- stopped children. We do this in a critical section so that no
-@@ -67,8 +67,8 @@ __sigaction (sig, act, oact)
- __USEPORT (PROC,
- __proc_mod_stopchild (port, !(a.sa_flags & SA_NOCLDSTOP)));
-
-- __spin_lock (&ss->lock);
-- pending = ss->pending & ~ss->blocked;
-+ _hurd_sigstate_lock (ss);
-+ pending = _hurd_sigstate_pending (ss) & ~ss->blocked;
- }
- else if (act != NULL && (a.sa_handler == SIG_IGN || a.sa_handler == SIG_DFL))
- /* We are changing to an action that might be to ignore SIG signals.
-@@ -77,11 +77,11 @@ __sigaction (sig, act, oact)
- back and then SIG is unblocked, the signal pending now should not
- arrive. So wake up the signal thread to check the new state and do
- the right thing. */
-- pending = ss->pending & __sigmask (sig);
-+ pending = _hurd_sigstate_pending (ss) & __sigmask (sig);
- else
- pending = 0;
-
-- __spin_unlock (&ss->lock);
-+ _hurd_sigstate_unlock (ss);
- __spin_unlock (&ss->critical_section_lock);
-
- if (pending)
-diff --git a/sysdeps/mach/hurd/sigpending.c b/sysdeps/mach/hurd/sigpending.c
-index 84ac927..f582d45 100644
---- a/sysdeps/mach/hurd/sigpending.c
-+++ b/sysdeps/mach/hurd/sigpending.c
-@@ -1,4 +1,5 @@
--/* Copyright (C) 1991, 1993, 1994, 1995, 1997 Free Software Foundation, Inc.
-+/* Copyright (C) 1991, 1993, 1994, 1995, 1997, 2011
-+ 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
-@@ -38,9 +39,9 @@ sigpending (set)
- }
-
- ss = _hurd_self_sigstate ();
-- __spin_lock (&ss->lock);
-- pending = ss->pending;
-- __spin_unlock (&ss->lock);
-+ _hurd_sigstate_lock (ss);
-+ pending = _hurd_sigstate_pending (ss);
-+ _hurd_sigstate_unlock (ss);
-
- *set = pending;
- return 0;
-diff --git a/sysdeps/mach/hurd/sigprocmask.c b/sysdeps/mach/hurd/sigprocmask.c
-index cbb5ecc..b12dc19 100644
---- a/sysdeps/mach/hurd/sigprocmask.c
-+++ b/sysdeps/mach/hurd/sigprocmask.c
-@@ -1,4 +1,5 @@
--/* Copyright (C) 1991,92,93,94,95,96,97,2002 Free Software Foundation, Inc.
-+/* Copyright (C) 1991,92,93,94,95,96,97,2002,2011
-+ 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
-@@ -40,7 +41,7 @@ __sigprocmask (how, set, oset)
-
- ss = _hurd_self_sigstate ();
-
-- __spin_lock (&ss->lock);
-+ _hurd_sigstate_lock (ss);
-
- old = ss->blocked;
-
-@@ -61,7 +62,7 @@ __sigprocmask (how, set, oset)
- break;
-
- default:
-- __spin_unlock (&ss->lock);
-+ _hurd_sigstate_unlock (ss);
- errno = EINVAL;
- return -1;
- }
-@@ -69,9 +70,9 @@ __sigprocmask (how, set, oset)
- ss->blocked &= ~_SIG_CANT_MASK;
- }
-
-- pending = ss->pending & ~ss->blocked;
-+ pending = _hurd_sigstate_pending (ss) & ~ss->blocked;
-
-- __spin_unlock (&ss->lock);
-+ _hurd_sigstate_unlock (ss);
-
- if (oset != NULL)
- *oset = old;
-diff --git a/sysdeps/mach/hurd/sigsuspend.c b/sysdeps/mach/hurd/sigsuspend.c
-index 7e32472..2e55e30 100644
---- a/sysdeps/mach/hurd/sigsuspend.c
-+++ b/sysdeps/mach/hurd/sigsuspend.c
-@@ -1,5 +1,5 @@
--/* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2002, 2007
-- Free Software Foundation, Inc.
-+/* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2002, 2007,
-+ 2011 Free Software Foundation, Inc.
-
- This file is part of the GNU C Library.
-
-@@ -43,7 +43,7 @@ __sigsuspend (set)
-
- ss = _hurd_self_sigstate ();
-
-- __spin_lock (&ss->lock);
-+ _hurd_sigstate_lock (ss);
-
- oldmask = ss->blocked;
- if (set != NULL)
-@@ -51,11 +51,11 @@ __sigsuspend (set)
- ss->blocked = newmask & ~_SIG_CANT_MASK;
-
- /* Notice if any pending signals just became unblocked. */
-- pending = ss->pending & ~ss->blocked;
-+ pending = _hurd_sigstate_pending (ss) & ~ss->blocked;
-
- /* Tell the signal thread to message us when a signal arrives. */
- ss->suspended = wait;
-- __spin_unlock (&ss->lock);
-+ _hurd_sigstate_unlock (ss);
-
- if (pending)
- /* Tell the signal thread to check for pending signals. */
-@@ -66,10 +66,11 @@ __sigsuspend (set)
- MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
- __mach_port_destroy (__mach_task_self (), wait);
-
-- __spin_lock (&ss->lock);
-- ss->blocked = oldmask; /* Restore the old mask. */
-- pending = ss->pending & ~ss->blocked; /* Again check for pending signals. */
-- __spin_unlock (&ss->lock);
-+ /* Restore the old mask and check for pending signals again. */
-+ _hurd_sigstate_lock (ss);
-+ ss->blocked = oldmask;
-+ pending = _hurd_sigstate_pending(ss) & ~ss->blocked;
-+ _hurd_sigstate_unlock (ss);
-
- if (pending)
- /* Tell the signal thread to check for pending signals. */
-diff --git a/sysdeps/mach/hurd/sigwait.c b/sysdeps/mach/hurd/sigwait.c
-index 9794076..af50f74 100644
---- a/sysdeps/mach/hurd/sigwait.c
-+++ b/sysdeps/mach/hurd/sigwait.c
-@@ -1,4 +1,4 @@
--/* Copyright (C) 1996,97,2001,02 Free Software Foundation, Inc.
-+/* Copyright (C) 1996,97,2001,2002,2011 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
-@@ -28,7 +28,7 @@ int
- __sigwait (const sigset_t *set, int *sig)
- {
- struct hurd_sigstate *ss;
-- sigset_t mask, ready;
-+ sigset_t mask, ready, blocked;
- int signo = 0;
- struct hurd_signal_preemptor preemptor;
- jmp_buf buf;
-@@ -50,8 +50,8 @@ __sigwait (const sigset_t *set, int *sig)
- /* Make sure this is all kosher */
- assert (__sigismember (&mask, signo));
-
-- /* Make sure this signal is unblocked */
-- __sigdelset (&ss->blocked, signo);
-+ /* Restore the blocking mask. */
-+ ss->blocked = blocked;
-
- return pe->handler;
- }
-@@ -72,10 +72,11 @@ __sigwait (const sigset_t *set, int *sig)
- __sigemptyset (&mask);
-
- ss = _hurd_self_sigstate ();
-- __spin_lock (&ss->lock);
-+ _hurd_sigstate_lock (ss);
-
- /* See if one of these signals is currently pending. */
-- __sigandset (&ready, &ss->pending, &mask);
-+ sigset_t pending = _hurd_sigstate_pending (ss);
-+ __sigandset (&ready, &pending, &mask);
- if (! __sigisemptyset (&ready))
- {
- for (signo = 1; signo < NSIG; signo++)
-@@ -103,7 +104,11 @@ __sigwait (const sigset_t *set, int *sig)
- preemptor.next = ss->preemptors;
- ss->preemptors = &preemptor;
-
-- __spin_unlock (&ss->lock);
-+ /* Unblock the expected signals */
-+ blocked = ss->blocked;
-+ ss->blocked &= ~mask;
-+
-+ _hurd_sigstate_unlock (ss);
-
- /* Wait. */
- __mach_msg (&msg, MACH_RCV_MSG, 0, sizeof (msg), wait,
-@@ -114,7 +119,7 @@ __sigwait (const sigset_t *set, int *sig)
- {
- assert (signo);
-
-- __spin_lock (&ss->lock);
-+ _hurd_sigstate_lock (ss);
-
- /* Delete our preemptor. */
- assert (ss->preemptors == &preemptor);
-@@ -123,7 +128,7 @@ __sigwait (const sigset_t *set, int *sig)
-
-
- all_done:
-- spin_unlock (&ss->lock);
-+ _hurd_sigstate_unlock (ss);
-
- __mach_port_destroy (__mach_task_self (), wait);
- *sig = signo;
-diff --git a/sysdeps/mach/hurd/spawni.c b/sysdeps/mach/hurd/spawni.c
-index 244ca2d..373da8d 100644
---- a/sysdeps/mach/hurd/spawni.c
-+++ b/sysdeps/mach/hurd/spawni.c
-@@ -1,5 +1,5 @@
- /* spawn a new process running an executable. Hurd version.
-- Copyright (C) 2001,02,04 Free Software Foundation, Inc.
-+ Copyright (C) 2001,2002,2004,2011 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
-@@ -239,26 +239,29 @@ __spawni (pid_t *pid, const char *file,
- assert (! __spin_lock_locked (&ss->critical_section_lock));
- __spin_lock (&ss->critical_section_lock);
-
-- __spin_lock (&ss->lock);
-+ _hurd_sigstate_lock (ss);
- ints[INIT_SIGMASK] = ss->blocked;
-- ints[INIT_SIGPENDING] = ss->pending;
-+ ints[INIT_SIGPENDING] = _hurd_sigstate_pending (ss); /* XXX really? */
- ints[INIT_SIGIGN] = 0;
- /* Unless we were asked to reset all handlers to SIG_DFL,
- pass down the set of signals that were set to SIG_IGN. */
-- if ((flags & POSIX_SPAWN_SETSIGDEF) == 0)
-- for (i = 1; i < NSIG; ++i)
-- if (ss->actions[i].sa_handler == SIG_IGN)
-- ints[INIT_SIGIGN] |= __sigmask (i);
--
-- /* We hold the sigstate lock until the exec has failed so that no signal
-- can arrive between when we pack the blocked and ignored signals, and
-- when the exec actually happens. A signal handler could change what
-+ {
-+ struct sigaction *actions = _hurd_sigstate_actions (ss);
-+ if ((flags & POSIX_SPAWN_SETSIGDEF) == 0)
-+ for (i = 1; i < NSIG; ++i)
-+ if (actions[i].sa_handler == SIG_IGN)
-+ ints[INIT_SIGIGN] |= __sigmask (i);
-+ }
-+
-+ /* We hold the critical section lock until the exec has failed so that no
-+ signal can arrive between when we pack the blocked and ignored signals,
-+ and when the exec actually happens. A signal handler could change what
- signals are blocked and ignored. Either the change will be reflected
- in the exec, or the signal will never be delivered. Setting the
- critical section flag avoids anything we call trying to acquire the
- sigstate lock. */
-
-- __spin_unlock (&ss->lock);
-+ _hurd_sigstate_unlock (ss);
-
- /* Set signal mask. */
- if ((flags & POSIX_SPAWN_SETSIGMASK) != 0)
Copied: glibc-package/trunk/debian/patches/hurd-i386/tg-hurdsig-SA_SIGINFO.diff (from rev 5168, glibc-package/trunk/debian/patches/hurd-i386/submitted-hurdsig-SA_SIGINFO.diff)
===================================================================
--- glibc-package/trunk/debian/patches/hurd-i386/tg-hurdsig-SA_SIGINFO.diff (rev 0)
+++ glibc-package/trunk/debian/patches/hurd-i386/tg-hurdsig-SA_SIGINFO.diff 2012-02-21 01:58:20 UTC (rev 5169)
@@ -0,0 +1,549 @@
+From: Jeremie Koenig <jk@jk.fr.eu.org>
+Subject: [PATCH] implement SA_SIGINFO signal handlers.
+
+ 52baaca Hurd signals: Copy bits/sigaction.h
+ 4232c66 Hurd signals: SA_SIGINFO support
+ 1831cfe Hurd signals: Use POSIX sigcodes
+
+---
+ hurd/hurd/signal.h | 5 +
+ hurd/hurdinit.c | 2 +-
+ sysdeps/mach/hurd/bits/sigaction.h | 81 ++++++++++++++++++++
+ sysdeps/mach/hurd/i386/bits/sigcontext.h | 4 +
+ sysdeps/mach/hurd/i386/exc2signal.c | 123 +++++++++++++++++++-----------
+ sysdeps/mach/hurd/i386/trampoline.c | 113 +++++++++++++++++++++++++--
+ sysdeps/mach/hurd/kill.c | 2 +-
+ sysdeps/mach/hurd/setitimer.c | 2 +-
+ 8 files changed, 274 insertions(+), 58 deletions(-)
+
+diff --git a/hurd/hurd/signal.h b/hurd/hurd/signal.h
+index 1c4733a..cc96f21 100644
+--- a/hurd/hurd/signal.h
++++ b/hurd/hurd/signal.h
+@@ -264,6 +264,11 @@ extern void _hurd_raise_signal (struct hurd_sigstate *ss, int signo,
+ extern void _hurd_exception2signal (struct hurd_signal_detail *detail,
+ int *signo);
+
++/* Translate a Mach exception into a signal with a legacy sigcode. */
++
++extern void _hurd_exception2signal_legacy (struct hurd_signal_detail *detail,
++ int *signo);
++
+
+ /* Make the thread described by SS take the signal described by SIGNO and
+ DETAIL. If the process is traced, this will in fact stop with a SIGNO
+diff --git a/hurd/hurdinit.c b/hurd/hurdinit.c
+index 259f8a3..97d3460 100644
+--- a/hurd/hurdinit.c
++++ b/hurd/hurdinit.c
+@@ -176,7 +176,7 @@ _hurd_new_proc_init (char **argv,
+ /* This process is "traced", meaning it should stop on signals or exec.
+ We are all set up now to handle signals. Stop ourselves, to inform
+ our parent (presumably a debugger) that the exec has completed. */
+- __msg_sig_post (_hurd_msgport, SIGTRAP, 0, __mach_task_self ());
++ __msg_sig_post (_hurd_msgport, SIGTRAP, TRAP_TRACE, __mach_task_self ());
+ }
+
+ #include <shlib-compat.h>
+diff --git a/sysdeps/mach/hurd/bits/sigaction.h b/sysdeps/mach/hurd/bits/sigaction.h
+new file mode 100644
+index 0000000..d3a4220
+--- /dev/null
++++ b/sysdeps/mach/hurd/bits/sigaction.h
+@@ -0,0 +1,81 @@
++/* Copyright (C) 1991,92,96,97,98,2001 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
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, write to the Free
++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++ 02111-1307 USA. */
++
++#ifndef _SIGNAL_H
++# error "Never include <bits/sigaction.h> directly; use <signal.h> instead."
++#endif
++
++/* These definitions match those used by the 4.4 BSD kernel.
++ If the operating system has a `sigaction' system call that correctly
++ implements the POSIX.1 behavior, there should be a system-dependent
++ version of this file that defines `struct sigaction' and the `SA_*'
++ constants appropriately. */
++
++/* Structure describing the action to be taken when a signal arrives. */
++struct sigaction
++ {
++ /* Signal handler. */
++#ifdef __USE_POSIX199309
++ union
++ {
++ /* Used if SA_SIGINFO is not set. */
++ __sighandler_t sa_handler;
++ /* Used if SA_SIGINFO is set. */
++ void (*sa_sigaction) (int, siginfo_t *, void *);
++ }
++ __sigaction_handler;
++# define sa_handler __sigaction_handler.sa_handler
++# define sa_sigaction __sigaction_handler.sa_sigaction
++#else
++ __sighandler_t sa_handler;
++#endif
++
++ /* Additional set of signals to be blocked. */
++ __sigset_t sa_mask;
++
++ /* Special flags. */
++ int sa_flags;
++ };
++
++/* Bits in `sa_flags'. */
++#if defined __USE_UNIX98 || defined __USE_MISC
++# define SA_ONSTACK 0x0001 /* Take signal on signal stack. */
++#endif
++#if defined __USE_UNIX98 || defined __USE_MISC || defined __USE_XOPEN2K8
++# define SA_RESTART 0x0002 /* Restart syscall on signal return. */
++# define SA_NODEFER 0x0010 /* Don't automatically block the signal when
++ its handler is being executed. */
++# define SA_RESETHAND 0x0004 /* Reset to SIG_DFL on entry to handler. */
++# define SA_SIGINFO 0x0040 /* Signal handler with SA_SIGINFO args */
++#endif
++#define SA_NOCLDSTOP 0x0008 /* Don't send SIGCHLD when children stop. */
++
++#ifdef __USE_MISC
++# define SA_INTERRUPT 0 /* Historical no-op ("not SA_RESTART"). */
++
++/* Some aliases for the SA_ constants. */
++# define SA_NOMASK SA_NODEFER
++# define SA_ONESHOT SA_RESETHAND
++# define SA_STACK SA_ONSTACK
++#endif
++
++
++/* Values for the HOW argument to `sigprocmask'. */
++#define SIG_BLOCK 1 /* Block signals. */
++#define SIG_UNBLOCK 2 /* Unblock signals. */
++#define SIG_SETMASK 3 /* Set the set of blocked signals. */
+diff --git a/sysdeps/mach/hurd/i386/bits/sigcontext.h b/sysdeps/mach/hurd/i386/bits/sigcontext.h
+index a78dd2f..1956d41 100644
+--- a/sysdeps/mach/hurd/i386/bits/sigcontext.h
++++ b/sysdeps/mach/hurd/i386/bits/sigcontext.h
+@@ -96,6 +96,10 @@ struct sigcontext
+ #define sc_ps sc_efl
+
+
++/* The deprecated sigcode values below are passed as an extra, non-portable
++ argument to regular signal handlers. You should use SA_SIGINFO handlers
++ instead, which use the standard POSIX signal codes. */
++
+ /* Codes for SIGFPE. */
+ #define FPE_INTOVF_TRAP 0x1 /* integer overflow */
+ #define FPE_INTDIV_FAULT 0x2 /* integer divide by zero */
+diff --git a/sysdeps/mach/hurd/i386/exc2signal.c b/sysdeps/mach/hurd/i386/exc2signal.c
+index a6bf750..7ffeb5f 100644
+--- a/sysdeps/mach/hurd/i386/exc2signal.c
++++ b/sysdeps/mach/hurd/i386/exc2signal.c
+@@ -24,8 +24,8 @@
+ /* Translate the Mach exception codes, as received in an `exception_raise' RPC,
+ into a signal number and signal subcode. */
+
+-void
+-_hurd_exception2signal (struct hurd_signal_detail *detail, int *signo)
++static void
++exception2signal (struct hurd_signal_detail *detail, int *signo, int posix)
+ {
+ detail->error = 0;
+
+@@ -37,44 +37,62 @@ _hurd_exception2signal (struct hurd_signal_detail *detail, int *signo)
+ break;
+
+ case EXC_BAD_ACCESS:
+- if (detail->exc_code == KERN_INVALID_ADDRESS
+- || detail->exc_code == KERN_PROTECTION_FAILURE
+- || detail->exc_code == KERN_WRITE_PROTECTION_FAILURE)
+- *signo = SIGSEGV;
+- else
+- *signo = SIGBUS;
+- detail->code = detail->exc_subcode;
++ switch (detail->exc_code)
++ {
++ case KERN_INVALID_ADDRESS:
++ case KERN_MEMORY_FAILURE:
++ *signo = SIGSEGV;
++ detail->code = posix ? SEGV_MAPERR : detail->exc_subcode;
++ break;
++
++ case KERN_PROTECTION_FAILURE:
++ case KERN_WRITE_PROTECTION_FAILURE:
++ *signo = SIGSEGV;
++ detail->code = posix ? SEGV_ACCERR : detail->exc_subcode;
++ break;
++
++ default:
++ *signo = SIGBUS;
++ detail->code = 0;
++ break;
++ }
+ detail->error = detail->exc_code;
+ break;
+
+ case EXC_BAD_INSTRUCTION:
+ *signo = SIGILL;
+- if (detail->exc_code == EXC_I386_INVOP)
+- detail->code = ILL_INVOPR_FAULT;
+- else if (detail->exc_code == EXC_I386_STKFLT)
+- detail->code = ILL_STACK_FAULT;
+- else
+- detail->code = 0;
++ switch (detail->exc_code)
++ {
++ case EXC_I386_INVOP:
++ detail->code = posix ? ILL_ILLOPC : ILL_INVOPR_FAULT;
++ break;
++
++ case EXC_I386_STKFLT:
++ detail->code = posix ? ILL_BADSTK : ILL_STACK_FAULT;
++ break;
++
++ default:
++ detail->code = 0;
++ break;
++ }
+ break;
+
+ case EXC_ARITHMETIC:
++ *signo = SIGFPE;
+ switch (detail->exc_code)
+ {
+ case EXC_I386_DIV: /* integer divide by zero */
+- *signo = SIGFPE;
+- detail->code = FPE_INTDIV_FAULT;
++ detail->code = posix ? FPE_INTDIV : FPE_INTDIV_FAULT;
+ break;
+
+ case EXC_I386_INTO: /* integer overflow */
+- *signo = SIGFPE;
+- detail->code = FPE_INTOVF_TRAP;
++ detail->code = posix ? FPE_INTOVF : FPE_INTOVF_TRAP;
+ break;
+
+ /* These aren't anywhere documented or used in Mach 3.0. */
+ case EXC_I386_NOEXT:
+ case EXC_I386_EXTOVR:
+ default:
+- *signo = SIGFPE;
+ detail->code = 0;
+ break;
+
+@@ -83,51 +101,43 @@ _hurd_exception2signal (struct hurd_signal_detail *detail, int *signo)
+ Give an error code corresponding to the first bit set. */
+ if (detail->exc_subcode & FPS_IE)
+ {
+- *signo = SIGILL;
+- detail->code = ILL_FPEOPR_FAULT;
++ /* NB: We used to send SIGILL here but we can't distinguish
++ POSIX vs. legacy with respect to what signal we send. */
++ detail->code = posix ? FPE_FLTINV : 0 /*ILL_FPEOPR_FAULT*/;
+ }
+ else if (detail->exc_subcode & FPS_DE)
+ {
+- *signo = SIGFPE;
+- detail->code = FPE_FLTDNR_FAULT;
++ detail->code = posix ? FPE_FLTUND : FPE_FLTDNR_FAULT;
+ }
+ else if (detail->exc_subcode & FPS_ZE)
+ {
+- *signo = SIGFPE;
+- detail->code = FPE_FLTDIV_FAULT;
++ detail->code = posix ? FPE_FLTDIV : FPE_FLTDIV_FAULT;
+ }
+ else if (detail->exc_subcode & FPS_OE)
+ {
+- *signo = SIGFPE;
+- detail->code = FPE_FLTOVF_FAULT;
++ detail->code = posix ? FPE_FLTOVF : FPE_FLTOVF_FAULT;
+ }
+ else if (detail->exc_subcode & FPS_UE)
+ {
+- *signo = SIGFPE;
+- detail->code = FPE_FLTUND_FAULT;
++ detail->code = posix ? FPE_FLTUND : FPE_FLTUND_FAULT;
+ }
+ else if (detail->exc_subcode & FPS_PE)
+ {
+- *signo = SIGFPE;
+- detail->code = FPE_FLTINX_FAULT;
++ detail->code = posix ? FPE_FLTRES : FPE_FLTINX_FAULT;
+ }
+ else
+ {
+- *signo = SIGFPE;
+ detail->code = 0;
+ }
+ break;
+
+ /* These two can only be arithmetic exceptions if we
+- are in V86 mode, which sounds like emulation to me.
+- (See Mach 3.0 i386/trap.c.) */
++ are in V86 mode. (See Mach 3.0 i386/trap.c.) */
+ case EXC_I386_EMERR:
+- *signo = SIGFPE;
+- detail->code = FPE_EMERR_FAULT;
++ detail->code = posix ? 0 : FPE_EMERR_FAULT;
+ break;
+ case EXC_I386_BOUND:
+- *signo = SIGFPE;
+- detail->code = FPE_EMBND_FAULT;
++ detail->code = posix ? FPE_FLTSUB : FPE_EMBND_FAULT;
+ break;
+ }
+ break;
+@@ -144,7 +154,7 @@ _hurd_exception2signal (struct hurd_signal_detail *detail, int *signo)
+ if (detail->exc_code == EXC_I386_BOUND)
+ {
+ *signo = SIGFPE;
+- detail->code = FPE_SUBRNG_FAULT;
++ detail->code = posix ? FPE_FLTSUB : FPE_SUBRNG_FAULT;
+ }
+ else
+ {
+@@ -155,12 +165,33 @@ _hurd_exception2signal (struct hurd_signal_detail *detail, int *signo)
+
+ case EXC_BREAKPOINT:
+ *signo = SIGTRAP;
+- if (detail->exc_code == EXC_I386_SGL)
+- detail->code = DBG_SINGLE_TRAP;
+- else if (detail->exc_code == EXC_I386_BPT)
+- detail->code = DBG_BRKPNT_FAULT;
+- else
+- detail->code = 0;
++ switch (detail->exc_code)
++ {
++ case EXC_I386_SGL:
++ detail->code = posix ? TRAP_BRKPT : DBG_SINGLE_TRAP;
++ break;
++
++ case EXC_I386_BPT:
++ detail->code = posix ? TRAP_BRKPT : DBG_BRKPNT_FAULT;
++ break;
++
++ default:
++ detail->code = 0;
++ break;
++ }
+ break;
+ }
+ }
++
++void
++_hurd_exception2signal (struct hurd_signal_detail *detail, int *signo)
++{
++ exception2signal (detail, signo, 1);
++}
++
++void
++_hurd_exception2signal_legacy (struct hurd_signal_detail *detail, int *signo)
++{
++ exception2signal (detail, signo, 0);
++}
++
+diff --git a/sysdeps/mach/hurd/i386/trampoline.c b/sysdeps/mach/hurd/i386/trampoline.c
+index ec52847..5abd33d 100644
+--- a/sysdeps/mach/hurd/i386/trampoline.c
++++ b/sysdeps/mach/hurd/i386/trampoline.c
+@@ -21,13 +21,66 @@
+ #include <hurd/signal.h>
+ #include <hurd/userlink.h>
+ #include <thread_state.h>
++#include <mach/exception.h>
+ #include <mach/machine/eflags.h>
+ #include <assert.h>
+ #include <errno.h>
+ #include "hurdfault.h"
+ #include <intr-msg.h>
++#include <sys/ucontext.h>
+
+
++/* Fill in a siginfo_t structure for SA_SIGINFO-enabled handlers. */
++static void fill_siginfo (siginfo_t *si, int signo,
++ const struct hurd_signal_detail *detail,
++ const struct machine_thread_all_state *state)
++{
++ si->si_signo = signo;
++ si->si_errno = detail->error;
++ si->si_code = detail->code;
++
++ /* XXX We would need a protocol change for sig_post to include
++ * this information. */
++ si->si_pid = -1;
++ si->si_uid = -1;
++
++ /* Address of the faulting instruction or memory access. */
++ if (detail->exc == EXC_BAD_ACCESS)
++ si->si_addr = (void *) detail->exc_subcode;
++ else
++ si->si_addr = (void *) state->basic.eip;
++
++ /* XXX On SIGCHLD, this should be the exit status of the child
++ * process. We would need a protocol change for the proc server
++ * to send this information along with the signal. */
++ si->si_status = 0;
++
++ si->si_band = 0; /* SIGPOLL is not supported yet. */
++ si->si_value.sival_int = 0; /* sigqueue() is not supported yet. */
++}
++
++/* Fill in a ucontext_t structure SA_SIGINFO-enabled handlers. */
++static void fill_ucontext (ucontext_t *uc, const struct sigcontext *sc)
++{
++ uc->uc_flags = 0;
++ uc->uc_link = NULL;
++ uc->uc_sigmask = sc->sc_mask;
++ uc->uc_stack.ss_sp = (__ptr_t) sc->sc_esp;
++ uc->uc_stack.ss_size = 0;
++ uc->uc_stack.ss_flags = 0;
++
++ /* Registers. */
++ memcpy (&uc->uc_mcontext.gregs[REG_GS], &sc->sc_gs,
++ (REG_TRAPNO - REG_GS) * sizeof (int));
++ uc->uc_mcontext.gregs[REG_TRAPNO] = 0;
++ uc->uc_mcontext.gregs[REG_ERR] = 0;
++ memcpy (&uc->uc_mcontext.gregs[REG_EIP], &sc->sc_eip,
++ (NGREG - REG_EIP) * sizeof (int));
++
++ /* XXX FPU state. */
++ memset (&uc->uc_mcontext.fpregs, 0, sizeof (fpregset_t));
++}
++
+ struct sigcontext *
+ _hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
+ int signo, struct hurd_signal_detail *detail,
+@@ -40,18 +93,37 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
+ extern const void _hurd_intr_rpc_msg_in_trap;
+ extern const void _hurd_intr_rpc_msg_cx_sp;
+ extern const void _hurd_intr_rpc_msg_sp_restored;
++ struct sigaction *action;
+ void *volatile sigsp;
+ struct sigcontext *scp;
+ struct
+ {
+ int signo;
+- long int sigcode;
+- struct sigcontext *scp; /* Points to ctx, below. */
++ union
++ {
++ /* Extra arguments for traditional signal handlers */
++ struct
++ {
++ long int sigcode;
++ struct sigcontext *scp; /* Points to ctx, below. */
++ } legacy;
++
++ /* Extra arguments for SA_SIGINFO handlers */
++ struct
++ {
++ siginfo_t *siginfop; /* Points to siginfo, below. */
++ ucontext_t *uctxp; /* Points to uctx, below. */
++ } posix;
++ };
+ void *sigreturn_addr;
+ void *sigreturn_returns_here;
+ struct sigcontext *return_scp; /* Same; arg to sigreturn. */
++
++ /* NB: sigreturn assumes link is next to ctx. */
+ struct sigcontext ctx;
+ struct hurd_userlink link;
++ ucontext_t ucontext;
++ siginfo_t siginfo;
+ } *stackframe;
+
+ if (ss->context)
+@@ -143,15 +215,9 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
+ = &stackframe->link.thread.next;
+ ss->active_resources = &stackframe->link;
+
+- /* Set up the arguments for the signal handler. */
+- stackframe->signo = signo;
+- stackframe->sigcode = detail->code;
+- stackframe->scp = stackframe->return_scp = scp = &stackframe->ctx;
+- stackframe->sigreturn_addr = &__sigreturn;
+- stackframe->sigreturn_returns_here = firewall; /* Crash on return. */
+-
+ /* Set up the sigcontext from the current state of the thread. */
+
++ scp = &stackframe->ctx;
+ scp->sc_onstack = ss->sigaltstack.ss_flags & SS_ONSTACK ? 1 : 0;
+
+ /* struct sigcontext is laid out so that starting at sc_gs mimics a
+@@ -165,6 +231,35 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
+ &state->fpu, &scp->sc_i386_float_state,
+ sizeof (state->fpu));
+
++ /* Set up the arguments for the signal handler. */
++ stackframe->signo = signo;
++ if (action->sa_flags & SA_SIGINFO)
++ {
++ stackframe->posix.siginfop = &stackframe->siginfo;
++ stackframe->posix.uctxp = &stackframe->ucontext;
++ fill_siginfo (&stackframe->siginfo, signo, detail, state);
++ fill_ucontext (&stackframe->ucontext, scp);
++ }
++ else
++ {
++ if (detail->exc)
++ {
++ int nsigno;
++ _hurd_exception2signal_legacy (detail, &nsigno);
++ assert (nsigno == signo);
++ }
++ else
++ detail->code = 0;
++
++ stackframe->legacy.sigcode = detail->code;
++ stackframe->legacy.scp = &stackframe->ctx;
++ }
++
++ /* Set up the bottom of the stack. */
++ stackframe->sigreturn_addr = &__sigreturn;
++ stackframe->sigreturn_returns_here = firewall; /* Crash on return. */
++ stackframe->return_scp = &stackframe->ctx;
++
+ _hurdsig_end_catch_fault ();
+
+ if (! ok)
+diff --git a/sysdeps/mach/hurd/kill.c b/sysdeps/mach/hurd/kill.c
+index a9946e0..ac7ffc7 100644
+--- a/sysdeps/mach/hurd/kill.c
++++ b/sysdeps/mach/hurd/kill.c
+@@ -65,7 +65,7 @@ __kill (pid_t pid, int sig)
+ {
+ if (msgport != MACH_PORT_NULL)
+ /* Send a signal message to his message port. */
+- return __msg_sig_post (msgport, sig, 0, refport);
++ return __msg_sig_post (msgport, sig, SI_USER, refport);
+
+ /* The process has no message port. Perhaps try direct
+ frobnication of the task. */
+diff --git a/sysdeps/mach/hurd/setitimer.c b/sysdeps/mach/hurd/setitimer.c
+index fec64a8..c82bfcd 100644
+--- a/sysdeps/mach/hurd/setitimer.c
++++ b/sysdeps/mach/hurd/setitimer.c
+@@ -105,7 +105,7 @@ timer_thread (void)
+ __msg_sig_post_request (_hurd_msgport,
+ _hurd_itimer_port,
+ MACH_MSG_TYPE_MAKE_SEND_ONCE,
+- SIGALRM, 0, __mach_task_self ());
++ SIGALRM, SI_TIMER, __mach_task_self ());
+ break;
+
+ case MACH_RCV_INTERRUPTED:
+--
+tg: (2ec583b..) t/hurdsig-SA_SIGINFO (depends on: t/hurdsig-global-dispositions)
Copied: glibc-package/trunk/debian/patches/hurd-i386/tg-hurdsig-fixes-2.diff (from rev 5168, glibc-package/trunk/debian/patches/hurd-i386/submitted-hurdsig-fixes-2.diff)
===================================================================
--- glibc-package/trunk/debian/patches/hurd-i386/tg-hurdsig-fixes-2.diff (rev 0)
+++ glibc-package/trunk/debian/patches/hurd-i386/tg-hurdsig-fixes-2.diff 2012-02-21 01:58:20 UTC (rev 5169)
@@ -0,0 +1,59 @@
+From: Jeremie Koenig <jk@jk.fr.eu.org>
+Subject: [PATCH] Small signal fixes
+
+ 22e7268 Hurd signals: fix sigwait for pending signals
+ da8bf5e Hurd signals: clear the pending mask in fork and spawn
+ 8e87205 Hurd signals: don't drop blocked ignored signals
+
+---
+ hurd/hurdsig.c | 4 +---
+ sysdeps/mach/hurd/fork.c | 4 +++-
+ sysdeps/mach/hurd/spawni.c | 2 +-
+ 3 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/hurd/hurdsig.c b/hurd/hurdsig.c
+index 67037e8..44e067c 100644
+--- a/hurd/hurdsig.c
++++ b/hurd/hurdsig.c
+@@ -859,9 +859,7 @@ post_signal (struct hurd_sigstate *ss,
+ }
+
+ /* Handle receipt of a blocked signal, or any signal while stopped. */
+- if (act != ignore && /* Signals ignored now are forgotten now. */
+- __sigismember (&blocked, signo) ||
+- (signo != SIGKILL && _hurd_stopped))
++ if (__sigismember (&blocked, signo) || (signo != SIGKILL && _hurd_stopped))
+ {
+ mark_pending ();
+ act = ignore;
+diff --git a/sysdeps/mach/hurd/fork.c b/sysdeps/mach/hurd/fork.c
+index bae4204..09f4321 100644
+--- a/sysdeps/mach/hurd/fork.c
++++ b/sysdeps/mach/hurd/fork.c
+@@ -648,8 +648,10 @@ __fork (void)
+ err = __USEPORT (PROC, __proc_getpids (port, &_hurd_pid, &_hurd_ppid,
+ &_hurd_orphaned));
+
+- /* Forking clears the trace flag. */
++ /* Forking clears the trace flag and pending masks. */
+ __sigemptyset (&_hurdsig_traced);
++ __sigemptyset (&_hurd_global_sigstate->pending);
++ __sigemptyset (&ss->pending);
+
+ /* Run things that want to run in the child task to set up. */
+ RUN_HOOK (_hurd_fork_child_hook, ());
+diff --git a/sysdeps/mach/hurd/spawni.c b/sysdeps/mach/hurd/spawni.c
+index c12f448..62e39eb 100644
+--- a/sysdeps/mach/hurd/spawni.c
++++ b/sysdeps/mach/hurd/spawni.c
+@@ -241,7 +241,7 @@ __spawni (pid_t *pid, const char *file,
+
+ _hurd_sigstate_lock (ss);
+ ints[INIT_SIGMASK] = ss->blocked;
+- ints[INIT_SIGPENDING] = _hurd_sigstate_pending (ss); /* XXX really? */
++ ints[INIT_SIGPENDING] = 0;
+ ints[INIT_SIGIGN] = 0;
+ /* Unless we were asked to reset all handlers to SIG_DFL,
+ pass down the set of signals that were set to SIG_IGN. */
+--
+tg: (e19a2fa..) t/hurdsig-fixes-2 (depends on: t/hurdsig-SA_SIGINFO)
Copied: glibc-package/trunk/debian/patches/hurd-i386/tg-hurdsig-fixes.diff (from rev 5168, glibc-package/trunk/debian/patches/hurd-i386/submitted-hurdsig-fixes.diff)
===================================================================
--- glibc-package/trunk/debian/patches/hurd-i386/tg-hurdsig-fixes.diff (rev 0)
+++ glibc-package/trunk/debian/patches/hurd-i386/tg-hurdsig-fixes.diff 2012-02-21 01:58:20 UTC (rev 5169)
@@ -0,0 +1,374 @@
+From: Jeremie Koenig <jk@jk.fr.eu.org>
+Subject: [PATCH] Signal code refactoring.
+
+These patches should not change the current
+behavior, although they do fix a few minor bugs which were made
+apparent in the process. They are unchanged from my previous post
+earlier this month.
+
+ 34f5960 _hurd_internal_post_signal: Split into more functions
+ 420eec9 _hurd_internal_post_signal: Scope variables more restrictively
+ 1f5accd _hurd_internal_post_signal: Split out inner functions
+ 1bb0a1d Hurd signals: refactor check_pending_signals
+ 1764465 Hurd signals: reindent
+ 28473d2 Hurd signals: make sigsuspend POSIX-conformant.
+ 26d091a Hurd signals: fix uninitialized value.
+
+---
+ hurd/hurdsig.c | 274 +++++++++++++++++++++++++++++++++-----------------------
+ 1 files changed, 161 insertions(+), 113 deletions(-)
+
+diff --git a/hurd/hurdsig.c b/hurd/hurdsig.c
+index 7a6b1d5..74a01a6 100644
+--- a/hurd/hurdsig.c
++++ b/hurd/hurdsig.c
+@@ -1,4 +1,4 @@
+-/* Copyright (C) 1991,92,93,94,95,96,97,98,99,2000,2001,2002,2005,2008
++/* Copyright (C) 1991,92,93,94,95,96,97,98,99,2000,2001,2002,2005,2008,2011
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+@@ -443,6 +443,30 @@ abort_all_rpcs (int signo, struct machine_thread_all_state *state, int live)
+ }
+ }
+
++/* Wake up any sigsuspend call that is blocking SS->thread. SS must be
++ locked. */
++static void
++wake_sigsuspend (struct hurd_sigstate *ss)
++{
++ error_t err;
++ mach_msg_header_t msg;
++
++ if (ss->suspended == MACH_PORT_NULL)
++ return;
++
++ /* There is a sigsuspend waiting. Tell it to wake up. */
++ msg.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_MAKE_SEND, 0);
++ msg.msgh_remote_port = ss->suspended;
++ msg.msgh_local_port = MACH_PORT_NULL;
++ /* These values do not matter. */
++ msg.msgh_id = 8675309; /* Jenny, Jenny. */
++ ss->suspended = MACH_PORT_NULL;
++ err = __mach_msg (&msg, MACH_SEND_MSG, sizeof msg, 0,
++ MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE,
++ MACH_PORT_NULL);
++ assert_perror (err);
++}
++
+ struct hurd_signal_preemptor *_hurdsig_preemptors = 0;
+ sigset_t _hurdsig_preempted_set;
+
+@@ -453,35 +477,18 @@ weak_alias (_hurdsig_preemptors, _hurdsig_preempters)
+ #define STOPSIGS (sigmask (SIGTTIN) | sigmask (SIGTTOU) | \
+ sigmask (SIGSTOP) | sigmask (SIGTSTP))
+
+-/* Deliver a signal. SS is not locked. */
+-void
+-_hurd_internal_post_signal (struct hurd_sigstate *ss,
+- int signo, struct hurd_signal_detail *detail,
+- mach_port_t reply_port,
+- mach_msg_type_name_t reply_port_type,
+- int untraced)
++/* Actual delivery of a single signal. Called with SS unlocked. When
++ the signal is delivered, return 1 with SS locked. If the signal is
++ being traced, return 0 with SS unlocked. */
++static int
++post_signal (struct hurd_sigstate *ss,
++ int signo, struct hurd_signal_detail *detail,
++ int untraced, void (*reply) (void))
+ {
+- error_t err;
+ struct machine_thread_all_state thread_state;
+ enum { stop, ignore, core, term, handle } act;
+- sighandler_t handler;
+- sigset_t pending;
+ int ss_suspended;
+
+- /* Reply to this sig_post message. */
+- __typeof (__msg_sig_post_reply) *reply_rpc
+- = (untraced ? __msg_sig_post_untraced_reply : __msg_sig_post_reply);
+- void reply (void)
+- {
+- error_t err;
+- if (reply_port == MACH_PORT_NULL)
+- return;
+- err = (*reply_rpc) (reply_port, reply_port_type, 0);
+- reply_port = MACH_PORT_NULL;
+- if (err != MACH_SEND_INVALID_DEST) /* Ignore dead reply port. */
+- assert_perror (err);
+- }
+-
+ /* Mark the signal as pending. */
+ void mark_pending (void)
+ {
+@@ -545,19 +552,23 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
+ ss_suspended = 1;
+ }
+
++ error_t err;
++ sighandler_t handler;
++
+ if (signo == 0)
+ {
+ if (untraced)
+- /* This is PTRACE_CONTINUE. */
+- resume ();
++ {
++ /* This is PTRACE_CONTINUE. */
++ act = ignore;
++ resume ();
++ }
+
+ /* This call is just to check for pending signals. */
+ __spin_lock (&ss->lock);
+- goto check_pending_signals;
++ return 1;
+ }
+
+- post_signal:
+-
+ thread_state.set = 0; /* We know nothing. */
+
+ __spin_lock (&ss->lock);
+@@ -620,7 +631,7 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
+ suspend ();
+ __spin_unlock (&ss->lock);
+ reply ();
+- return;
++ return 0;
+ }
+
+ handler = ss->actions[signo].sa_handler;
+@@ -863,7 +874,7 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
+ as a unit. */
+ crit ? 0 : signo, 1,
+ &thread_state, &state_changed,
+- &reply)
++ reply)
+ != MACH_PORT_NULL);
+
+ if (crit)
+@@ -949,6 +960,9 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
+ && signo != SIGILL && signo != SIGTRAP)
+ ss->actions[signo].sa_handler = SIG_DFL;
+
++ /* Any sigsuspend call must return after the handler does. */
++ wake_sigsuspend (ss);
++
+ /* Start the thread running the handler (or possibly waiting for an
+ RPC reply before running the handler). */
+ err = __thread_set_state (ss->thread, MACHINE_THREAD_STATE_FLAVOR,
+@@ -962,95 +976,129 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
+ }
+ }
+
+- /* The signal has either been ignored or is now being handled. We can
+- consider it delivered and reply to the killer. */
+- reply ();
++ return 1;
++}
+
+- /* We get here unless the signal was fatal. We still hold SS->lock.
+- Check for pending signals, and loop to post them. */
+- {
+- /* Return nonzero if SS has any signals pending we should worry about.
+- We don't worry about any pending signals if we are stopped, nor if
+- SS is in a critical section. We are guaranteed to get a sig_post
+- message before any of them become deliverable: either the SIGCONT
+- signal, or a sig_post with SIGNO==0 as an explicit poll when the
+- thread finishes its critical section. */
+- inline int signals_pending (void)
+- {
+- if (_hurd_stopped || __spin_lock_locked (&ss->critical_section_lock))
+- return 0;
+- return pending = ss->pending & ~ss->blocked;
+- }
++/* Return the set of pending signals in SS which should be delivered. */
++static sigset_t
++pending_signals (struct hurd_sigstate *ss)
++{
++ /* We don't worry about any pending signals if we are stopped, nor if
++ SS is in a critical section. We are guaranteed to get a sig_post
++ message before any of them become deliverable: either the SIGCONT
++ signal, or a sig_post with SIGNO==0 as an explicit poll when the
++ thread finishes its critical section. */
++ if (_hurd_stopped || __spin_lock_locked (&ss->critical_section_lock))
++ return 0;
+
+- check_pending_signals:
+- untraced = 0;
++ return ss->pending & ~ss->blocked;
++}
+
+- if (signals_pending ())
+- {
+- for (signo = 1; signo < NSIG; ++signo)
+- if (__sigismember (&pending, signo))
+- {
+- deliver_pending:
+- __sigdelset (&ss->pending, signo);
+- *detail = ss->pending_data[signo];
+- __spin_unlock (&ss->lock);
+- goto post_signal;
+- }
+- }
++/* Post the specified pending signals in SS and return 1. If one of
++ them is traced, abort immediately and return 0. SS must be locked on
++ entry and will be unlocked in all cases. */
++static int
++post_pending (struct hurd_sigstate *ss, sigset_t pending, void (*reply) (void))
++{
++ int signo;
++ struct hurd_signal_detail detail;
+
+- /* No pending signals left undelivered for this thread.
+- If we were sent signal 0, we need to check for pending
+- signals for all threads. */
+- if (signo == 0)
+- {
+- __spin_unlock (&ss->lock);
+- __mutex_lock (&_hurd_siglock);
+- for (ss = _hurd_sigstates; ss != NULL; ss = ss->next)
+- {
+- __spin_lock (&ss->lock);
+- for (signo = 1; signo < NSIG; ++signo)
+- if (__sigismember (&ss->pending, signo)
+- && (!__sigismember (&ss->blocked, signo)
+- /* We "deliver" immediately pending blocked signals whose
+- action might be to ignore, so that if ignored they are
+- dropped right away. */
+- || ss->actions[signo].sa_handler == SIG_IGN
+- || ss->actions[signo].sa_handler == SIG_DFL))
+- {
+- mutex_unlock (&_hurd_siglock);
+- goto deliver_pending;
+- }
+- __spin_unlock (&ss->lock);
+- }
+- __mutex_unlock (&_hurd_siglock);
+- }
+- else
++ for (signo = 1; signo < NSIG; ++signo)
++ if (__sigismember (&pending, signo))
+ {
+- /* No more signals pending; SS->lock is still locked.
+- Wake up any sigsuspend call that is blocking SS->thread. */
+- if (ss->suspended != MACH_PORT_NULL)
+- {
+- /* There is a sigsuspend waiting. Tell it to wake up. */
+- error_t err;
+- mach_msg_header_t msg;
+- msg.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_MAKE_SEND, 0);
+- msg.msgh_remote_port = ss->suspended;
+- msg.msgh_local_port = MACH_PORT_NULL;
+- /* These values do not matter. */
+- msg.msgh_id = 8675309; /* Jenny, Jenny. */
+- ss->suspended = MACH_PORT_NULL;
+- err = __mach_msg (&msg, MACH_SEND_MSG, sizeof msg, 0,
+- MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE,
+- MACH_PORT_NULL);
+- assert_perror (err);
+- }
++ __sigdelset (&ss->pending, signo);
++ detail = ss->pending_data[signo];
+ __spin_unlock (&ss->lock);
++
++ /* Will reacquire the lock, except if the signal is traced. */
++ if (! post_signal (ss, signo, &detail, 0, reply))
++ return 0;
+ }
+- }
+
+- /* All pending signals delivered to all threads.
+- Now we can send the reply message even for signal 0. */
+- reply ();
++ /* No more signals pending; SS->lock is still locked. */
++ __spin_unlock (&ss->lock);
++
++ return 1;
++}
++
++/* Post all the pending signals of all threads and return 1. If a traced
++ signal is encountered, abort immediately and return 0. */
++static int
++post_all_pending_signals (void (*reply) (void))
++{
++ struct hurd_sigstate *ss;
++ sigset_t pending;
++
++ for (;;)
++ {
++ __mutex_lock (&_hurd_siglock);
++ for (ss = _hurd_sigstates; ss != NULL; ss = ss->next)
++ {
++ __spin_lock (&ss->lock);
++
++ pending = pending_signals (ss);
++ if (pending)
++ /* post_pending() below will unlock SS. */
++ break;
++
++ __spin_unlock (&ss->lock);
++ }
++ __mutex_unlock (&_hurd_siglock);
++
++ if (! pending)
++ return 1;
++ if (! post_pending (ss, pending, reply))
++ return 0;
++ }
++}
++
++/* Deliver a signal. SS is not locked. */
++void
++_hurd_internal_post_signal (struct hurd_sigstate *ss,
++ int signo, struct hurd_signal_detail *detail,
++ mach_port_t reply_port,
++ mach_msg_type_name_t reply_port_type,
++ int untraced)
++{
++ /* Reply to this sig_post message. */
++ __typeof (__msg_sig_post_reply) *reply_rpc
++ = (untraced ? __msg_sig_post_untraced_reply : __msg_sig_post_reply);
++ void reply (void)
++ {
++ error_t err;
++ if (reply_port == MACH_PORT_NULL)
++ return;
++ err = (*reply_rpc) (reply_port, reply_port_type, 0);
++ reply_port = MACH_PORT_NULL;
++ if (err != MACH_SEND_INVALID_DEST) /* Ignore dead reply port. */
++ assert_perror (err);
++ }
++
++ if (! post_signal (ss, signo, detail, untraced, reply))
++ return;
++
++ /* The signal was neither fatal nor traced. We still hold SS->lock. */
++ if (signo != 0)
++ {
++ /* The signal has either been ignored or is now being handled. We can
++ consider it delivered and reply to the killer. */
++ reply ();
++
++ /* Post any pending signals for this thread. */
++ if (! post_pending (ss, pending_signals (ss), reply))
++ return;
++ }
++ else
++ {
++ /* We need to check for pending signals for all threads. */
++ __spin_unlock (&ss->lock);
++ if (! post_all_pending_signals (reply))
++ return;
++
++ /* All pending signals delivered to all threads.
++ Now we can send the reply message even for signal 0. */
++ reply ();
++ }
+ }
+
+ /* Decide whether REFPORT enables the sender to send us a SIGNO signal.
+--
+tg: (0234227..) t/hurdsig-fixes (depends on: baseline)
Copied: glibc-package/trunk/debian/patches/hurd-i386/tg-hurdsig-global-dispositions.diff (from rev 5168, glibc-package/trunk/debian/patches/hurd-i386/submitted-hurdsig-global-dispositions.diff)
===================================================================
--- glibc-package/trunk/debian/patches/hurd-i386/tg-hurdsig-global-dispositions.diff (rev 0)
+++ glibc-package/trunk/debian/patches/hurd-i386/tg-hurdsig-global-dispositions.diff 2012-02-21 01:58:20 UTC (rev 5169)
@@ -0,0 +1,1226 @@
+From: Jeremie Koenig <jk@jk.fr.eu.org>
+Subject: [PATCH] Global signal dispositions.
+
+Although they should not change the
+default behaviors of signals for cthread programs, these patches add
+new functions which can be used by libpthread to enable
+POSIX-conforming behavior of signals on a per-thread basis.
+
+ e407ae3 Hurd signals: implement global signal dispositions
+ 38eb4b3 Hurd signals: provide a sigstate destructor
+ 344dfd6 Hurd signals: fix sigwait() for global signals
+ fb055f2 Hurd signals: fix global untraced signals.
+
+---
+ hurd/ctty-input.c | 18 ++-
+ hurd/ctty-output.c | 18 ++-
+ hurd/hurd/signal.h | 40 ++++--
+ hurd/hurdexec.c | 11 +-
+ hurd/hurdmsg.c | 27 +---
+ hurd/hurdsig.c | 272 +++++++++++++++++++++++++++--------
+ sysdeps/mach/hurd/fork.c | 9 +-
+ sysdeps/mach/hurd/i386/sigreturn.c | 13 +-
+ sysdeps/mach/hurd/i386/trampoline.c | 8 +-
+ sysdeps/mach/hurd/sigaction.c | 18 ++--
+ sysdeps/mach/hurd/sigpending.c | 9 +-
+ sysdeps/mach/hurd/sigprocmask.c | 11 +-
+ sysdeps/mach/hurd/sigsuspend.c | 19 ++--
+ sysdeps/mach/hurd/sigwait.c | 23 ++--
+ sysdeps/mach/hurd/spawni.c | 23 ++--
+ 15 files changed, 350 insertions(+), 169 deletions(-)
+
+diff --git a/hurd/ctty-input.c b/hurd/ctty-input.c
+index ef8395a..4da33c7 100644
+--- a/hurd/ctty-input.c
++++ b/hurd/ctty-input.c
+@@ -1,5 +1,5 @@
+ /* _hurd_ctty_input -- Do an input RPC and generate SIGTTIN if necessary.
+- Copyright (C) 1995,97,99 Free Software Foundation, Inc.
++ Copyright (C) 1995,97,99,2011 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
+@@ -44,12 +44,15 @@ _hurd_ctty_input (io_t port, io_t ctty, error_t (*rpc) (io_t))
+ else
+ {
+ struct hurd_sigstate *ss = _hurd_self_sigstate ();
+- __spin_lock (&ss->lock);
++ struct sigaction *actions;
++
++ _hurd_sigstate_lock (ss);
++ actions = _hurd_sigstate_actions (ss);
+ if (__sigismember (&ss->blocked, SIGTTIN) ||
+- ss->actions[SIGTTIN].sa_handler == SIG_IGN)
++ actions[SIGTTIN].sa_handler == SIG_IGN)
+ /* We are blocking or ignoring SIGTTIN. Just fail. */
+ err = EIO;
+- __spin_unlock (&ss->lock);
++ _hurd_sigstate_unlock (ss);
+
+ if (err == EBACKGROUND)
+ {
+@@ -66,10 +69,11 @@ _hurd_ctty_input (io_t port, io_t ctty, error_t (*rpc) (io_t))
+ SIGTTIN or resumed after being stopped. Now this is
+ still a "system call", so check to see if we should
+ restart it. */
+- __spin_lock (&ss->lock);
+- if (!(ss->actions[SIGTTIN].sa_flags & SA_RESTART))
++ _hurd_sigstate_lock (ss);
++ actions = _hurd_sigstate_actions (ss);
++ if (!(actions[SIGTTIN].sa_flags & SA_RESTART))
+ err = EINTR;
+- __spin_unlock (&ss->lock);
++ _hurd_sigstate_unlock (ss);
+ }
+ }
+ }
+diff --git a/hurd/ctty-output.c b/hurd/ctty-output.c
+index 92ab95a..6e4bd74 100644
+--- a/hurd/ctty-output.c
++++ b/hurd/ctty-output.c
+@@ -1,5 +1,5 @@
+ /* _hurd_ctty_output -- Do an output RPC and generate SIGTTOU if necessary.
+- Copyright (C) 1995,97,99 Free Software Foundation, Inc.
++ Copyright (C) 1995,97,99,2011 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
+@@ -35,16 +35,19 @@ _hurd_ctty_output (io_t port, io_t ctty, error_t (*rpc) (io_t))
+
+ do
+ {
++ struct sigaction *actions;
++
+ /* Don't use the ctty io port if we are blocking or ignoring
+ SIGTTOU. We redo this check at the top of the loop in case
+ the signal handler changed the state. */
+- __spin_lock (&ss->lock);
++ _hurd_sigstate_lock (ss);
++ actions = _hurd_sigstate_actions (ss);
+ if (__sigismember (&ss->blocked, SIGTTOU) ||
+- ss->actions[SIGTTOU].sa_handler == SIG_IGN)
++ actions[SIGTTOU].sa_handler == SIG_IGN)
+ err = EIO;
+ else
+ err = 0;
+- __spin_unlock (&ss->lock);
++ _hurd_sigstate_unlock (ss);
+
+ if (err)
+ return (*rpc) (port);
+@@ -71,10 +74,11 @@ _hurd_ctty_output (io_t port, io_t ctty, error_t (*rpc) (io_t))
+ SIGTTOU or resumed after being stopped. Now this is
+ still a "system call", so check to see if we should
+ restart it. */
+- __spin_lock (&ss->lock);
+- if (!(ss->actions[SIGTTOU].sa_flags & SA_RESTART))
++ _hurd_sigstate_lock (ss);
++ actions = _hurd_sigstate_actions (ss);
++ if (!(actions[SIGTTOU].sa_flags & SA_RESTART))
+ err = EINTR;
+- __spin_unlock (&ss->lock);
++ _hurd_sigstate_unlock (ss);
+ }
+ }
+ /* If the last RPC generated a SIGTTOU, loop to try it again. */
+diff --git a/hurd/hurd/signal.h b/hurd/hurd/signal.h
+index 21e30c5..1c4733a 100644
+--- a/hurd/hurd/signal.h
++++ b/hurd/hurd/signal.h
+@@ -1,5 +1,5 @@
+ /* Implementing POSIX.1 signals under the Hurd.
+- Copyright (C) 1993,94,95,96,98,99,2002,2007,2008
++ Copyright (C) 1993,94,95,96,98,99,2002,2007,2008,2011
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+@@ -71,7 +71,13 @@ struct hurd_sigstate
+
+ sigset_t blocked; /* What signals are blocked. */
+ sigset_t pending; /* Pending signals, possibly blocked. */
++
++ /* Signal handlers. ACTIONS[0] is used to mark the threads with POSIX
++ semantics: if sa_handler is SIG_IGN instead of SIG_DFL, this thread
++ will receive global signals and use the process-wide action vector
++ instead of this one. */
+ struct sigaction actions[NSIG];
++
+ struct sigaltstack sigaltstack;
+
+ /* Chain of thread-local signal preemptors; see <hurd/sigpreempt.h>.
+@@ -127,6 +133,26 @@ extern struct hurd_sigstate *_hurd_self_sigstate (void)
+ by different threads. */
+ __attribute__ ((__const__));
+
++/* Process-wide signal state. */
++
++extern struct hurd_sigstate *_hurd_global_sigstate;
++
++/* Mark the given thread as a process-wide signal receiver. */
++
++extern void _hurd_sigstate_set_global_rcv (struct hurd_sigstate *ss);
++
++/* A thread can either use its own action vector and pending signal set
++ or use the global ones, depending on wether it has been marked as a
++ global receiver. The accessors below take that into account. */
++
++extern void _hurd_sigstate_lock (struct hurd_sigstate *ss);
++extern struct sigaction *_hurd_sigstate_actions (struct hurd_sigstate *ss);
++extern sigset_t _hurd_sigstate_pending (const struct hurd_sigstate *ss);
++extern void _hurd_sigstate_unlock (struct hurd_sigstate *ss);
++
++/* Used by libpthread to remove stale sigstate structures. */
++extern void _hurd_sigstate_delete (thread_t thread);
++
+ #ifndef _HURD_SIGNAL_H_EXTERN_INLINE
+ #define _HURD_SIGNAL_H_EXTERN_INLINE __extern_inline
+ #endif
+@@ -150,12 +176,6 @@ extern thread_t _hurd_msgport_thread;
+
+ extern mach_port_t _hurd_msgport;
+
+-
+-/* Thread to receive process-global signals. */
+-
+-extern thread_t _hurd_sigthread;
+-
+-
+ /* Resource limit on core file size. Enforced by hurdsig.c. */
+ extern int _hurd_core_limit;
+
+@@ -203,10 +223,10 @@ _hurd_critical_section_unlock (void *our_lock)
+ /* It was us who acquired the critical section lock. Unlock it. */
+ struct hurd_sigstate *ss = our_lock;
+ sigset_t pending;
+- __spin_lock (&ss->lock);
++ _hurd_sigstate_lock (ss);
+ __spin_unlock (&ss->critical_section_lock);
+- pending = ss->pending & ~ss->blocked;
+- __spin_unlock (&ss->lock);
++ pending = _hurd_sigstate_pending(ss) & ~ss->blocked;
++ _hurd_sigstate_unlock (ss);
+ if (! __sigisemptyset (&pending))
+ /* There are unblocked signals pending, which weren't
+ delivered because we were in the critical section.
+diff --git a/hurd/hurdexec.c b/hurd/hurdexec.c
+index beae869..ee3162f 100644
+--- a/hurd/hurdexec.c
++++ b/hurd/hurdexec.c
+@@ -1,4 +1,4 @@
+-/* Copyright (C) 1991,92,93,94,95,96,97,99,2001,02
++/* Copyright (C) 1991,92,93,94,95,96,97,99,2001,2002,2011
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+@@ -109,12 +109,13 @@ _hurd_exec (task_t task, file_t file,
+ assert (! __spin_lock_locked (&ss->critical_section_lock));
+ __spin_lock (&ss->critical_section_lock);
+
+- __spin_lock (&ss->lock);
++ _hurd_sigstate_lock (ss);
++ struct sigaction *actions = _hurd_sigstate_actions (ss);
+ ints[INIT_SIGMASK] = ss->blocked;
+- ints[INIT_SIGPENDING] = ss->pending;
++ ints[INIT_SIGPENDING] = _hurd_sigstate_pending (ss);
+ ints[INIT_SIGIGN] = 0;
+ for (i = 1; i < NSIG; ++i)
+- if (ss->actions[i].sa_handler == SIG_IGN)
++ if (actions[i].sa_handler == SIG_IGN)
+ ints[INIT_SIGIGN] |= __sigmask (i);
+
+ /* We hold the sigstate lock until the exec has failed so that no signal
+@@ -125,7 +126,7 @@ _hurd_exec (task_t task, file_t file,
+ critical section flag avoids anything we call trying to acquire the
+ sigstate lock. */
+
+- __spin_unlock (&ss->lock);
++ _hurd_sigstate_unlock (ss);
+
+ /* Pack up the descriptor table to give the new program. */
+ __mutex_lock (&_hurd_dtable_lock);
+diff --git a/hurd/hurdmsg.c b/hurd/hurdmsg.c
+index ffcce61..fdc7551 100644
+--- a/hurd/hurdmsg.c
++++ b/hurd/hurdmsg.c
+@@ -1,4 +1,5 @@
+-/* Copyright (C) 1992, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
++/* Copyright (C) 1992, 1994, 1995, 1996, 1997, 2011
++ 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
+@@ -122,17 +123,9 @@ get_int (int which, int *value)
+ case INIT_UMASK:
+ *value = _hurd_umask;
+ return 0;
+- case INIT_SIGMASK:
+- {
+- struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread);
+- __spin_lock (&ss->lock);
+- *value = ss->blocked;
+- __spin_unlock (&ss->lock);
+- return 0;
+- }
+ case INIT_SIGPENDING:
+ {
+- struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread);
++ struct hurd_sigstate *ss = _hurd_global_sigstate;
+ __spin_lock (&ss->lock);
+ *value = ss->pending;
+ __spin_unlock (&ss->lock);
+@@ -140,7 +133,7 @@ get_int (int which, int *value)
+ }
+ case INIT_SIGIGN:
+ {
+- struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread);
++ struct hurd_sigstate *ss = _hurd_global_sigstate;
+ sigset_t ign;
+ int sig;
+ __spin_lock (&ss->lock);
+@@ -208,17 +201,9 @@ set_int (int which, int value)
+ return 0;
+
+ /* These are pretty odd things to do. But you asked for it. */
+- case INIT_SIGMASK:
+- {
+- struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread);
+- __spin_lock (&ss->lock);
+- ss->blocked = value;
+- __spin_unlock (&ss->lock);
+- return 0;
+- }
+ case INIT_SIGPENDING:
+ {
+- struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread);
++ struct hurd_sigstate *ss = _hurd_global_sigstate;
+ __spin_lock (&ss->lock);
+ ss->pending = value;
+ __spin_unlock (&ss->lock);
+@@ -226,7 +211,7 @@ set_int (int which, int value)
+ }
+ case INIT_SIGIGN:
+ {
+- struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread);
++ struct hurd_sigstate *ss = _hurd_global_sigstate;
+ int sig;
+ const sigset_t ign = value;
+ __spin_lock (&ss->lock);
+diff --git a/hurd/hurdsig.c b/hurd/hurdsig.c
+index 74a01a6..67037e8 100644
+--- a/hurd/hurdsig.c
++++ b/hurd/hurdsig.c
+@@ -44,9 +44,6 @@ mach_port_t _hurd_msgport;
+ /* Thread listening on it. */
+ thread_t _hurd_msgport_thread;
+
+-/* Thread which receives task-global signals. */
+-thread_t _hurd_sigthread;
+-
+ /* These are set up by _hurdsig_init. */
+ unsigned long int __hurd_sigthread_stack_base;
+ unsigned long int __hurd_sigthread_stack_end;
+@@ -55,6 +52,9 @@ unsigned long int *__hurd_sigthread_variables;
+ /* Linked-list of per-thread signal state. */
+ struct hurd_sigstate *_hurd_sigstates;
+
++/* Sigstate for the task-global signals. */
++struct hurd_sigstate *_hurd_global_sigstate;
++
+ /* Timeout for RPC's after interrupt_operation. */
+ mach_msg_timeout_t _hurd_interrupted_rpc_timeout = 3000;
+
+@@ -83,7 +83,7 @@ _hurd_thread_sigstate (thread_t thread)
+ {
+ ss = malloc (sizeof (*ss));
+ if (ss == NULL)
+- __libc_fatal ("hurd: Can't allocate thread sigstate\n");
++ __libc_fatal ("hurd: Can't allocate sigstate\n");
+ ss->thread = thread;
+ __spin_lock_init (&ss->lock);
+
+@@ -96,16 +96,19 @@ _hurd_thread_sigstate (thread_t thread)
+ ss->intr_port = MACH_PORT_NULL;
+ ss->context = NULL;
+
+- /* Initialize the sigaction vector from the default signal receiving
+- thread's state, and its from the system defaults. */
+- if (thread == _hurd_sigthread)
+- default_sigaction (ss->actions);
++ if (thread == MACH_PORT_NULL)
++ {
++ /* Process-wide sigstate, use the system defaults. */
++ default_sigaction (ss->actions);
++
++ /* The global sigstate is not added to the _hurd_sigstates list.
++ It is created with _hurd_thread_sigstate (MACH_PORT_NULL)
++ but should be accessed through _hurd_global_sigstate. */
++ }
+ else
+ {
+- struct hurd_sigstate *s;
+- for (s = _hurd_sigstates; s != NULL; s = s->next)
+- if (s->thread == _hurd_sigthread)
+- break;
++ /* Use the global actions as a default for new threads. */
++ struct hurd_sigstate *s = _hurd_global_sigstate;
+ if (s)
+ {
+ __spin_lock (&s->lock);
+@@ -114,14 +117,108 @@ _hurd_thread_sigstate (thread_t thread)
+ }
+ else
+ default_sigaction (ss->actions);
+- }
+
+- ss->next = _hurd_sigstates;
+- _hurd_sigstates = ss;
++ ss->next = _hurd_sigstates;
++ _hurd_sigstates = ss;
++ }
+ }
+ __mutex_unlock (&_hurd_siglock);
+ return ss;
+ }
++
++/* Destroy a sigstate structure. Called by libpthread just before the
++ * corresponding thread is terminated (the kernel thread port must remain valid
++ * until this function is called.) */
++void
++_hurd_sigstate_delete (thread_t thread)
++{
++ struct hurd_sigstate **ssp, *ss;
++
++ __mutex_lock (&_hurd_siglock);
++ for (ssp = &_hurd_sigstates; *ssp; ssp = &(*ssp)->next)
++ if ((*ssp)->thread == thread)
++ break;
++
++ ss = *ssp;
++ if (ss)
++ *ssp = ss->next;
++
++ __mutex_unlock (&_hurd_siglock);
++ if (ss)
++ free (ss);
++}
++
++/* Make SS a global receiver, with pthread signal semantics. */
++void
++_hurd_sigstate_set_global_rcv (struct hurd_sigstate *ss)
++{
++ assert (ss->thread != MACH_PORT_NULL);
++ ss->actions[0].sa_handler = SIG_IGN;
++}
++
++/* Check whether SS is a global receiver. */
++static int
++sigstate_is_global_rcv (const struct hurd_sigstate *ss)
++{
++ return ss->actions[0].sa_handler == SIG_IGN;
++}
++
++/* Lock/unlock a hurd_sigstate structure. If the accessors below require
++ it, the global sigstate will be locked as well. */
++void
++_hurd_sigstate_lock (struct hurd_sigstate *ss)
++{
++ if (sigstate_is_global_rcv (ss))
++ __spin_lock (&_hurd_global_sigstate->lock);
++ __spin_lock (&ss->lock);
++}
++void
++_hurd_sigstate_unlock (struct hurd_sigstate *ss)
++{
++ __spin_unlock (&ss->lock);
++ if (sigstate_is_global_rcv (ss))
++ __spin_unlock (&_hurd_global_sigstate->lock);
++}
++
++/* Retreive a thread's full set of pending signals, including the global
++ ones if appropriate. SS must be locked. */
++sigset_t
++_hurd_sigstate_pending (const struct hurd_sigstate *ss)
++{
++ sigset_t pending = ss->pending;
++ if (sigstate_is_global_rcv (ss))
++ __sigorset (&pending, &pending, &_hurd_global_sigstate->pending);
++ return pending;
++}
++
++/* Clear a pending signal and return the associated detailed
++ signal information. SS must be locked, and must have signal SIGNO
++ pending, either directly or through the global sigstate. */
++static struct hurd_signal_detail
++sigstate_clear_pending (struct hurd_sigstate *ss, int signo)
++{
++ if (sigstate_is_global_rcv (ss)
++ && __sigismember (&_hurd_global_sigstate->pending, signo))
++ {
++ __sigdelset (&_hurd_global_sigstate->pending, signo);
++ return _hurd_global_sigstate->pending_data[signo];
++ }
++
++ assert (__sigismember (&ss->pending, signo));
++ __sigdelset (&ss->pending, signo);
++ return ss->pending_data[signo];
++}
++
++/* Retreive a thread's action vector. SS must be locked. */
++struct sigaction *
++_hurd_sigstate_actions (struct hurd_sigstate *ss)
++{
++ if (sigstate_is_global_rcv (ss))
++ return _hurd_global_sigstate->actions;
++ else
++ return ss->actions;
++}
++
+
+ /* Signal delivery itself is on this page. */
+
+@@ -216,6 +313,8 @@ static void
+ abort_thread (struct hurd_sigstate *ss, struct machine_thread_all_state *state,
+ void (*reply) (void))
+ {
++ assert (ss->thread != MACH_PORT_NULL);
++
+ if (!(state->set & THREAD_ABORTED))
+ {
+ error_t err = __thread_abort (ss->thread);
+@@ -355,7 +454,7 @@ _hurdsig_abort_rpcs (struct hurd_sigstate *ss, int signo, int sigthread,
+ call above will retry their RPCs unless we clear SS->intr_port.
+ So we clear it for the thread taking a signal when SA_RESTART is
+ clear, so that its call returns EINTR. */
+- if (! signo || !(ss->actions[signo].sa_flags & SA_RESTART))
++ if (! signo || !(_hurd_sigstate_actions (ss) [signo].sa_flags & SA_RESTART))
+ ss->intr_port = MACH_PORT_NULL;
+ }
+
+@@ -478,9 +577,11 @@ weak_alias (_hurdsig_preemptors, _hurdsig_preempters)
+ sigmask (SIGSTOP) | sigmask (SIGTSTP))
+
+ /* Actual delivery of a single signal. Called with SS unlocked. When
+- the signal is delivered, return 1 with SS locked. If the signal is
+- being traced, return 0 with SS unlocked. */
+-static int
++ the signal is delivered, return SS, locked (or, if SS was originally
++ _hurd_global_sigstate, the sigstate of the actual thread the signal
++ was delivered to). If the signal is being traced, return NULL with
++ SS unlocked. */
++static struct hurd_sigstate *
+ post_signal (struct hurd_sigstate *ss,
+ int signo, struct hurd_signal_detail *detail,
+ int untraced, void (*reply) (void))
+@@ -533,8 +634,12 @@ post_signal (struct hurd_sigstate *ss,
+ assert_perror (err);
+ for (i = 0; i < nthreads; ++i)
+ {
+- if (threads[i] != _hurd_msgport_thread &&
+- (act != handle || threads[i] != ss->thread))
++ if (act == handle && threads[i] == ss->thread)
++ {
++ /* The thread that will run the handler is kept suspended. */
++ ss_suspended = 1;
++ }
++ else if (threads[i] != _hurd_msgport_thread)
+ {
+ err = __thread_resume (threads[i]);
+ assert_perror (err);
+@@ -547,9 +652,6 @@ post_signal (struct hurd_sigstate *ss,
+ (vm_address_t) threads,
+ nthreads * sizeof *threads);
+ _hurd_stopped = 0;
+- if (act == handle)
+- /* The thread that will run the handler is already suspended. */
+- ss_suspended = 1;
+ }
+
+ error_t err;
+@@ -565,13 +667,43 @@ post_signal (struct hurd_sigstate *ss,
+ }
+
+ /* This call is just to check for pending signals. */
+- __spin_lock (&ss->lock);
+- return 1;
++ _hurd_sigstate_lock (ss);
++ return ss;
+ }
+
+ thread_state.set = 0; /* We know nothing. */
+
+- __spin_lock (&ss->lock);
++ _hurd_sigstate_lock (ss);
++
++ /* If this is a global signal, try to find a thread ready to accept
++ it right away. This is especially important for untraced signals,
++ since going through the global pending mask would de-untrace them. */
++ if (ss->thread == MACH_PORT_NULL)
++ {
++ struct hurd_sigstate *rss;
++
++ __mutex_lock (&_hurd_siglock);
++ for (rss = _hurd_sigstates; rss != NULL; rss = rss->next)
++ {
++ if (! sigstate_is_global_rcv (rss))
++ continue;
++
++ /* The global sigstate is already locked. */
++ __spin_lock (&rss->lock);
++ if (! __sigismember (&rss->blocked, signo))
++ {
++ ss = rss;
++ break;
++ }
++ __spin_unlock (&rss->lock);
++ }
++ __mutex_unlock (&_hurd_siglock);
++ }
++
++ /* We want the preemptors to be able to update the blocking mask
++ without affecting the delivery of this signal, so we save the
++ current value to test against later. */
++ sigset_t blocked = ss->blocked;
+
+ /* Check for a preempted signal. Preempted signals can arrive during
+ critical sections. */
+@@ -629,12 +761,12 @@ post_signal (struct hurd_sigstate *ss,
+ mark_pending ();
+ else
+ suspend ();
+- __spin_unlock (&ss->lock);
++ _hurd_sigstate_unlock (ss);
+ reply ();
+- return 0;
++ return NULL;
+ }
+
+- handler = ss->actions[signo].sa_handler;
++ handler = _hurd_sigstate_actions (ss) [signo].sa_handler;
+
+ if (handler == SIG_DFL)
+ /* Figure out the default action for this signal. */
+@@ -728,7 +860,7 @@ post_signal (struct hurd_sigstate *ss,
+
+ /* Handle receipt of a blocked signal, or any signal while stopped. */
+ if (act != ignore && /* Signals ignored now are forgotten now. */
+- __sigismember (&ss->blocked, signo) ||
++ __sigismember (&blocked, signo) ||
+ (signo != SIGKILL && _hurd_stopped))
+ {
+ mark_pending ();
+@@ -764,6 +896,7 @@ post_signal (struct hurd_sigstate *ss,
+ now's the time to set it going. */
+ if (ss_suspended)
+ {
++ assert (ss->thread != MACH_PORT_NULL);
+ err = __thread_resume (ss->thread);
+ assert_perror (err);
+ ss_suspended = 0;
+@@ -808,6 +941,8 @@ post_signal (struct hurd_sigstate *ss,
+ struct sigcontext *scp, ocontext;
+ int wait_for_reply, state_changed;
+
++ assert (ss->thread != MACH_PORT_NULL);
++
+ /* Stop the thread and abort its pending RPC operations. */
+ if (! ss_suspended)
+ {
+@@ -942,23 +1077,25 @@ post_signal (struct hurd_sigstate *ss,
+ }
+ }
+
++ struct sigaction *action = & _hurd_sigstate_actions (ss) [signo];
++
+ /* Backdoor extra argument to signal handler. */
+ scp->sc_error = detail->error;
+
+ /* Block requested signals while running the handler. */
+ scp->sc_mask = ss->blocked;
+- __sigorset (&ss->blocked, &ss->blocked, &ss->actions[signo].sa_mask);
++ __sigorset (&ss->blocked, &ss->blocked, &action->sa_mask);
+
+ /* Also block SIGNO unless we're asked not to. */
+- if (! (ss->actions[signo].sa_flags & (SA_RESETHAND | SA_NODEFER)))
++ if (! (action->sa_flags & (SA_RESETHAND | SA_NODEFER)))
+ __sigaddset (&ss->blocked, signo);
+
+ /* Reset to SIG_DFL if requested. SIGILL and SIGTRAP cannot
+ be automatically reset when delivered; the system silently
+ enforces this restriction. */
+- if (ss->actions[signo].sa_flags & SA_RESETHAND
++ if (action->sa_flags & SA_RESETHAND
+ && signo != SIGILL && signo != SIGTRAP)
+- ss->actions[signo].sa_handler = SIG_DFL;
++ action->sa_handler = SIG_DFL;
+
+ /* Any sigsuspend call must return after the handler does. */
+ wake_sigsuspend (ss);
+@@ -976,7 +1113,7 @@ post_signal (struct hurd_sigstate *ss,
+ }
+ }
+
+- return 1;
++ return ss;
+ }
+
+ /* Return the set of pending signals in SS which should be delivered. */
+@@ -991,7 +1128,7 @@ pending_signals (struct hurd_sigstate *ss)
+ if (_hurd_stopped || __spin_lock_locked (&ss->critical_section_lock))
+ return 0;
+
+- return ss->pending & ~ss->blocked;
++ return _hurd_sigstate_pending (ss) & ~ss->blocked;
+ }
+
+ /* Post the specified pending signals in SS and return 1. If one of
+@@ -1003,12 +1140,15 @@ post_pending (struct hurd_sigstate *ss, sigset_t pending, void (*reply) (void))
+ int signo;
+ struct hurd_signal_detail detail;
+
++ /* Make sure SS corresponds to an actual thread, since we assume it won't
++ change in post_signal. */
++ assert (ss->thread != MACH_PORT_NULL);
++
+ for (signo = 1; signo < NSIG; ++signo)
+ if (__sigismember (&pending, signo))
+ {
+- __sigdelset (&ss->pending, signo);
+- detail = ss->pending_data[signo];
+- __spin_unlock (&ss->lock);
++ detail = sigstate_clear_pending (ss, signo);
++ _hurd_sigstate_unlock (ss);
+
+ /* Will reacquire the lock, except if the signal is traced. */
+ if (! post_signal (ss, signo, &detail, 0, reply))
+@@ -1016,7 +1156,7 @@ post_pending (struct hurd_sigstate *ss, sigset_t pending, void (*reply) (void))
+ }
+
+ /* No more signals pending; SS->lock is still locked. */
+- __spin_unlock (&ss->lock);
++ _hurd_sigstate_unlock (ss);
+
+ return 1;
+ }
+@@ -1034,14 +1174,14 @@ post_all_pending_signals (void (*reply) (void))
+ __mutex_lock (&_hurd_siglock);
+ for (ss = _hurd_sigstates; ss != NULL; ss = ss->next)
+ {
+- __spin_lock (&ss->lock);
++ _hurd_sigstate_lock (ss);
+
+ pending = pending_signals (ss);
+ if (pending)
+ /* post_pending() below will unlock SS. */
+ break;
+
+- __spin_unlock (&ss->lock);
++ _hurd_sigstate_unlock (ss);
+ }
+ __mutex_unlock (&_hurd_siglock);
+
+@@ -1074,11 +1214,12 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
+ assert_perror (err);
+ }
+
+- if (! post_signal (ss, signo, detail, untraced, reply))
++ ss = post_signal (ss, signo, detail, untraced, reply);
++ if (! ss)
+ return;
+
+ /* The signal was neither fatal nor traced. We still hold SS->lock. */
+- if (signo != 0)
++ if (signo != 0 && ss->thread != MACH_PORT_NULL)
+ {
+ /* The signal has either been ignored or is now being handled. We can
+ consider it delivered and reply to the killer. */
+@@ -1090,8 +1231,9 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
+ }
+ else
+ {
+- /* We need to check for pending signals for all threads. */
+- __spin_unlock (&ss->lock);
++ /* If this was a process-wide signal or a poll request, we need
++ to check for pending signals for all threads. */
++ _hurd_sigstate_unlock (ss);
+ if (! post_all_pending_signals (reply))
+ return;
+
+@@ -1217,9 +1359,10 @@ _S_msg_sig_post (mach_port_t me,
+ d.code = sigcode;
+ d.exc = 0;
+
+- /* Post the signal to the designated signal-receiving thread. This will
+- reply when the signal can be considered delivered. */
+- _hurd_internal_post_signal (_hurd_thread_sigstate (_hurd_sigthread),
++ /* Post the signal to a global receiver thread (or mark it pending in
++ the global sigstate). This will reply when the signal can be
++ considered delivered. */
++ _hurd_internal_post_signal (_hurd_global_sigstate,
+ signo, &d, reply_port, reply_port_type,
+ 0); /* Stop if traced. */
+
+@@ -1247,7 +1390,7 @@ _S_msg_sig_post_untraced (mach_port_t me,
+
+ /* Post the signal to the designated signal-receiving thread. This will
+ reply when the signal can be considered delivered. */
+- _hurd_internal_post_signal (_hurd_thread_sigstate (_hurd_sigthread),
++ _hurd_internal_post_signal (_hurd_global_sigstate,
+ signo, &d, reply_port, reply_port_type,
+ 1); /* Untraced flag. */
+
+@@ -1258,8 +1401,8 @@ extern void __mig_init (void *);
+
+ #include <mach/task_special_ports.h>
+
+-/* Initialize the message port and _hurd_sigthread and start the signal
+- thread. */
++/* Initialize the message port, _hurd_global_sigstate, and start the
++ signal thread. */
+
+ void
+ _hurdsig_init (const int *intarray, size_t intarraysize)
+@@ -1282,27 +1425,34 @@ _hurdsig_init (const int *intarray, size_t intarraysize)
+ MACH_MSG_TYPE_MAKE_SEND);
+ assert_perror (err);
+
++ /* Initialize the global signal state. */
++ _hurd_global_sigstate = _hurd_thread_sigstate (MACH_PORT_NULL);
++
++ /* We block all signals, and let actual threads pull them from the
++ pending mask. */
++ __sigfillset(& _hurd_global_sigstate->blocked);
++
+ /* Initialize the main thread's signal state. */
+ ss = _hurd_self_sigstate ();
+
+- /* Copy inherited values from our parent (or pre-exec process state)
+- into the signal settings of the main thread. */
++ /* Mark it as a process-wide signal receiver. Threads in this set use
++ the common action vector in _hurd_global_sigstate. */
++ _hurd_sigstate_set_global_rcv (ss);
++
++ /* Copy inherited signal settings from our parent (or pre-exec process
++ state) */
+ if (intarraysize > INIT_SIGMASK)
+ ss->blocked = intarray[INIT_SIGMASK];
+ if (intarraysize > INIT_SIGPENDING)
+- ss->pending = intarray[INIT_SIGPENDING];
++ _hurd_global_sigstate->pending = intarray[INIT_SIGPENDING];
+ if (intarraysize > INIT_SIGIGN && intarray[INIT_SIGIGN] != 0)
+ {
+ int signo;
+ for (signo = 1; signo < NSIG; ++signo)
+ if (intarray[INIT_SIGIGN] & __sigmask(signo))
+- ss->actions[signo].sa_handler = SIG_IGN;
++ _hurd_global_sigstate->actions[signo].sa_handler = SIG_IGN;
+ }
+
+- /* Set the default thread to receive task-global signals
+- to this one, the main (first) user thread. */
+- _hurd_sigthread = ss->thread;
+-
+ /* Start the signal thread listening on the message port. */
+
+ if (__hurd_threadvar_stack_mask == 0)
+diff --git a/sysdeps/mach/hurd/fork.c b/sysdeps/mach/hurd/fork.c
+index 66fa7e2..bae4204 100644
+--- a/sysdeps/mach/hurd/fork.c
++++ b/sysdeps/mach/hurd/fork.c
+@@ -459,6 +459,7 @@ __fork (void)
+ function, accounted for by mach_port_names (and which will thus be
+ accounted for in the child below). This extra right gets consumed
+ in the child by the store into _hurd_sigthread in the child fork. */
++ /* XXX consumed? (_hurd_sigthread is no more) */
+ if (thread_refs > 1 &&
+ (err = __mach_port_mod_refs (newtask, ss->thread,
+ MACH_PORT_RIGHT_SEND,
+@@ -616,10 +617,6 @@ __fork (void)
+ for (i = 0; i < _hurd_nports; ++i)
+ __spin_unlock (&_hurd_ports[i].lock);
+
+- /* We are one of the (exactly) two threads in this new task, we
+- will take the task-global signals. */
+- _hurd_sigthread = ss->thread;
+-
+ /* Claim our sigstate structure and unchain the rest: the
+ threads existed in the parent task but don't exist in this
+ task (the child process). Delay freeing them until later
+@@ -640,6 +637,10 @@ __fork (void)
+ _hurd_sigstates = ss;
+ __mutex_unlock (&_hurd_siglock);
+
++ /* We are one of the (exactly) two threads in this new task, we
++ will take the task-global signals. */
++ _hurd_sigstate_set_global_rcv (ss);
++
+ /* Fetch our new process IDs from the proc server. No need to
+ refetch our pgrp; it is always inherited from the parent (so
+ _hurd_pgrp is already correct), and the proc server will send us a
+diff --git a/sysdeps/mach/hurd/i386/sigreturn.c b/sysdeps/mach/hurd/i386/sigreturn.c
+index 60b0d00..8cb92ef 100644
+--- a/sysdeps/mach/hurd/i386/sigreturn.c
++++ b/sysdeps/mach/hurd/i386/sigreturn.c
+@@ -1,4 +1,5 @@
+-/* Copyright (C) 1991,92,94,95,96,97,98,2001 Free Software Foundation, Inc.
++/* Copyright (C) 1991,92,94,95,96,97,98,2001,2011
++ 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
+@@ -39,7 +40,7 @@ __sigreturn (struct sigcontext *scp)
+ }
+
+ ss = _hurd_self_sigstate ();
+- __spin_lock (&ss->lock);
++ _hurd_sigstate_lock (ss);
+
+ /* Remove the link on the `active resources' chain added by
+ _hurd_setup_sighandler. Its purpose was to make sure
+@@ -51,19 +52,19 @@ __sigreturn (struct sigcontext *scp)
+ ss->intr_port = scp->sc_intr_port;
+
+ /* Check for pending signals that were blocked by the old set. */
+- if (ss->pending & ~ss->blocked)
++ if (_hurd_sigstate_pending (ss) & ~ss->blocked)
+ {
+ /* There are pending signals that just became unblocked. Wake up the
+ signal thread to deliver them. But first, squirrel away SCP where
+ the signal thread will notice it if it runs another handler, and
+ arrange to have us called over again in the new reality. */
+ ss->context = scp;
+- __spin_unlock (&ss->lock);
++ _hurd_sigstate_unlock (ss);
+ __msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ());
+ /* If a pending signal was handled, sig_post never returned.
+ If it did return, the pending signal didn't run a handler;
+ proceed as usual. */
+- __spin_lock (&ss->lock);
++ _hurd_sigstate_lock (ss);
+ ss->context = NULL;
+ }
+
+@@ -74,7 +75,7 @@ __sigreturn (struct sigcontext *scp)
+ abort ();
+ }
+ else
+- __spin_unlock (&ss->lock);
++ _hurd_sigstate_unlock (ss);
+
+ /* Destroy the MiG reply port used by the signal handler, and restore the
+ reply port in use by the thread when interrupted. */
+diff --git a/sysdeps/mach/hurd/i386/trampoline.c b/sysdeps/mach/hurd/i386/trampoline.c
+index 99d9308..ec52847 100644
+--- a/sysdeps/mach/hurd/i386/trampoline.c
++++ b/sysdeps/mach/hurd/i386/trampoline.c
+@@ -1,5 +1,5 @@
+ /* Set thread_state for sighandler, and sigcontext to recover. i386 version.
+- Copyright (C) 1994,1995,1996,1997,1998,1999,2005,2008
++ Copyright (C) 1994,1995,1996,1997,1998,1999,2005,2008,2011
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+@@ -77,7 +77,11 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
+ interrupted RPC frame. */
+ state->basic.esp = state->basic.uesp;
+
+- if ((ss->actions[signo].sa_flags & SA_ONSTACK) &&
++ /* XXX what if handler != action->handler (for instance, if a signal
++ * preemptor took over) ? */
++ action = & _hurd_sigstate_actions (ss) [signo];
++
++ if ((action->sa_flags & SA_ONSTACK) &&
+ !(ss->sigaltstack.ss_flags & (SS_DISABLE|SS_ONSTACK)))
+ {
+ sigsp = ss->sigaltstack.ss_sp + ss->sigaltstack.ss_size;
+diff --git a/sysdeps/mach/hurd/sigaction.c b/sysdeps/mach/hurd/sigaction.c
+index fe452e8..bedf14c 100644
+--- a/sysdeps/mach/hurd/sigaction.c
++++ b/sysdeps/mach/hurd/sigaction.c
+@@ -1,4 +1,4 @@
+-/* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2002, 2007
++/* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2002, 2007, 2011
+ Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+@@ -51,15 +51,15 @@ __sigaction (sig, act, oact)
+ ss = _hurd_self_sigstate ();
+
+ __spin_lock (&ss->critical_section_lock);
+- __spin_lock (&ss->lock);
+- old = ss->actions[sig];
++ _hurd_sigstate_lock (ss);
++ old = _hurd_sigstate_actions (ss) [sig];
+ if (act != NULL)
+- ss->actions[sig] = a;
++ _hurd_sigstate_actions (ss) [sig] = a;
+
+ if (act != NULL && sig == SIGCHLD &&
+ (a.sa_flags & SA_NOCLDSTOP) != (old.sa_flags & SA_NOCLDSTOP))
+ {
+- __spin_unlock (&ss->lock);
++ _hurd_sigstate_unlock (ss);
+
+ /* Inform the proc server whether or not it should send us SIGCHLD for
+ stopped children. We do this in a critical section so that no
+@@ -67,8 +67,8 @@ __sigaction (sig, act, oact)
+ __USEPORT (PROC,
+ __proc_mod_stopchild (port, !(a.sa_flags & SA_NOCLDSTOP)));
+
+- __spin_lock (&ss->lock);
+- pending = ss->pending & ~ss->blocked;
++ _hurd_sigstate_lock (ss);
++ pending = _hurd_sigstate_pending (ss) & ~ss->blocked;
+ }
+ else if (act != NULL && (a.sa_handler == SIG_IGN || a.sa_handler == SIG_DFL))
+ /* We are changing to an action that might be to ignore SIG signals.
+@@ -77,11 +77,11 @@ __sigaction (sig, act, oact)
+ back and then SIG is unblocked, the signal pending now should not
+ arrive. So wake up the signal thread to check the new state and do
+ the right thing. */
+- pending = ss->pending & __sigmask (sig);
++ pending = _hurd_sigstate_pending (ss) & __sigmask (sig);
+ else
+ pending = 0;
+
+- __spin_unlock (&ss->lock);
++ _hurd_sigstate_unlock (ss);
+ __spin_unlock (&ss->critical_section_lock);
+
+ if (pending)
+diff --git a/sysdeps/mach/hurd/sigpending.c b/sysdeps/mach/hurd/sigpending.c
+index 84ac927..f582d45 100644
+--- a/sysdeps/mach/hurd/sigpending.c
++++ b/sysdeps/mach/hurd/sigpending.c
+@@ -1,4 +1,5 @@
+-/* Copyright (C) 1991, 1993, 1994, 1995, 1997 Free Software Foundation, Inc.
++/* Copyright (C) 1991, 1993, 1994, 1995, 1997, 2011
++ 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
+@@ -38,9 +39,9 @@ sigpending (set)
+ }
+
+ ss = _hurd_self_sigstate ();
+- __spin_lock (&ss->lock);
+- pending = ss->pending;
+- __spin_unlock (&ss->lock);
++ _hurd_sigstate_lock (ss);
++ pending = _hurd_sigstate_pending (ss);
++ _hurd_sigstate_unlock (ss);
+
+ *set = pending;
+ return 0;
+diff --git a/sysdeps/mach/hurd/sigprocmask.c b/sysdeps/mach/hurd/sigprocmask.c
+index cbb5ecc..b12dc19 100644
+--- a/sysdeps/mach/hurd/sigprocmask.c
++++ b/sysdeps/mach/hurd/sigprocmask.c
+@@ -1,4 +1,5 @@
+-/* Copyright (C) 1991,92,93,94,95,96,97,2002 Free Software Foundation, Inc.
++/* Copyright (C) 1991,92,93,94,95,96,97,2002,2011
++ 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
+@@ -40,7 +41,7 @@ __sigprocmask (how, set, oset)
+
+ ss = _hurd_self_sigstate ();
+
+- __spin_lock (&ss->lock);
++ _hurd_sigstate_lock (ss);
+
+ old = ss->blocked;
+
+@@ -61,7 +62,7 @@ __sigprocmask (how, set, oset)
+ break;
+
+ default:
+- __spin_unlock (&ss->lock);
++ _hurd_sigstate_unlock (ss);
+ errno = EINVAL;
+ return -1;
+ }
+@@ -69,9 +70,9 @@ __sigprocmask (how, set, oset)
+ ss->blocked &= ~_SIG_CANT_MASK;
+ }
+
+- pending = ss->pending & ~ss->blocked;
++ pending = _hurd_sigstate_pending (ss) & ~ss->blocked;
+
+- __spin_unlock (&ss->lock);
++ _hurd_sigstate_unlock (ss);
+
+ if (oset != NULL)
+ *oset = old;
+diff --git a/sysdeps/mach/hurd/sigsuspend.c b/sysdeps/mach/hurd/sigsuspend.c
+index 7e32472..2e55e30 100644
+--- a/sysdeps/mach/hurd/sigsuspend.c
++++ b/sysdeps/mach/hurd/sigsuspend.c
+@@ -1,5 +1,5 @@
+-/* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2002, 2007
+- Free Software Foundation, Inc.
++/* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2002, 2007,
++ 2011 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+@@ -43,7 +43,7 @@ __sigsuspend (set)
+
+ ss = _hurd_self_sigstate ();
+
+- __spin_lock (&ss->lock);
++ _hurd_sigstate_lock (ss);
+
+ oldmask = ss->blocked;
+ if (set != NULL)
+@@ -51,11 +51,11 @@ __sigsuspend (set)
+ ss->blocked = newmask & ~_SIG_CANT_MASK;
+
+ /* Notice if any pending signals just became unblocked. */
+- pending = ss->pending & ~ss->blocked;
++ pending = _hurd_sigstate_pending (ss) & ~ss->blocked;
+
+ /* Tell the signal thread to message us when a signal arrives. */
+ ss->suspended = wait;
+- __spin_unlock (&ss->lock);
++ _hurd_sigstate_unlock (ss);
+
+ if (pending)
+ /* Tell the signal thread to check for pending signals. */
+@@ -66,10 +66,11 @@ __sigsuspend (set)
+ MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+ __mach_port_destroy (__mach_task_self (), wait);
+
+- __spin_lock (&ss->lock);
+- ss->blocked = oldmask; /* Restore the old mask. */
+- pending = ss->pending & ~ss->blocked; /* Again check for pending signals. */
+- __spin_unlock (&ss->lock);
++ /* Restore the old mask and check for pending signals again. */
++ _hurd_sigstate_lock (ss);
++ ss->blocked = oldmask;
++ pending = _hurd_sigstate_pending(ss) & ~ss->blocked;
++ _hurd_sigstate_unlock (ss);
+
+ if (pending)
+ /* Tell the signal thread to check for pending signals. */
+diff --git a/sysdeps/mach/hurd/sigwait.c b/sysdeps/mach/hurd/sigwait.c
+index 9794076..af50f74 100644
+--- a/sysdeps/mach/hurd/sigwait.c
++++ b/sysdeps/mach/hurd/sigwait.c
+@@ -1,4 +1,4 @@
+-/* Copyright (C) 1996,97,2001,02 Free Software Foundation, Inc.
++/* Copyright (C) 1996,97,2001,2002,2011 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
+@@ -28,7 +28,7 @@ int
+ __sigwait (const sigset_t *set, int *sig)
+ {
+ struct hurd_sigstate *ss;
+- sigset_t mask, ready;
++ sigset_t mask, ready, blocked;
+ int signo = 0;
+ struct hurd_signal_preemptor preemptor;
+ jmp_buf buf;
+@@ -50,8 +50,8 @@ __sigwait (const sigset_t *set, int *sig)
+ /* Make sure this is all kosher */
+ assert (__sigismember (&mask, signo));
+
+- /* Make sure this signal is unblocked */
+- __sigdelset (&ss->blocked, signo);
++ /* Restore the blocking mask. */
++ ss->blocked = blocked;
+
+ return pe->handler;
+ }
+@@ -72,10 +72,11 @@ __sigwait (const sigset_t *set, int *sig)
+ __sigemptyset (&mask);
+
+ ss = _hurd_self_sigstate ();
+- __spin_lock (&ss->lock);
++ _hurd_sigstate_lock (ss);
+
+ /* See if one of these signals is currently pending. */
+- __sigandset (&ready, &ss->pending, &mask);
++ sigset_t pending = _hurd_sigstate_pending (ss);
++ __sigandset (&ready, &pending, &mask);
+ if (! __sigisemptyset (&ready))
+ {
+ for (signo = 1; signo < NSIG; signo++)
+@@ -103,7 +104,11 @@ __sigwait (const sigset_t *set, int *sig)
+ preemptor.next = ss->preemptors;
+ ss->preemptors = &preemptor;
+
+- __spin_unlock (&ss->lock);
++ /* Unblock the expected signals */
++ blocked = ss->blocked;
++ ss->blocked &= ~mask;
++
++ _hurd_sigstate_unlock (ss);
+
+ /* Wait. */
+ __mach_msg (&msg, MACH_RCV_MSG, 0, sizeof (msg), wait,
+@@ -114,7 +119,7 @@ __sigwait (const sigset_t *set, int *sig)
+ {
+ assert (signo);
+
+- __spin_lock (&ss->lock);
++ _hurd_sigstate_lock (ss);
+
+ /* Delete our preemptor. */
+ assert (ss->preemptors == &preemptor);
+@@ -123,7 +128,7 @@ __sigwait (const sigset_t *set, int *sig)
+
+
+ all_done:
+- spin_unlock (&ss->lock);
++ _hurd_sigstate_unlock (ss);
+
+ __mach_port_destroy (__mach_task_self (), wait);
+ *sig = signo;
+diff --git a/sysdeps/mach/hurd/spawni.c b/sysdeps/mach/hurd/spawni.c
+index 3d2b591..c12f448 100644
+--- a/sysdeps/mach/hurd/spawni.c
++++ b/sysdeps/mach/hurd/spawni.c
+@@ -239,26 +239,29 @@ __spawni (pid_t *pid, const char *file,
+ assert (! __spin_lock_locked (&ss->critical_section_lock));
+ __spin_lock (&ss->critical_section_lock);
+
+- __spin_lock (&ss->lock);
++ _hurd_sigstate_lock (ss);
+ ints[INIT_SIGMASK] = ss->blocked;
+- ints[INIT_SIGPENDING] = ss->pending;
++ ints[INIT_SIGPENDING] = _hurd_sigstate_pending (ss); /* XXX really? */
+ ints[INIT_SIGIGN] = 0;
+ /* Unless we were asked to reset all handlers to SIG_DFL,
+ pass down the set of signals that were set to SIG_IGN. */
+- if ((flags & POSIX_SPAWN_SETSIGDEF) == 0)
+- for (i = 1; i < NSIG; ++i)
+- if (ss->actions[i].sa_handler == SIG_IGN)
+- ints[INIT_SIGIGN] |= __sigmask (i);
++ {
++ struct sigaction *actions = _hurd_sigstate_actions (ss);
++ if ((flags & POSIX_SPAWN_SETSIGDEF) == 0)
++ for (i = 1; i < NSIG; ++i)
++ if (actions[i].sa_handler == SIG_IGN)
++ ints[INIT_SIGIGN] |= __sigmask (i);
++ }
+
+- /* We hold the sigstate lock until the exec has failed so that no signal
+- can arrive between when we pack the blocked and ignored signals, and
+- when the exec actually happens. A signal handler could change what
++ /* We hold the critical section lock until the exec has failed so that no
++ signal can arrive between when we pack the blocked and ignored signals,
++ and when the exec actually happens. A signal handler could change what
+ signals are blocked and ignored. Either the change will be reflected
+ in the exec, or the signal will never be delivered. Setting the
+ critical section flag avoids anything we call trying to acquire the
+ sigstate lock. */
+
+- __spin_unlock (&ss->lock);
++ _hurd_sigstate_unlock (ss);
+
+ /* Set signal mask. */
+ if ((flags & POSIX_SPAWN_SETSIGMASK) != 0)
+--
+tg: (c2fb0b6..) t/hurdsig-global-dispositions (depends on: t/hurdsig-fixes)
Copied: glibc-package/trunk/debian/patches/hurd-i386/tg-no-hp-timing.diff (from rev 5168, glibc-package/trunk/debian/patches/hurd-i386/unsubmitted-no-hp-timing.diff)
===================================================================
--- glibc-package/trunk/debian/patches/hurd-i386/tg-no-hp-timing.diff (rev 0)
+++ glibc-package/trunk/debian/patches/hurd-i386/tg-no-hp-timing.diff 2012-02-21 01:58:20 UTC (rev 5169)
@@ -0,0 +1,62 @@
+From: Samuel Thibault <samuel.thibault@ens-lyon.org>
+Subject: [PATCH] No hp timing
+
+2010-08-21 Samuel Thibault <samuel.thibault@ens-lyon.org>
+
+We don't have support for hp timing for now, even the i686 variant, which needs
+to know the CPU speed.
+Copied from sysdeps/generic/hp-timing.h
+
+---
+ sysdeps/mach/hurd/hp-timing.h | 41 +++++++++++++++++++++++++++++++++++++++++
+ 1 files changed, 41 insertions(+), 0 deletions(-)
+
+diff --git a/sysdeps/mach/hurd/hp-timing.h b/sysdeps/mach/hurd/hp-timing.h
+new file mode 100644
+index 0000000..933fb83
+--- /dev/null
++++ b/sysdeps/mach/hurd/hp-timing.h
+@@ -0,0 +1,41 @@
++/* High precision, low overhead timing functions. Generic version.
++ Copyright (C) 1998, 2000 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, write to the Free
++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++ 02111-1307 USA. */
++
++#ifndef _HP_TIMING_H
++#define _HP_TIMING_H 1
++
++/* We don't have support for high precision timing for now. */
++
++/* Provide dummy definitions. */
++#define HP_TIMING_AVAIL (0)
++#define HP_TIMING_INLINE (0)
++typedef int hp_timing_t;
++#define HP_TIMING_ZERO(Var)
++#define HP_TIMING_NOW(var)
++#define HP_TIMING_DIFF_INIT()
++#define HP_TIMING_DIFF(Diff, Start, End)
++#define HP_TIMING_ACCUM(Sum, Diff)
++#define HP_TIMING_ACCUM_NT(Sum, Diff)
++#define HP_TIMING_PRINT(Buf, Len, Val)
++
++/* Since this implementation is not available we tell the user about it. */
++#define HP_TIMING_NONAVAIL 1
++
++#endif /* hp-timing.h */
+--
+tg: (0234227..) t/no-hp-timing (depends on: baseline)
Deleted: glibc-package/trunk/debian/patches/hurd-i386/unsubmitted-no-hp-timing.diff
===================================================================
--- glibc-package/trunk/debian/patches/hurd-i386/unsubmitted-no-hp-timing.diff 2012-02-20 19:22:27 UTC (rev 5168)
+++ glibc-package/trunk/debian/patches/hurd-i386/unsubmitted-no-hp-timing.diff 2012-02-21 01:58:20 UTC (rev 5169)
@@ -1,56 +0,0 @@
-2010-08-21 Samuel Thibault <samuel.thibault@ens-lyon.org>
-
-We don't have support for hp timing for now, even the i686 variant, which needs
-to know the CPU speed.
-Copied from sysdeps/generic/hp-timing.h
-
-No topgit branch, TODO?
-
----
- sysdeps/mach/hurd/hp-timing.h | 41 +++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 41 insertions(+)
-
---- /dev/null
-+++ b/sysdeps/mach/hurd/hp-timing.h
-@@ -0,0 +1,41 @@
-+/* High precision, low overhead timing functions. Generic version.
-+ Copyright (C) 1998, 2000 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, write to the Free
-+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+ 02111-1307 USA. */
-+
-+#ifndef _HP_TIMING_H
-+#define _HP_TIMING_H 1
-+
-+/* We don't have support for high precision timing for now. */
-+
-+/* Provide dummy definitions. */
-+#define HP_TIMING_AVAIL (0)
-+#define HP_TIMING_INLINE (0)
-+typedef int hp_timing_t;
-+#define HP_TIMING_ZERO(Var)
-+#define HP_TIMING_NOW(var)
-+#define HP_TIMING_DIFF_INIT()
-+#define HP_TIMING_DIFF(Diff, Start, End)
-+#define HP_TIMING_ACCUM(Sum, Diff)
-+#define HP_TIMING_ACCUM_NT(Sum, Diff)
-+#define HP_TIMING_PRINT(Buf, Len, Val)
-+
-+/* Since this implementation is not available we tell the user about it. */
-+#define HP_TIMING_NONAVAIL 1
-+
-+#endif /* hp-timing.h */
Modified: glibc-package/trunk/debian/patches/series
===================================================================
--- glibc-package/trunk/debian/patches/series 2012-02-20 19:22:27 UTC (rev 5168)
+++ glibc-package/trunk/debian/patches/series 2012-02-21 01:58:20 UTC (rev 5169)
@@ -145,7 +145,7 @@
hurd-i386/submitted-regex_internal.diff
hurd-i386/tg-mkdir_root.diff
hurd-i386/tg-__i686_defined.diff
-hurd-i386/unsubmitted-no-hp-timing.diff
+hurd-i386/tg-no-hp-timing.diff
hurd-i386/tg-catch-signal.diff
hurd-i386/tg-sendmsg-SCM_RIGHTS.diff
hurd-i386/cvs-header-prot.diff
@@ -159,10 +159,11 @@
hurd-i386/cvs-ldsodefs.h.diff
hurd-i386/tg-elfosabi_gnu.diff
hurd-i386/submitted-init-first.diff
-hurd-i386/submitted-hurdsig-fixes.diff
-hurd-i386/submitted-hurdsig-global-dispositions.diff
-hurd-i386/submitted-hurdsig-SA_SIGINFO.diff
-hurd-i386/submitted-hurdsig-fixes-2.diff
+hurd-i386/tg-hurdsig-fixes.diff
+hurd-i386/tg-hurdsig-global-dispositions.diff
+hurd-i386/local-hurdsig-global-dispositions-version.diff
+hurd-i386/tg-hurdsig-SA_SIGINFO.diff
+hurd-i386/tg-hurdsig-fixes-2.diff
hurd-i386/tg-libc_stack_end.diff
hurd-i386/tg-ttyname_ERANGE.diff
hurd-i386/cvs-DEV_BSIZE.diff
Reply to: