[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: