diff -u eglibc-2.15/debian/rules eglibc-2.15/debian/rules --- eglibc-2.15/debian/rules +++ eglibc-2.15/debian/rules @@ -173,6 +173,15 @@ # Don't put debug files from these packages in libc-dbg NODEBUG_libc-bin = 1 NODEBUG_libc-dev-bin = 1 +NODEBUG_libc6-amd64 = 1 +NODEBUG_libc6-i386 = 1 +NODEBUG_libc6-mipsn32 = 1 +NODEBUG_libc6-powerpc = 1 +NODEBUG_libc6-ppc64 = 1 +NODEBUG_libc6-s390 = 1 +NODEBUG_libc6-s390x = 1 +NODEBUG_libc6-sparc64 = 1 +NODEBUG_libc6-mips64 = 1 NODEBUG_nscd = 1 ifneq ($(DEB_STAGE),stage1) diff -u eglibc-2.15/debian/control eglibc-2.15/debian/control --- eglibc-2.15/debian/control +++ eglibc-2.15/debian/control @@ -13,7 +13,7 @@ Maintainer: Ubuntu Developers XSBC-Original-Maintainer: GNU Libc Maintainers Uploaders: Clint Adams , Aurelien Jarno -Standards-Version: 3.9.2 +Standards-Version: 3.9.3 XS-Debian-Vcs-Browser: http://svn.debian.org/wsvn/pkg-glibc/glibc-package/ XS-Debian-Vcs-Svn: svn://svn.debian.org/pkg-glibc/glibc-package/ Homepage: http://www.eglibc.org diff -u eglibc-2.15/debian/changelog eglibc-2.15/debian/changelog --- eglibc-2.15/debian/changelog +++ eglibc-2.15/debian/changelog @@ -1,3 +1,11 @@ +eglibc (2.15-0ubuntu4) precise; urgency=low + + * Merge from Debian (r5173, 2.13-27). + * Don't include the non-default multilib debug files in the libc6-dbg + package for any architecture. + + -- Matthias Klose Fri, 02 Mar 2012 19:41:37 +0100 + eglibc (2.15-0ubuntu3) precise; urgency=low [ Matthias Klose ] @@ -190,6 +198,40 @@ -- Matthias Klose Fri, 14 Oct 2011 11:38:00 +0200 +eglibc (2.13-27) unstable; urgency=low + + [ Samuel Thibault ] + * patches/hurd-i386/local-select.diff: Do not apply the select(0) hack to + vim, as it hurts its performance badly. + * patches/hurd-i386/submitted-hurdsig-SA_SIGINFO.diff: merge + submitted-posix2008.diff fix. + * patches/hurd-i386/{submitted,unsubmitted}-*: Rename to tg-* according to + integration in upstream tg repository. + + [ Aurelien Jarno ] + * kfreebsd/local-sysdeps.diff: update to revision 4080 (from glibc-bsd). + Closes: #653380, #660397, #660401. + * patches/localedata/first_weekday.diff: change first day of week to + Sunday for es_AR locale. Closes: #657064. + * local/manpages/gai.conf.5: update from latest RedHat version. Closes: + #659504. + * testsuite-checking/expected-results-arm-linux-gnueabihf-libc: new + file using the latest build as a reference. + * patches/mips/cvs-dlopen-lazy.diff: new patch from upstream to resolve + race between dlopen and lazy binding on MIPS. + * patches/sparc/cvs-fcntl_h.diff: new patch from upstream to define + O_FSYNC on sparc. Closes: #577577. + * testsuite-checking/expected-results-mipsel-linux-gnu-libc, + testsuite-checking/expected-results-mips32el-linux-gnu-mipsn32, + testsuite-checking/expected-results-mips64el-linux-gnu-mips64: add + test-fenv.out to the list of known failures, it fails on loongson 2 + machines due to a CPU bug. + * Bump to Standards-Version 3.9.3 (no changes). + * Don't provide debug files for biarch packages to make libc6-dbg + co-installable. + + -- Aurelien Jarno Sun, 26 Feb 2012 18:50:40 +0100 + eglibc (2.13-26) unstable; urgency=low [ Aurelien Jarno ] diff -u eglibc-2.15/debian/control.in/main eglibc-2.15/debian/control.in/main --- eglibc-2.15/debian/control.in/main +++ eglibc-2.15/debian/control.in/main @@ -13,7 +13,7 @@ Maintainer: Ubuntu Developers XSBC-Original-Maintainer: GNU Libc Maintainers Uploaders: Clint Adams , Aurelien Jarno -Standards-Version: 3.9.2 +Standards-Version: 3.9.3 XS-Debian-Vcs-Browser: http://svn.debian.org/wsvn/pkg-glibc/glibc-package/ XS-Debian-Vcs-Svn: svn://svn.debian.org/pkg-glibc/glibc-package/ Homepage: http://www.eglibc.org diff -u eglibc-2.15/debian/testsuite-checking/expected-results-mips32el-linux-gnu-mipsn32 eglibc-2.15/debian/testsuite-checking/expected-results-mips32el-linux-gnu-mipsn32 --- eglibc-2.15/debian/testsuite-checking/expected-results-mips32el-linux-gnu-mipsn32 +++ eglibc-2.15/debian/testsuite-checking/expected-results-mips32el-linux-gnu-mipsn32 @@ -9,6 +9,7 @@ check-execstack.out, Error 1 check-localplt.out, Error 1 test-double.out, Error 1 +test-fenv.out, Error 1 test-idouble.out, Error 1 test-misc.out, Error 1 tst-audit1.out, Error 127 diff -u eglibc-2.15/debian/testsuite-checking/expected-results-arm-linux-gnueabihf-libc eglibc-2.15/debian/testsuite-checking/expected-results-arm-linux-gnueabihf-libc --- eglibc-2.15/debian/testsuite-checking/expected-results-arm-linux-gnueabihf-libc +++ eglibc-2.15/debian/testsuite-checking/expected-results-arm-linux-gnueabihf-libc @@ -7,7 +7,10 @@ check-localplt.out, Error 1 tst-cpuclock2.out, Error 1 +test-double.out, Error 1 +test-fenv.out, Error 1 +test-float.out, Error 1 test-idouble.out, Error 1 test-ifloat.out, Error 1 -tst-mqueue5.out, Error 1 +tst-cputimer1.out, Error 1 tst-timer.out, Error 139 tst-waitid.out, Error 1 diff -u eglibc-2.15/debian/testsuite-checking/expected-results-mipsel-linux-gnu-libc eglibc-2.15/debian/testsuite-checking/expected-results-mipsel-linux-gnu-libc --- eglibc-2.15/debian/testsuite-checking/expected-results-mipsel-linux-gnu-libc +++ eglibc-2.15/debian/testsuite-checking/expected-results-mipsel-linux-gnu-libc @@ -6,6 +6,7 @@ annexc.out, Error 1 (ignored) check-execstack.out, Error 1 check-localplt.out, Error 1 +test-fenv.out, Error 1 tst-audit1.out, Error 127 tst-audit2.out, Error 127 tst-backtrace1.out, Error 1 diff -u eglibc-2.15/debian/testsuite-checking/expected-results-mips64el-linux-gnu-mips64 eglibc-2.15/debian/testsuite-checking/expected-results-mips64el-linux-gnu-mips64 --- eglibc-2.15/debian/testsuite-checking/expected-results-mips64el-linux-gnu-mips64 +++ eglibc-2.15/debian/testsuite-checking/expected-results-mips64el-linux-gnu-mips64 @@ -9,6 +9,7 @@ check-execstack.out, Error 1 check-localplt.out, Error 1 test-double.out, Error 1 +test-fenv.out, Error 1 test-idouble.out, Error 1 test-misc.out, Error 1 tst-audit1.out, Error 127 diff -u eglibc-2.15/debian/local/manpages/gai.conf.5 eglibc-2.15/debian/local/manpages/gai.conf.5 --- eglibc-2.15/debian/local/manpages/gai.conf.5 +++ eglibc-2.15/debian/local/manpages/gai.conf.5 @@ -51,7 +51,7 @@ .TP \fBprecedence\fR \fInetmask\fR \fIprecedence\fR This keyword is similar to \fBlabel\fR but instead the value is added -to the precendence table as specified in RFC 3484. Once again, the +to the precedence table as specified in RFC 3484. Once again, the presence of a single \fBprecedence\fR line in the configuration file causes the default table to not be used. @@ -62,6 +62,12 @@ `\fByes\fR' the file is re-read. This might cause problems in multi-threaded applications and is generally a bad idea. The default is `\fBno\fR'. +.TP +\fBscopev4\fR \fImask\fR \fIvalue\fR +Add another rule to the RFC 3484 scope table for IPv4 address. +By default the scope IDs described in section 3.2 in +RFC 3438 are used. +Changing these defaults should hardly ever be necessary. .SH EXAMPLE @@ -74,11 +80,11 @@ label 2002::/16 2 label ::/96 3 label ::ffff:0:0/96 4 -precendence ::1/128 50 -precendence ::/0 40 -precendence 2002::/16 30 -precendence ::/96 20 -precendence ::ffff:0:0/96 10 +precedence ::1/128 50 +precedence ::/0 40 +precedence 2002::/16 30 +precedence ::/96 20 +precedence ::ffff:0:0/96 10 .SH FILES diff -u eglibc-2.15/debian/patches/series.hurd-i386 eglibc-2.15/debian/patches/series.hurd-i386 --- eglibc-2.15/debian/patches/series.hurd-i386 +++ eglibc-2.15/debian/patches/series.hurd-i386 @@ -3,7 +3,7 @@ hurd-i386/tg-bits_atomic.h_multiple_threads.diff hurd-i386/local-pthread_stubs.diff hurd-i386/unsubmitted-pthread-unsupported-stubs.diff -hurd-i386/unsubmitted-unlockpt-chroot.diff +hurd-i386/tg-unlockpt-chroot.diff hurd-i386/local-msg-nosignal.diff hurd-i386/unsubmitted-pthread.diff hurd-i386/local-clock_gettime_MONOTONIC.diff reverted: --- eglibc-2.15/debian/patches/hurd-i386/submitted-itimer-lock.diff +++ eglibc-2.15.orig/debian/patches/hurd-i386/submitted-itimer-lock.diff @@ -1,24 +0,0 @@ -http://sourceware.org/ml/libc-alpha/2009-02/msg00003.html - -2009-02-01 Samuel Thibault - - * sysdeps/mach/hurd/setitimer.c (setitimer_locked): Use common exit path - instead of returning without unlocking. - -No topgit branch, TODO. - ---- - sysdeps/mach/hurd/setitimer.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/sysdeps/mach/hurd/setitimer.c -+++ b/sysdeps/mach/hurd/setitimer.c -@@ -220,7 +220,7 @@ - /* Start up the itimer thread running `timer_thread' (below). */ - if (err = __thread_create (__mach_task_self (), - &_hurd_itimer_thread)) -- return __hurd_fail (err); -+ goto out; - _hurd_itimer_thread_stack_base = 0; /* Anywhere. */ - _hurd_itimer_thread_stack_size = __vm_page_size; /* Small stack. */ - if ((err = __mach_setup_thread (__mach_task_self (), reverted: --- eglibc-2.15/debian/patches/hurd-i386/submitted-_hurd_socket_server-indexcheck.diff +++ eglibc-2.15.orig/debian/patches/hurd-i386/submitted-_hurd_socket_server-indexcheck.diff @@ -1,23 +0,0 @@ -http://cygwin.com/ml/libc-alpha/2011-11/msg00076.html - -Refuse negative socket domains right away; otherwise, it is possible to read -and set out-of-bounds locations of the `servers' array (returning the values -at those invalid memory locations), and even try to deallocate ports with -random values if the `dead' parameter is different than zero. - -* hurd/hurdsock.c (_hurd_socket_server): Check for negative domains. ---- a/hurd/hurdsock.c -+++ b/hurd/hurdsock.c -@@ -47,6 +47,12 @@ - { - socket_t server; - -+ if (domain < 0) -+ { -+ errno = EAFNOSUPPORT; -+ return MACH_PORT_NULL; -+ } -+ - HURD_CRITICAL_BEGIN; - __mutex_lock (&lock); - diff -u eglibc-2.15/debian/patches/hurd-i386/local-select.diff eglibc-2.15/debian/patches/hurd-i386/local-select.diff --- eglibc-2.15/debian/patches/hurd-i386/local-select.diff +++ eglibc-2.15/debian/patches/hurd-i386/local-select.diff @@ -11,7 +11,7 @@ to = timeout->tv_sec * 1000 + (timeout->tv_nsec + 999999) / 1000000; -+ if (!to) ++ if (strcmp(program_invocation_short_name, "vi") && strcmp(program_invocation_short_name, "vim") && strcmp(program_invocation_short_name, "vimdiff") && !to) + to = 1; } reverted: --- eglibc-2.15/debian/patches/hurd-i386/submitted-IPV6_PKTINFO.diff +++ eglibc-2.15.orig/debian/patches/hurd-i386/submitted-IPV6_PKTINFO.diff @@ -1,33 +0,0 @@ -Add more ipv6 macros. - -http://www.sourceware.org/bugzilla/show_bug.cgi?id=3906 - -No topgit branch, TODO. - ---- - bits/in.h | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - ---- a/bits/in.h -+++ b/bits/in.h -@@ -50,7 +50,7 @@ - - /* IPV6 socket options. */ - #define IPV6_ADDRFORM 1 --#define IPV6_RXINFO 2 -+#define IPV6_PKTINFO 2 - #define IPV6_HOPOPTS 3 - #define IPV6_DSTOPTS 4 - #define IPV6_RTHDR 5 -@@ -58,8 +58,9 @@ - #define IPV6_CHECKSUM 7 - #define IPV6_HOPLIMIT 8 - --#define IPV6_TXINFO IPV6_RXINFO --#define SCM_SRCINFO IPV6_TXINFO -+#define IPV6_RXINFO IPV6_PKTINFO -+#define IPV6_TXINFO IPV6_PKTINFO -+#define SCM_SRCINFO IPV6_PKTINFO - #define SCM_SRCRT IPV6_RXSRCRT - - #define IPV6_UNICAST_HOPS 16 reverted: --- eglibc-2.15/debian/patches/hurd-i386/submitted-hurdsig-SA_SIGINFO.diff +++ eglibc-2.15.orig/debian/patches/hurd-i386/submitted-hurdsig-SA_SIGINFO.diff @@ -1,531 +0,0 @@ -jkoenig's work on signals - -No topgit branch - -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 -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,79 @@ -+/* 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 directly; use 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. */ -+# 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 - #include - #include -+#include - #include - #include - #include - #include "hurdfault.h" - #include -+#include - - -+/* 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: reverted: --- eglibc-2.15/debian/patches/hurd-i386/submitted-catch-signal.diff +++ eglibc-2.15.orig/debian/patches/hurd-i386/submitted-catch-signal.diff @@ -1,49 +0,0 @@ -http://sourceware.org/ml/libc-alpha/2010-09/msg00015.html - -2010-09-13 Samuel Thibault - - Fix signal-catching functions. - - We need to restore the signal mask, because else the signal handling - code will have blocked the catched signal and for instance calling - hurd_catch_signal again would then dump core. There was also a trivial - inverted logic. - - * hurd/catch-signal.c (hurd_catch_signal): Use sigsetjmp/siglongjmp - instead of setjmp/longjmp to restore the signal mask. Call sigsetjmp - when handler == SIG_ERR, not when handler != SIG_ERR. - -No topgit branch, TODO. - ---- - hurd/catch-signal.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) ---- a/hurd/catch-signal.c -+++ b/hurd/catch-signal.c -@@ -28,9 +28,9 @@ - error_t (*operate) (struct hurd_signal_preemptor *), - sighandler_t handler) - { -- jmp_buf buf; -+ sigjmp_buf buf; - void throw (int signo, long int sigcode, struct sigcontext *scp) -- { longjmp (buf, scp->sc_error ?: EGRATUITOUS); } -+ { siglongjmp (buf, scp->sc_error ?: EGRATUITOUS); } - - struct hurd_signal_preemptor preemptor = - { -@@ -41,12 +41,12 @@ - struct hurd_sigstate *const ss = _hurd_self_sigstate (); - error_t error; - -- if (handler == SIG_ERR) -+ if (handler != SIG_ERR) - /* Not our handler; don't bother saving state. */ - error = 0; - else - /* This returns again with nonzero value when we preempt a signal. */ -- error = setjmp (buf); -+ error = sigsetjmp (buf, 1); - - if (error == 0) - { reverted: --- eglibc-2.15/debian/patches/hurd-i386/submitted-libc_stack_end.diff +++ eglibc-2.15.orig/debian/patches/hurd-i386/submitted-libc_stack_end.diff @@ -1,64 +0,0 @@ -http://www.cygwin.com/ml/libc-alpha/2011-08/msg00124.html - -2011-08-24 Samuel Thibault - -* sysdeps/generic/ldsodefs.h [LIBC_STACK_END_NOT_RELRO] (__libc_stack_end): Do -not use attribute_relro. -* sysdeps/mach/hurd/dl-sysdep.h (LIBC_STACK_END_NOT_RELRO): Define. -* sysdeps/mach/hurd/i386/init-first.c (init): Update __libc_stack_end to -libthread-provided value. -* sysdeps/mach/hurd/dl-sysdep.c (__libc_stack_end): Do not use attribute_relro. - -No topgit branch, TODO. - ---- - generic/ldsodefs.h | 6 +++++- - mach/hurd/dl-sysdep.c | 2 +- - mach/hurd/dl-sysdep.h | 3 ++- - mach/hurd/i386/init-first.c | 2 ++ - 4 files changed, 10 insertions(+), 3 deletions(-) - -diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h -index d040590..cb24ca7 100644 ---- a/sysdeps/generic/ldsodefs.h -+++ b/sysdeps/generic/ldsodefs.h -@@ -723,7 +723,11 @@ rtld_hidden_proto (_dl_make_stack_executable) - might use the variable which results in copy relocations on some - platforms. But this does not matter, ld.so can always use the local - copy. */ --extern void *__libc_stack_end attribute_relro; -+extern void *__libc_stack_end -+#ifndef LIBC_STACK_END_NOT_RELRO -+ attribute_relro -+#endif -+ ; - rtld_hidden_proto (__libc_stack_end) - - /* Parameters passed to the dynamic linker. */ -diff --git a/sysdeps/mach/hurd/dl-sysdep.h b/sysdeps/mach/hurd/dl-sysdep.h -index 4b21b77..8f1c728 100644 ---- a/sysdeps/mach/hurd/dl-sysdep.h -+++ b/sysdeps/mach/hurd/dl-sysdep.h -@@ -25,7 +25,8 @@ - #define RTLD_PRIVATE_ERRNO 0 - - #ifdef SHARED --/* _dl_argv cannot be attribute_relro, because the stack-switching -+/* _dl_argv and __libc_stack_end cannot be attribute_relro, because the stack-switching - libc initializer for using cthreads might write into it. */ - # define DL_ARGV_NOT_RELRO 1 -+# define LIBC_STACK_END_NOT_RELRO 1 - #endif -diff --git a/sysdeps/mach/hurd/i386/init-first.c b/sysdeps/mach/hurd/i386/init-first.c -index e79af1d..7b2ea12 100644 ---- a/sysdeps/mach/hurd/i386/init-first.c -+++ b/sysdeps/mach/hurd/i386/init-first.c -@@ -227,6 +224,8 @@ init (int *_data) - - void switch_stacks (void); - -+ __libc_stack_end = newsp; -+ - /* Copy per-thread variables from that temporary - area onto the new cthread stack. */ - memcpy (__hurd_threadvar_location_from_sp (0, newsp), reverted: --- eglibc-2.15/debian/patches/hurd-i386/unsubmitted-bigmem.diff +++ eglibc-2.15.orig/debian/patches/hurd-i386/unsubmitted-bigmem.diff @@ -1,45 +0,0 @@ -Allow the kernel to start earlier than VM_MAX_ADDRESS - -A bit hackish. - -No topgit branch, TODO. - ---- - sysdeps/mach/hurd/dl-sysdep.c | 26 ++++++++++++++++++++------ - 1 file changed, 20 insertions(+), 6 deletions(-) - ---- a/sysdeps/mach/hurd/dl-sysdep.c -+++ b/sysdeps/mach/hurd/dl-sysdep.c -@@ -105,12 +105,26 @@ - max=a; break;} - fmha=a+=fmhs;} - if (err) assert(err==KERN_NO_SPACE); -- if (!fmha)fmhs=0;else{ -- fmhs=max-fmha; -- err = __vm_map (__mach_task_self (), -- &fmha, fmhs, 0, 0, MACH_PORT_NULL, 0, 1, -- VM_PROT_NONE, VM_PROT_NONE, VM_INHERIT_COPY); -- assert_perror(err);} -+ if (!fmha) -+ fmhs=0; -+ else -+ while (1) { -+ fmhs=max-fmha; -+ err = __vm_map (__mach_task_self (), -+ &fmha, fmhs, 0, 0, MACH_PORT_NULL, 0, 1, -+ VM_PROT_NONE, VM_PROT_NONE, VM_INHERIT_COPY); -+ if (!err) -+ break; -+ if (err != KERN_INVALID_ADDRESS && err != KERN_NO_SPACE) -+ assert_perror(err); -+ vm_address_t new_max = (max - 1) & 0xf0000000U; -+ if (new_max >= max) { -+ fmhs = 0; -+ fmha = 0; -+ break; -+ } -+ max = new_max; -+ } - } - /* XXX loser kludge for vm_map kernel bug */ - #endif reverted: --- eglibc-2.15/debian/patches/hurd-i386/submitted-sysvshm.diff +++ eglibc-2.15.orig/debian/patches/hurd-i386/submitted-sysvshm.diff @@ -1,777 +0,0 @@ -# All lines beginning with `# DP:' are a description of the patch. -# DP: Description: Implement SysV shared memory for GNU/Hurd. -# DP: Dpatch author: Michael Banck -# DP: Patch author: Marcus Brinkmann -# DP: Upstream status: Unsubmitted, copyright assignments needed -# DP: Date: 2005-07-11 - -2005-07-11 Marcus Brinkmann - - * hurd/Makefile (routines): Add sysvshm. - (distribute): Add sysvshm.h. - * hurd/sysvshm.h: New file. - * hurd/sysvshm.c: New file. - * sysdeps/mach/hurd/bits/stat.h (S_IMMAP0): New macro. - (S_ISPARE): Unset the S_IMMAP0 flag. - * sysdeps/mach/hurd/ftok.c: New file. - * sysdeps/mach/hurd/shmat.c: New file. - * sysdeps/mach/hurd/shmctl.c: New file. - * sysdeps/mach/hurd/shmdt.c: New file. - * sysdeps/mach/hurd/bits/posix_opt.h: Define _XOPEN_SHM to 1. - -No topgit branch, TODO. - ---- - hurd/Makefile | 3 - hurd/sysvshm.c | 96 ++++++++++++++ - hurd/sysvshm.h | 47 +++++++ - sysdeps/mach/hurd/bits/posix_opt.h | 4 - sysdeps/mach/hurd/ftok.c | 43 ++++++ - sysdeps/mach/hurd/shmat.c | 78 +++++++++++ - sysdeps/mach/hurd/shmctl.c | 132 +++++++++++++++++++ - sysdeps/mach/hurd/shmdt.c | 51 +++++++ - sysdeps/mach/hurd/shmget.c | 245 +++++++++++++++++++++++++++++++++++++ - 9 files changed, 696 insertions(+), 3 deletions(-) - ---- a/hurd/Makefile -+++ b/hurd/Makefile -@@ -60,6 +60,7 @@ - vpprintf \ - ports-get ports-set hurdports hurdmsg \ - errno-loc \ -+ sysvshm \ - $(sig) $(dtable) $(inlines) port-cleanup report-wait xattr - sig = hurdsig hurdfault siginfo hurd-raise preempt-sig \ - trampoline longjmp-ts catch-exc exc2signal hurdkill sigunwind \ -@@ -68,7 +69,7 @@ - getdport openport \ - fd-close fd-read fd-write hurdioctl ctty-input ctty-output - inlines = $(inline-headers:%.h=%-inlines) --distribute = hurdstartup.h hurdfault.h hurdhost.h \ -+distribute = hurdstartup.h hurdfault.h hurdhost.h sysvshm.h \ - faultexc.defs intr-rpc.defs intr-rpc.h intr-msg.h Notes - - # XXX this is a temporary hack; see hurdmalloc.h ---- /dev/null -+++ b/hurd/sysvshm.c -@@ -0,0 +1,96 @@ -+/* Copyright (C) 2005 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. */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+ -+/* Description of an shm attachment. */ -+struct sysvshm_attach -+{ -+ /* Linked list. */ -+ struct sysvshm_attach *next; -+ -+ /* Map address. */ -+ void *addr; -+ -+ /* Map size. */ -+ size_t size; -+}; -+ -+/* List of attachments. */ -+static struct sysvshm_attach *attach_list; -+ -+/* A lock to protect the linked list of shared memory attachments. */ -+static struct mutex sysvshm_lock = MUTEX_INITIALIZER; -+ -+ -+/* Adds a segment attachment. */ -+error_t -+__sysvshm_add (void *addr, size_t size) -+{ -+ struct sysvshm_attach *shm; -+ -+ shm = malloc (sizeof (*shm)); -+ if (!shm) -+ return errno; -+ -+ __mutex_lock (&sysvshm_lock); -+ shm->addr = addr; -+ shm->size = size; -+ shm->next = attach_list; -+ attach_list = shm; -+ __mutex_unlock (&sysvshm_lock); -+ -+ return 0; -+} -+ -+/* Removes a segment attachment. Returns its size if found, or EINVAL -+ otherwise. */ -+error_t -+__sysvshm_remove (void *addr, size_t *size) -+{ -+ struct sysvshm_attach *shm; -+ struct sysvshm_attach **pshm = &attach_list; -+ -+ __mutex_lock (&sysvshm_lock); -+ shm = attach_list; -+ while (shm) -+ { -+ shm = *pshm; -+ if (shm->addr == addr) -+ { -+ *pshm = shm->next; -+ *size = shm->size; -+ __mutex_unlock (&sysvshm_lock); -+ return 0; -+ } -+ pshm = &shm->next; -+ shm = shm->next; -+ } -+ __mutex_unlock (&sysvshm_lock); -+ return EINVAL; -+} ---- /dev/null -+++ b/hurd/sysvshm.h -@@ -0,0 +1,47 @@ -+/* Copyright (C) 2005 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. */ -+ -+#include -+#include -+ -+/* The area (from top to bottom) that is used for private keys. These -+ are all keys that have the second highest bit set. */ -+#define SHM_PRIV_KEY_START INT_MAX -+#define SHM_PRIV_KEY_END ((INT_MAX / 2) + 1) -+ -+#define SHM_PREFIX "shm-" -+#define SHM_DIR _PATH_DEV "shm/" -+ -+/* The maximum number of characters in a shared memory segment file name. -+ 32 is the max number of characters in a 128 bit number in hex. */ -+#if __WORDSIZE > 128 -+#error Need to increase SHM_NAMEMAX. -+#else -+#define SHM_NAMEMAX (sizeof (SHM_PREFIX) - 1 + 32 + 1) -+#endif -+ -+/* Use this with printf and its variants. */ -+#define SHM_NAMEPRI SHM_PREFIX "%0x" -+ -+ -+/* Adds a segment attachment. */ -+error_t __sysvshm_add (void *addr, size_t size); -+ -+/* Removes a segment attachment. Returns its size if found, or EINVAL -+ otherwise. */ -+error_t __sysvshm_remove (void *addr, size_t *size); ---- /dev/null -+++ b/sysdeps/mach/hurd/ftok.c -@@ -0,0 +1,43 @@ -+/* Copyright (C) 1995, 1996, 2000, 2005 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Ulrich Drepper , August 1995. -+ -+ 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. */ -+ -+#include -+#include -+ -+ -+/* In the Hurd, we use the second-to-most-significant bit as flag for -+ private keys. We use a different order of the components so that -+ the biggest one---the inode number---is affected by this. */ -+ -+key_t -+ftok (pathname, proj_id) -+ const char *pathname; -+ int proj_id; -+{ -+ struct stat64 st; -+ key_t key; -+ -+ if (__xstat64 (_STAT_VER, pathname, &st) < 0) -+ return (key_t) -1; -+ -+ key = ((st.st_dev & 0xff) | ((proj_id & 0xff) << 8) -+ | ((st.st_ino & 0x3fff) << 16)); -+ -+ return key; -+} ---- /dev/null -+++ b/sysdeps/mach/hurd/shmat.c -@@ -0,0 +1,78 @@ -+/* Copyright (C) 2005 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. */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "sysvshm.h" -+ -+/* Attach the shared memory segment associated with SHMID to the data -+ segment of the calling process. SHMADDR and SHMFLG determine how -+ and where the segment is attached. */ -+void * -+__shmat (int shmid, const void *shmaddr, int shmflg) -+{ -+ error_t err; -+ char filename[sizeof (SHM_DIR) - 1 + SHM_NAMEMAX]; -+ int fd; -+ void *addr; -+ struct stat statbuf; -+ int res; -+ -+ sprintf (filename, SHM_DIR SHM_NAMEPRI, shmid); -+ fd = __open (filename, (shmflg & SHM_RDONLY) ? O_RDONLY : O_RDWR); -+ if (fd < 0) -+ { -+ if (errno == ENOENT) -+ errno = EINVAL; -+ return (void *) -1; -+ } -+ -+ res = __fstat (fd, &statbuf); -+ if (res < 0) -+ { -+ __close (fd); -+ return (void *) -1; -+ } -+ -+ addr = __mmap ((void *) shmaddr, statbuf.st_size, -+ PROT_READ | ((shmflg & SHM_RDONLY) ? 0 : PROT_WRITE), -+ MAP_SHARED, fd, 0); -+ __close (fd); -+ if (addr == MAP_FAILED) -+ return (void *) -1; -+ -+ err = __sysvshm_add (addr, statbuf.st_size); -+ if (err) -+ { -+ munmap (addr, statbuf.st_size); -+ return (void *) -1; -+ } -+ -+ return addr; -+} -+ -+weak_alias(__shmat, shmat) ---- /dev/null -+++ b/sysdeps/mach/hurd/shmctl.c -@@ -0,0 +1,132 @@ -+/* Copyright (C) 2005 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. */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "sysvshm.h" -+ -+/* Provide operations to control over shared memory segments. */ -+int -+__shmctl (int id, int cmd, struct shmid_ds *buf) -+{ -+ error_t err = 0; -+ int fd; -+ int res; -+ char filename[sizeof (SHM_DIR) - 1 + SHM_NAMEMAX]; -+ struct stat statbuf; -+ -+ sprintf (filename, SHM_DIR SHM_NAMEPRI, id); -+ /* SysV requires read access for IPC_STAT. */ -+ fd = __open (filename, O_NORW); -+ if (fd < 0) -+ { -+ if (errno == ENOENT) -+ errno = EINVAL; -+ return -1; -+ } -+ -+ res = __fstat (fd, &statbuf); -+ if (res < 0) -+ { -+ err = errno; -+ __close (fd); -+ errno = err; -+ return -1; -+ } -+ -+ switch (cmd) -+ { -+ case IPC_STAT: -+ -+ buf->shm_perm.__key = id; -+ buf->shm_perm.uid = statbuf.st_uid; -+ buf->shm_perm.gid = statbuf.st_gid; -+ -+ /* We do not support the creator. */ -+ buf->shm_perm.cuid = statbuf.st_uid; -+ buf->shm_perm.cgid = statbuf.st_gid; -+ -+ /* We just want the protection bits. */ -+ buf->shm_perm.mode = statbuf.st_mode & 0777; -+ /* Hopeless. We do not support a sequence number. */ -+ buf->shm_perm.__seq = statbuf.st_ino; -+ buf->shm_segsz = statbuf.st_size; -+ -+ /* Hopeless. We do not support any of these. */ -+ buf->shm_atime = statbuf.st_atime; -+ buf->shm_dtime = statbuf.st_mtime; -+ /* Well, this comes at least close. */ -+ buf->shm_ctime = statbuf.st_ctime; -+ -+ /* We do not support the PID. */ -+ buf->shm_cpid = 0; -+ buf->shm_lpid = 0; -+ -+ if (statbuf.st_mode & S_IMMAP0) -+ buf->shm_nattch = 0; -+ else -+ /* 42 is the answer. Of course this is bogus, but for most -+ applications, this should be fine. */ -+ buf->shm_nattch = 42; -+ -+ break; -+ -+ case IPC_SET: -+ if (statbuf.st_uid != buf->shm_perm.uid -+ || statbuf.st_gid != buf->shm_perm.gid) -+ { -+ res = __fchown (fd, -+ (statbuf.st_uid != buf->shm_perm.uid) -+ ? buf->shm_perm.uid : -1, -+ (statbuf.st_gid != buf->shm_perm.gid) -+ ? buf->shm_perm.gid : -1); -+ if (res < 0) -+ err = errno; -+ } -+ -+ if (!err && statbuf.st_mode & 0777 != buf->shm_perm.mode & 0777) -+ { -+ res = __fchmod (fd, (statbuf.st_mode & ~0777) -+ | (buf->shm_perm.mode & 0777)); -+ if (res < 0) -+ err = errno; -+ } -+ break; -+ -+ case IPC_RMID: -+ res = __unlink (filename); -+ /* FIXME: Check error (mapping ENOENT to EINVAL). */ -+ break; -+ -+ default: -+ err = EINVAL; -+ } -+ -+ __close (fd); -+ errno = err; -+ return err ? -1 : 0; -+} -+ -+weak_alias(__shmctl, shmctl) ---- /dev/null -+++ b/sysdeps/mach/hurd/shmdt.c -@@ -0,0 +1,51 @@ -+/* Copyright (C) 2005 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. */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "sysvshm.h" -+ -+/* Detach shared memory segment starting at address specified by -+ SHMADDR from the caller's data segment. */ -+int -+__shmdt (const void *shmaddr) -+{ -+ error_t err; -+ size_t size; -+ -+ err = __sysvshm_remove ((void *) shmaddr, &size); -+ if (err) -+ { -+ errno = err; -+ return -1; -+ } -+ -+ __munmap ((void *) shmaddr, size); -+ return 0; -+} -+ -+weak_alias(__shmdt, shmdt) ---- /dev/null -+++ b/sysdeps/mach/hurd/shmget.c -@@ -0,0 +1,242 @@ -+/* Copyright (C) 2005 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. */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "sysvshm.h" -+ -+/* Create a new shared memory segment file without linking it into the -+ filesystem. Return the directory and file ports in R_DIR and R_FILE. */ -+static error_t -+create_shm_file (size_t size, int flags, file_t *r_dir, file_t *r_file) -+{ -+ error_t err; -+ file_t dir; -+ file_t file; -+ -+ flags &= 0777; -+ -+ /* Get a port to the directory that will contain the file. */ -+ dir = __file_name_lookup (SHM_DIR, 0, 0); -+ if (dir == MACH_PORT_NULL) -+ return errno; -+ -+ /* Create an unnamed file in the directory. */ -+ err = __dir_mkfile (dir, O_RDWR, flags, &file); -+ if (err) -+ { -+ __mach_port_deallocate (__mach_task_self (), dir); -+ return err; -+ } -+ -+ err = __file_set_size (file, size); -+ if (err) -+ { -+ __mach_port_deallocate (__mach_task_self (), file); -+ __mach_port_deallocate (__mach_task_self (), dir); -+ -+ return err; -+ } -+ -+ *r_dir = dir; -+ *r_file = file; -+ -+ return 0; -+} -+ -+ -+/* Open the shared memory segment *R_KEY and return a file descriptor -+ to it in R_FD. If KEY is IPC_PRIVATE, use a private key and return -+ it in R_KEY. */ -+static error_t -+get_exclusive (int shmflags, size_t size, key_t *r_key, int *r_fd) -+{ -+ error_t err; -+ file_t dir; -+ file_t file; -+ char filename[SHM_NAMEMAX]; -+ key_t key = *r_key; -+ bool is_private; -+ -+ /* Create the shared memory segment. */ -+ err = create_shm_file (size, shmflags, &dir, &file); -+ if (err) -+ return err; -+ -+ if (key == IPC_PRIVATE) -+ { -+ is_private = true; -+ key = SHM_PRIV_KEY_START; -+ -+ /* Try to link the shared memory segment into the filesystem -+ (exclusively). Private segments have negative keys. */ -+ do -+ { -+ sprintf (filename, SHM_NAMEPRI, key); -+ err = __dir_link (dir, file, filename, 1); -+ if (!err) -+ { -+ /* We are done. */ -+ *r_key = key; -+ break; -+ } -+ else if (err == EEXIST) -+ { -+ /* Check if we ran out of keys. If not, try again with new -+ key. */ -+ if (key == SHM_PRIV_KEY_END) -+ err = ENOSPC; -+ else -+ err = 0; -+ -+ key--; -+ } -+ } -+ while (!err); -+ } -+ else -+ { -+ /* Try to link the shared memory segment into the filesystem -+ (exclusively) under the given key. */ -+ sprintf (filename, SHM_NAMEPRI, key); -+ err = __dir_link (dir, file, filename, 1); -+ } -+ -+ __mach_port_deallocate (__mach_task_self (), dir); -+ -+ if (!err) -+ { -+ int fd; -+ -+ /* Get a file descriptor for that port. */ -+ fd = _hurd_intern_fd (file, O_RDWR, 1); /* dealloc on error */ -+ if (fd < 0) -+ err = errno; -+ else -+ *r_fd = fd; -+ } -+ -+ return err; -+} -+ -+ -+/* Open the shared memory segment KEY (creating it if it doesn't yet -+ exist) and return a file descriptor to it in R_FD. */ -+static error_t -+get_shared (int shmflags, size_t size, key_t key, int *r_fd) -+{ -+ error_t err = 0; -+ char filename[sizeof (SHM_DIR) - 1 + SHM_NAMEMAX]; -+ int fd = -1; -+ sprintf (filename, SHM_DIR SHM_NAMEPRI, key); -+ -+ do -+ { -+ fd = __open (filename, O_NORW, shmflags & 0777); -+ -+ if (fd < 0 && errno != ENOENT) -+ /* We give up. */ -+ return errno; -+ else if (fd >= 0) -+ { -+ int res; -+ struct stat statbuf; -+ -+ /* Check the size (we only need to do this if we did not -+ create the shared memory segment file ourselves). */ -+ res = __fstat (fd, &statbuf); -+ if (res < 0) -+ { -+ err = errno; -+ __close (fd); -+ return err; -+ } -+ -+ if (statbuf.st_size < size) -+ { -+ __close (fd); -+ return EINVAL; -+ } -+ } -+ else -+ { -+ /* The memory segment doesn't exist. */ -+ if (shmflags & IPC_CREAT) -+ { -+ /* Try to create it exclusively. */ -+ err = get_exclusive (shmflags, size, &key, &fd); -+ if (err == EEXIST) -+ /* If somebody created it in the meanwhile, just try again. */ -+ err = 0; -+ } -+ else -+ err = ENOENT; -+ } -+ } -+ while (fd < 0 && !err); -+ -+ if (!err) -+ *r_fd = fd; -+ else -+ *r_fd = -1; -+ -+ return err; -+} -+ -+/* Return an identifier for an shared memory segment of at least size -+ SIZE which is associated with KEY. */ -+int -+__shmget (key_t key, size_t size, int shmflags) -+{ -+ error_t err; -+ int fd; -+ -+ if (key == IPC_PRIVATE || shmflags & IPC_EXCL) -+ /* An exclusive shared memory segment must be created. */ -+ err = get_exclusive (shmflags, size, &key, &fd); -+ else -+ err = get_shared (shmflags, size, key, &fd); -+ -+ if (err) -+ { -+ errno = err; -+ return -1; -+ } -+ -+ /* From here, we can't fail. That's important, as otherwise we -+ would need to unlink the file if we created it (in that case, the -+ code above would have to be changed to pass a "created" flag down -+ to the caller). */ -+ -+ __close (fd); -+ -+ return key; -+} -+ -+weak_alias(__shmget, shmget) ---- a/sysdeps/mach/hurd/bits/posix_opt.h -+++ b/sysdeps/mach/hurd/bits/posix_opt.h -@@ -69,8 +69,8 @@ - /* X/Open thread realtime support is not supported. */ - #undef _XOPEN_REALTIME_THREADS - --/* XPG4.2 shared memory is not supported. */ --#undef _XOPEN_SHM -+/* XPG4.2 shared memory is supported. */ -+#define _XOPEN_SHM 1 - - /* We do not have the POSIX threads interface. */ - #define _POSIX_THREADS -1 reverted: --- eglibc-2.15/debian/patches/hurd-i386/submitted-ioctl-decode-argument.diff +++ eglibc-2.15.orig/debian/patches/hurd-i386/submitted-ioctl-decode-argument.diff @@ -1,67 +0,0 @@ -=http://www.sourceware.org/bugzilla/show_bug.cgi?id=766 - -2005-07-28 Samuel Thibault - - * ioctl.c (__ioctl): Add handling of parameter-less ioctls. - -2005-07-28 Samuel Thibault - - * ioctls.h (_IOIW): New macro for immediate-write ioctls. - -No topgit branch, TODO. - ---- - sysdeps/mach/hurd/bits/ioctls.h | 1 + - sysdeps/mach/hurd/ioctl.c | 16 ++++++++++------ - 2 files changed, 11 insertions(+), 6 deletions(-) - ---- a/sysdeps/mach/hurd/ioctl.c -+++ b/sysdeps/mach/hurd/ioctl.c -@@ -89,7 +89,7 @@ - void *p; - #endif - -- void *arg; -+ void *arg = NULL; - - error_t err; - -@@ -140,7 +140,7 @@ - in (_IOT_COUNT1 (type), _IOT_TYPE1 (type)); - in (_IOT_COUNT2 (type), _IOT_TYPE2 (type)); - } -- else if (_IOC_INOUT (request) == IOC_VOID) -+ else if ((_IOC_INOUT (request) == IOC_VOID) && _IOT_COUNT0 (type)) - { - /* The RPC takes a single integer_t argument. - Rather than pointing to the value, ARG is the value itself. */ -@@ -209,11 +209,15 @@ - return msg.header.RetCode; - } - -- va_list ap; -+ if (_IOT_COUNT0 (type)) -+ { -+ /* Data need either be sent, received, or even both. */ -+ va_list ap; - -- va_start (ap, request); -- arg = va_arg (ap, void *); -- va_end (ap); -+ va_start (ap, request); -+ arg = va_arg (ap, void *); -+ va_end (ap); -+ } - - { - /* Check for a registered handler for REQUEST. */ ---- a/sysdeps/mach/hurd/bits/ioctls.h -+++ b/sysdeps/mach/hurd/bits/ioctls.h -@@ -158,6 +158,7 @@ - _IOT_foobar is defined either in this file, - or where struct foobar is defined. */ - #define _IO(g, n) _IOC (IOC_VOID, (g), (n), 0) -+#define _IOIW(g, n, t) _IOC (IOC_VOID, (g), (n), _IOC_ENCODE_TYPE (t)) - #define _IOR(g, n, t) _IOC (IOC_OUT, (g), (n), _IOC_ENCODE_TYPE (t)) - #define _IOW(g, n, t) _IOC (IOC_IN, (g), (n), _IOC_ENCODE_TYPE (t)) - #define _IOWR(g, n, t) _IOC (IOC_INOUT, (g), (n), _IOC_ENCODE_TYPE (t)) reverted: --- eglibc-2.15/debian/patches/hurd-i386/unsubmitted-sendmsg-SCM_RIGHTS.diff +++ eglibc-2.15.orig/debian/patches/hurd-i386/unsubmitted-sendmsg-SCM_RIGHTS.diff @@ -1,274 +0,0 @@ -From 1b911148009f696717da0b676d6d10af85d5aefb Mon Sep 17 00:00:00 2001 -From: Emilio Pozuelo Monfort -Date: Sat, 17 Jul 2010 22:09:13 +0200 -Subject: [PATCH] Add support to send file descriptors over Unix sockets - -No togpit branch, TODO. - ---- - sysdeps/mach/hurd/recvmsg.c | 108 ++++++++++++++++++++++++++++++++++++++++++-- - sysdeps/mach/hurd/sendmsg.c | 73 ++++++++++++++++++++++++----- - 2 files changed, 166 insertions(+), 15 deletions(-) - ---- a/sysdeps/mach/hurd/recvmsg.c -+++ b/sysdeps/mach/hurd/recvmsg.c -@@ -1,4 +1,4 @@ --/* Copyright (C) 2001, 2002 Free Software Foundation, Inc. -+/* Copyright (C) 2001, 2002, 2010 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 -@@ -33,13 +33,33 @@ - addr_port_t aport; - char *data = NULL; - mach_msg_type_number_t len = 0; -- mach_port_t *ports; -+ mach_port_t *ports, *newports; - mach_msg_type_number_t nports = 0; -+ struct cmsghdr *cmsg; - char *cdata = NULL; - mach_msg_type_number_t clen = 0; - size_t amount; - char *buf; -- int i; -+ int nfds, *fds; -+ int i, j; -+ -+ error_t reauthenticate (mach_port_t port, mach_port_t *result) -+ { -+ error_t err; -+ mach_port_t ref; -+ ref = __mach_reply_port (); -+ do -+ err = __io_reauthenticate (port, ref, MACH_MSG_TYPE_MAKE_SEND); -+ while (err == EINTR); -+ if (!err) -+ do -+ err = __USEPORT (AUTH, __auth_user_authenticate (port, -+ ref, MACH_MSG_TYPE_MAKE_SEND, -+ result)); -+ while (err == EINTR); -+ __mach_port_destroy (__mach_task_self (), ref); -+ return err; -+ } - - /* Find the total number of bytes to be read. */ - amount = 0; -@@ -136,6 +156,85 @@ - message->msg_controllen = clen; - memcpy (message->msg_control, cdata, message->msg_controllen); - -+ /* SCM_RIGHTS ports. */ -+ if (nports > 0) -+ { -+ newports = __alloca (nports * sizeof (mach_port_t)); -+ -+ /* Reauthenticate all ports here. */ -+ for (i = 0; i < nports; i++) -+ { -+ err = reauthenticate (ports[i], &newports[i]); -+ __mach_port_deallocate (__mach_task_self (), ports[i]); -+ if (err) -+ { -+ for (j = 0; j < i; j++) -+ __mach_port_deallocate (__mach_task_self (), newports[j]); -+ for (j = i+1; j < nports; j++) -+ __mach_port_deallocate (__mach_task_self (), ports[j]); -+ -+ __vm_deallocate (__mach_task_self (), (vm_address_t) cdata, clen); -+ __hurd_fail (err); -+ } -+ } -+ -+ j = 0; -+ for (cmsg = CMSG_FIRSTHDR (message); -+ cmsg; -+ cmsg = CMSG_NXTHDR (message, cmsg)) -+ { -+ if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) -+ { -+ fds = (int *) CMSG_DATA (cmsg); -+ nfds = (cmsg->cmsg_len - CMSG_ALIGN (sizeof (struct cmsghdr))) -+ / sizeof (int); -+ -+ for (i = 0; i < nfds && j < nports; i++) -+ { -+ /* The fd's flags are passed in the control data. */ -+ fds[i] = _hurd_intern_fd (newports[j++], fds[i], 0); -+ if (fds[i] == -1) -+ { -+ err = errno; -+ goto cleanup; -+ } -+ } -+ } -+ } -+ -+ if (j != nports) -+ err = EGRATUITOUS; -+ -+ if (err) -+ cleanup: -+ { -+ /* Clean up all the file descriptors. */ -+ nports = j; -+ j = 0; -+ for (cmsg = CMSG_FIRSTHDR (message); -+ cmsg; -+ cmsg = CMSG_NXTHDR (message, cmsg)) -+ { -+ if (cmsg->cmsg_level == SOL_SOCKET -+ && cmsg->cmsg_type == SCM_RIGHTS) -+ { -+ fds = (int *) CMSG_DATA (cmsg); -+ nfds = (cmsg->cmsg_len -+ - CMSG_ALIGN (sizeof (struct cmsghdr))) -+ / sizeof (int); -+ for (i = 0; i < nfds && j < nports; i++, j++) -+ _hurd_fd_close (_hurd_fd_get (fds[i])); -+ } -+ } -+ -+ for (; j < nports; j++) -+ __mach_port_deallocate (__mach_task_self (), newports[j]); -+ -+ __vm_deallocate (__mach_task_self (), (vm_address_t) cdata, clen); -+ __hurd_fail (err); -+ } -+ } -+ - __vm_deallocate (__mach_task_self (), (vm_address_t) cdata, clen); - - return (buf - data); ---- a/sysdeps/mach/hurd/sendmsg.c -+++ b/sysdeps/mach/hurd/sendmsg.c -@@ -1,4 +1,4 @@ --/* Copyright (C) 2001,2002,2004 Free Software Foundation, Inc. -+/* Copyright (C) 2001,2002,2004,2010 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 -@@ -32,6 +32,10 @@ - __libc_sendmsg (int fd, const struct msghdr *message, int flags) - { - error_t err = 0; -+ struct cmsghdr *cmsg; -+ mach_port_t *ports = NULL; -+ mach_msg_type_number_t nports = 0; -+ int *fds, nfds; - struct sockaddr_un *addr = message->msg_name; - socklen_t addr_len = message->msg_namelen; - addr_port_t aport = MACH_PORT_NULL; -@@ -44,6 +48,7 @@ - mach_msg_type_number_t len; - mach_msg_type_number_t amount; - int dealloc = 0; -+ int socketrpc = 0; - int i; - - /* Find the total number of bytes to be written. */ -@@ -101,6 +106,46 @@ - } - } - -+ /* SCM_RIGHTS support: get the number of fds to send. */ -+ cmsg = CMSG_FIRSTHDR (message); -+ for (; cmsg; cmsg = CMSG_NXTHDR (message, cmsg)) -+ if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) -+ nports += (cmsg->cmsg_len - CMSG_ALIGN (sizeof (struct cmsghdr))) -+ / sizeof (int); -+ -+ if (nports) -+ ports = __alloca (nports * sizeof (mach_port_t)); -+ -+ nports = 0; -+ for (cmsg = CMSG_FIRSTHDR (message); -+ cmsg; -+ cmsg = CMSG_NXTHDR (message, cmsg)) -+ { -+ if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) -+ { -+ fds = (int *) CMSG_DATA (cmsg); -+ nfds = (cmsg->cmsg_len - CMSG_ALIGN (sizeof (struct cmsghdr))) -+ / sizeof (int); -+ -+ for (i = 0; i < nfds; i++) -+ { -+ err = HURD_DPORT_USE -+ (fds[i], -+ ({ -+ err = __io_restrict_auth (port, &ports[nports], -+ 0, 0, 0, 0); -+ if (! err) -+ nports++; -+ /* We pass the flags in the control data. */ -+ fds[i] = descriptor->flags; -+ })); -+ -+ if (err) -+ goto out; -+ } -+ } -+ } -+ - if (addr) - { - if (addr->sun_family == AF_LOCAL) -@@ -110,9 +155,8 @@ - file_t file = __file_name_lookup (addr->sun_path, 0, 0); - if (file == MACH_PORT_NULL) - { -- if (dealloc) -- __vm_deallocate (__mach_task_self (), data.addr, len); -- return -1; -+ err = errno; -+ goto out; - } - err = __ifsock_getsockaddr (file, &aport); - __mach_port_deallocate (__mach_task_self (), file); -@@ -120,11 +164,7 @@ - /* The file did not grok the ifsock protocol. */ - err = ENOTSOCK; - if (err) -- { -- if (dealloc) -- __vm_deallocate (__mach_task_self (), data.addr, len); -- return __hurd_fail (err); -- } -+ goto out; - } - else - err = EIEIO; -@@ -143,8 +183,9 @@ - /* Send the data. */ - err = __socket_send (port, aport, - flags, data.ptr, len, -- NULL, -- MACH_MSG_TYPE_COPY_SEND, 0, -+ ports, -+ MACH_MSG_TYPE_COPY_SEND, -+ nports, - message->msg_control, - message->msg_controllen, - &amount); -@@ -153,11 +194,19 @@ - } - err; - })); -+ socketrpc = 1; -+ -+ out: -+ for (i = 0; i < nports; i++) -+ __mach_port_deallocate (__mach_task_self (), ports[i]); - - if (dealloc) - __vm_deallocate (__mach_task_self (), data.addr, len); - -- return err ? __hurd_sockfail (fd, flags, err) : amount; -+ if (socketrpc) -+ return err ? __hurd_sockfail (fd, flags, err) : amount; -+ else -+ return __hurd_fail (err); - } - - weak_alias (__libc_sendmsg, sendmsg) reverted: --- eglibc-2.15/debian/patches/hurd-i386/unsubmitted-thread-cancel.diff +++ eglibc-2.15.orig/debian/patches/hurd-i386/unsubmitted-thread-cancel.diff @@ -1,18 +0,0 @@ -The critical section lock _can_ be held in that place. - -No topgit branch, TODO. - ---- - hurd/thread-cancel.c | 1 - - 1 file changed, 1 deletion(-) - ---- a/hurd/thread-cancel.c -+++ b/hurd/thread-cancel.c -@@ -52,7 +52,6 @@ - return 0; - } - -- assert (! __spin_lock_locked (&ss->critical_section_lock)); - __spin_lock (&ss->critical_section_lock); - __spin_lock (&ss->lock); - err = __thread_suspend (thread); reverted: --- eglibc-2.15/debian/patches/hurd-i386/submitted-ttyname_ERANGE.diff +++ eglibc-2.15.orig/debian/patches/hurd-i386/submitted-ttyname_ERANGE.diff @@ -1,22 +0,0 @@ -http://sourceware.org/ml/libc-alpha/2011-08/msg00013.html - -2011-08-05 Samuel Thibault - - * sysdeps/mach/hurd/ttyname_r.c (__ttyname_r): Return ERANGE instead of - EINVAL when BUFLEN is too smal. - -No topgit branch, TODO. - -diff --git a/sysdeps/mach/hurd/ttyname_r.c b/sysdeps/mach/hurd/ttyname_r.c -index 5f6c9c3..5718fca 100644 ---- a/sysdeps/mach/hurd/ttyname_r.c -+++ b/sysdeps/mach/hurd/ttyname_r.c -@@ -43,7 +43,7 @@ __ttyname_r (int fd, char *buf, size_t buflen) - len = strlen (nodename) + 1; - if (len > buflen) - { -- errno = EINVAL; -+ errno = ERANGE; - return errno; - } - reverted: --- eglibc-2.15/debian/patches/hurd-i386/submitted-select-inputcheck.diff +++ eglibc-2.15.orig/debian/patches/hurd-i386/submitted-select-inputcheck.diff @@ -1,52 +0,0 @@ -http://cygwin.com/ml/libc-alpha/2011-12/msg00012.html - -_hurd_select: check for invalid parameter values - -Check for invalid values of the `timeout' and `nfds' parameters; move the -calculation of `to' right after the validation of `timeout'. - -2011-11-26 Pino Toscano - - * hurd/hurdselect.c (_hurd_select): Return EINVAL for negative - `timeout' values. - Return EINVAL for `nfds' values either negative or greater than - FD_SETSIZE. ---- a/hurd/hurdselect.c -+++ b/hurd/hurdselect.c -@@ -50,10 +50,7 @@ _hurd_select (int nfds, - error_t err; - fd_set rfds, wfds, xfds; - int firstfd, lastfd; -- mach_msg_timeout_t to = (timeout != NULL ? -- (timeout->tv_sec * 1000 + -- (timeout->tv_nsec + 999999) / 1000000) : -- 0); -+ mach_msg_timeout_t to = 0; - struct - { - struct hurd_userlink ulink; -@@ -72,6 +69,24 @@ _hurd_select (int nfds, - assert (sizeof (union typeword) == sizeof (mach_msg_type_t)); - assert (sizeof (uint32_t) == sizeof (mach_msg_type_t)); - -+ if (nfds < 0 || nfds > FD_SETSIZE) -+ { -+ errno = EINVAL; -+ return -1; -+ } -+ -+ if (timeout != NULL) -+ { -+ if (timeout->tv_sec < 0 || timeout->tv_nsec < 0) -+ { -+ errno = EINVAL; -+ return -1; -+ } -+ -+ to = timeout->tv_sec * 1000 + -+ (timeout->tv_nsec + 999999) / 1000000; -+ } -+ - if (sigmask && __sigprocmask (SIG_SETMASK, sigmask, &oset)) - return -1; - reverted: --- eglibc-2.15/debian/patches/hurd-i386/submitted-ioctl-unsigned-size_t.diff +++ eglibc-2.15.orig/debian/patches/hurd-i386/submitted-ioctl-unsigned-size_t.diff @@ -1,51 +0,0 @@ -Add some basic types for ioctls. - -http://sources.redhat.com/ml/libc-alpha/2007-07/msg00078.html - -No topgit branch, TODO. - ---- - sysdeps/mach/hurd/bits/ioctls.h | 14 +++++++++++++- - 1 file changed, 13 insertions(+), 1 deletion(-) - ---- a/sysdeps/mach/hurd/bits/ioctls.h -+++ b/sysdeps/mach/hurd/bits/ioctls.h -@@ -149,9 +149,26 @@ - #define _IOT_SIMPLE(type) _IOT (_IOTS (type), 1, 0, 0, 0, 0) - - /* Basic C types. */ --#define _IOT__IOTBASE_int _IOT_SIMPLE (int) - #define _IOT__IOTBASE_char _IOT_SIMPLE (char) - #define _IOT__IOTBASE_short _IOT_SIMPLE (short) -+#define _IOT__IOTBASE_int _IOT_SIMPLE (int) -+#define _IOT__IOTBASE_long _IOT_SIMPLE (long) -+#define _IOT_char _IOT_SIMPLE (char) -+#define _IOT_short _IOT_SIMPLE (short) -+#define _IOT_int _IOT_SIMPLE (int) -+#define _IOT_long _IOT_SIMPLE (long) -+ -+#define _IOT__IOTBASE_int8_t _IOT_SIMPLE (int8_t) -+#define _IOT__IOTBASE_uint8_t _IOT_SIMPLE (uint8_t) -+#define _IOT__IOTBASE_int16_t _IOT_SIMPLE (int16_t) -+#define _IOT__IOTBASE_uint16_t _IOT_SIMPLE (uint16_t) -+#define _IOT__IOTBASE_int32_t _IOT_SIMPLE (int32_t) -+#define _IOT__IOTBASE_uint32_t _IOT_SIMPLE (uint32_t) -+#define _IOT__IOTBASE_int64_t _IOT_SIMPLE (int64_t) -+#define _IOT__IOTBASE_uint64_t _IOT_SIMPLE (uint64_t) -+ -+#define _IOT__IOTBASE_size_t _IOT_SIMPLE (size_t) -+#define _IOT__IOTBASE_ssize_t _IOT_SIMPLE (ssize_t) - - - /* Standard flavors of ioctls. -@@ -174,6 +182,10 @@ - #define _IOC_ENCODE_TYPE_1(typespec) _IOC_ENCODE_TYPE_2(typespec) - #define _IOC_ENCODE_TYPE_2(typespec) _IOT_##typespec - -+/* Also, ignore signedness. */ -+#define _IOTBASE_unsigned -+#define _IOTBASE_signed -+ - - /* ioctls verbatim from 4.4 . */ - reverted: --- eglibc-2.15/debian/patches/hurd-i386/submitted-setresid.diff +++ eglibc-2.15.orig/debian/patches/hurd-i386/submitted-setresid.diff @@ -1,229 +0,0 @@ -http://cygwin.com/ml/libc-alpha/2011-10/msg00031.html - -2011-10-17 Samuel Thibault - -* sysdeps/mach/hurd/setresgid.c (__setresgid): Handle the -1 case, which -shall preserve existing values. -* sysdeps/mach/hurd/setresuid.c (__setresuid): Likewise. - -No topgit branch, TODO. - ---- - setresgid.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++------------ - setresuid.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++------------ - 2 files changed, 118 insertions(+), 28 deletions(-) - -diff --git a/sysdeps/mach/hurd/setresgid.c b/sysdeps/mach/hurd/setresgid.c -index 8fcf26e..2a0dd90 100644 ---- a/sysdeps/mach/hurd/setresgid.c -+++ b/sysdeps/mach/hurd/setresgid.c -@@ -1,5 +1,5 @@ - /* setresgid -- set real group ID, effective group ID, and saved-set group ID -- Copyright (C) 2002, 2005, 2006 Free Software Foundation, Inc. -+ Copyright (C) 2002, 2005, 2006, 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 -@@ -29,7 +29,6 @@ __setresgid (gid_t rgid, gid_t egid, gid_t sgid) - { - auth_t newauth; - error_t err; -- gid_t agids[2] = { rgid, sgid }; - - HURD_CRITICAL_BEGIN; - __mutex_lock (&_hurd_id.lock); -@@ -40,29 +39,75 @@ __setresgid (gid_t rgid, gid_t egid, gid_t sgid) - /* Make a new auth handle which has EGID as the first element in the - list of effective gids. */ - -- if (_hurd_id.gen.ngids > 0) -+ uid_t *newgen, *newaux; -+ uid_t auxs[2] = { rgid, sgid }; -+ size_t ngen, naux; -+ -+ newgen = _hurd_id.gen.gids; -+ ngen = _hurd_id.gen.ngids; -+ if (egid != -1) -+ { -+ if (_hurd_id.gen.ngids == 0) -+ { -+ /* No effective gids now. The new set will be just UID. */ -+ newgen = &egid; -+ ngen = 1; -+ } -+ else -+ { -+ _hurd_id.gen.gids[0] = egid; -+ _hurd_id.valid = 0; -+ } -+ } -+ -+ newaux = _hurd_id.aux.gids; -+ naux = _hurd_id.aux.ngids; -+ if (rgid != -1) - { -- _hurd_id.gen.gids[0] = egid; -- _hurd_id.valid = 0; -+ if (_hurd_id.aux.ngids == 0) -+ { -+ newaux = &rgid; -+ naux = 1; -+ } -+ else -+ { -+ _hurd_id.aux.gids[0] = rgid; -+ _hurd_id.valid = 0; -+ } - } -- if (_hurd_id.aux.ngids > 1) -+ -+ if (sgid != -1) - { -- _hurd_id.aux.gids[0] = rgid; -- _hurd_id.aux.gids[1] = sgid; -- _hurd_id.valid = 0; -+ if (rgid == -1) -+ { -+ if (_hurd_id.aux.ngids >= 1) -+ auxs[0] = _hurd_id.aux.gids[0]; -+ else if (_hurd_id.gen.ngids >= 1) -+ auxs[0] = _hurd_id.gen.gids[0]; -+ else -+ /* Not even an effective gid, fallback to the only UID we have. */ -+ auxs[0] = sgid; -+ } -+ if (_hurd_id.aux.ngids <= 1) -+ { -+ /* No saved gids now. The new set will be just UID. */ -+ newaux = auxs; -+ naux = 2; -+ } -+ else -+ { -+ _hurd_id.aux.gids[1] = sgid; -+ _hurd_id.valid = 0; -+ } - } - - err = __USEPORT (AUTH, __auth_makeauth - (port, NULL, MACH_MSG_TYPE_COPY_SEND, 0, - _hurd_id.gen.uids, _hurd_id.gen.nuids, - _hurd_id.aux.uids, _hurd_id.aux.nuids, -- _hurd_id.gen.ngids ? _hurd_id.gen.gids : &egid, -- _hurd_id.gen.ngids ?: 1, -- _hurd_id.aux.ngids > 1 ? _hurd_id.aux.gids : agids, -- _hurd_id.aux.ngids > 1 ? _hurd_id.aux.ngids : 2, -+ newgen, ngen, newaux, naux, - &newauth)); - } -- - __mutex_unlock (&_hurd_id.lock); - HURD_CRITICAL_END; - -diff --git a/sysdeps/mach/hurd/setresuid.c b/sysdeps/mach/hurd/setresuid.c -index ccf8d08..e254437 100644 ---- a/sysdeps/mach/hurd/setresuid.c -+++ b/sysdeps/mach/hurd/setresuid.c -@@ -1,5 +1,5 @@ - /* setresuid -- set real user ID, effective user ID, and saved-set user ID -- Copyright (C) 2002, 2005, 2006 Free Software Foundation, Inc. -+ Copyright (C) 2002, 2005, 2006, 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 -@@ -29,7 +29,6 @@ __setresuid (uid_t ruid, uid_t euid, uid_t suid) - { - auth_t newauth; - error_t err; -- uid_t auids[2] = { ruid, suid }; - - HURD_CRITICAL_BEGIN; - __mutex_lock (&_hurd_id.lock); -@@ -40,29 +39,75 @@ __setresuid (uid_t ruid, uid_t euid, uid_t suid) - /* Make a new auth handle which has EUID as the first element in the - list of effective uids. */ - -- if (_hurd_id.gen.nuids > 0) -+ uid_t *newgen, *newaux; -+ uid_t auxs[2] = { ruid, suid }; -+ size_t ngen, naux; -+ -+ newgen = _hurd_id.gen.uids; -+ ngen = _hurd_id.gen.nuids; -+ if (euid != -1) -+ { -+ if (_hurd_id.gen.nuids == 0) -+ { -+ /* No effective uids now. The new set will be just UID. */ -+ newgen = &euid; -+ ngen = 1; -+ } -+ else -+ { -+ _hurd_id.gen.uids[0] = euid; -+ _hurd_id.valid = 0; -+ } -+ } -+ -+ newaux = _hurd_id.aux.uids; -+ naux = _hurd_id.aux.nuids; -+ if (ruid != -1) - { -- _hurd_id.gen.uids[0] = euid; -- _hurd_id.valid = 0; -+ if (_hurd_id.aux.nuids == 0) -+ { -+ newaux = &ruid; -+ naux = 1; -+ } -+ else -+ { -+ _hurd_id.aux.uids[0] = ruid; -+ _hurd_id.valid = 0; -+ } - } -- if (_hurd_id.aux.nuids > 1) -+ -+ if (suid != -1) - { -- _hurd_id.aux.uids[0] = ruid; -- _hurd_id.aux.uids[1] = suid; -- _hurd_id.valid = 0; -+ if (ruid == -1) -+ { -+ if (_hurd_id.aux.nuids >= 1) -+ auxs[0] = _hurd_id.aux.uids[0]; -+ else if (_hurd_id.gen.nuids >= 1) -+ auxs[0] = _hurd_id.gen.uids[0]; -+ else -+ /* Not even an effective uid, fallback to the only UID we have. */ -+ auxs[0] = suid; -+ } -+ if (_hurd_id.aux.nuids <= 1) -+ { -+ /* No saved uids now. The new set will be just UID. */ -+ newaux = auxs; -+ naux = 2; -+ } -+ else -+ { -+ _hurd_id.aux.uids[1] = suid; -+ _hurd_id.valid = 0; -+ } - } - - err = __USEPORT (AUTH, __auth_makeauth - (port, NULL, MACH_MSG_TYPE_COPY_SEND, 0, -- _hurd_id.gen.nuids ? _hurd_id.gen.uids : &euid, -- _hurd_id.gen.nuids ?: 1, -- _hurd_id.aux.nuids > 1 ? _hurd_id.aux.uids : auids, -- _hurd_id.aux.nuids > 1 ? _hurd_id.aux.nuids : 2, -+ newgen, ngen, newaux, naux, - _hurd_id.gen.gids, _hurd_id.gen.ngids, - _hurd_id.aux.gids, _hurd_id.aux.ngids, - &newauth)); - } -- - __mutex_unlock (&_hurd_id.lock); - HURD_CRITICAL_END; - reverted: --- eglibc-2.15/debian/patches/hurd-i386/unsubmitted-mkdir_root.diff +++ eglibc-2.15.orig/debian/patches/hurd-i386/unsubmitted-mkdir_root.diff @@ -1,57 +0,0 @@ -Fix mkdir / error value (needed for busybox's mkdir -p) - -In the / case, directory_name_split can't really split that into an -absolute ROOT file_t and ".", since name is supposed to be a pointer in -file_name... Changing the interface is being proposed. - -No topgit branch, TODO. - ---- - sysdeps/mach/hurd/mkdir.c | 6 +++++- - sysdeps/mach/hurd/mkdirat.c | 6 +++++- - 2 files changed, 10 insertions(+), 2 deletions(-) - ---- a/sysdeps/mach/hurd/mkdir.c -+++ b/sysdeps/mach/hurd/mkdir.c -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - - /* Create a directory named FILE_NAME with protections MODE. */ - int -@@ -29,7 +30,10 @@ - { - error_t err; - const char *name; -- file_t parent = __directory_name_split (file_name, (char **) &name); -+ file_t parent; -+ if (!strcmp(file_name, "/")) -+ return EEXIST; -+ parent = __directory_name_split (file_name, (char **) &name); - if (parent == MACH_PORT_NULL) - return -1; - err = __dir_mkdir (parent, name, mode & ~_hurd_umask); ---- a/sysdeps/mach/hurd/mkdirat.c -+++ b/sysdeps/mach/hurd/mkdirat.c -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - - int - mkdirat (fd, path, mode) -@@ -32,7 +33,10 @@ - { - error_t err; - const char *name; -- file_t parent = __directory_name_split_at (fd, path, (char **) &name); -+ file_t parent; -+ if (!strcmp(path, "/")) -+ return EEXIST; -+ parent = __directory_name_split_at (fd, path, (char **) &name); - if (parent == MACH_PORT_NULL) - return -1; - err = __dir_mkdir (parent, name, mode & ~_hurd_umask); reverted: --- eglibc-2.15/debian/patches/hurd-i386/unsubmitted-pthread_types.diff +++ eglibc-2.15.orig/debian/patches/hurd-i386/unsubmitted-pthread_types.diff @@ -1,12 +0,0 @@ -We do have pthread types. - -No topgit branch, TODO. - ---- - sysdeps/mach/hurd/bits/pthreadtypes.h | 1 + - 1 file changed, 1 insertion(+) - ---- /dev/null -+++ b/sysdeps/mach/hurd/bits/pthreadtypes.h -@@ -0,0 +1 @@ -+#include reverted: --- eglibc-2.15/debian/patches/hurd-i386/submitted-SOL_IP.patch +++ eglibc-2.15.orig/debian/patches/hurd-i386/submitted-SOL_IP.patch @@ -1,33 +0,0 @@ -2009-09-28 Samuel Thibault - - * bits/in.h (SOL_IP, SOL_IPV6, SOL_ICMPV6): New macros. - -No topgit branch, TODO. - ---- - bits/in.h | 7 +++++++ - 1 file changed, 7 insertions(+) - ---- a/bits/in.h -+++ b/bits/in.h -@@ -22,6 +22,9 @@ - # error "Never use directly; include instead." - #endif - -+/* To select the IP level. */ -+#define SOL_IP 0 -+ - /* Options for use with `getsockopt' and `setsockopt' at the IP level. - The first word in the comment at the right is the data type used; - "bool" means a boolean value stored in an `int'. */ -@@ -48,6 +51,10 @@ - char ip_opts[40]; /* Actually variable in size. */ - }; - -+/* Socket level values for IPv6. */ -+#define SOL_IPV6 41 -+#define SOL_ICMPV6 58 -+ - /* IPV6 socket options. */ - #define IPV6_ADDRFORM 1 - #define IPV6_PKTINFO 2 reverted: --- eglibc-2.15/debian/patches/hurd-i386/submitted-hurdsig-fixes.diff +++ eglibc-2.15.orig/debian/patches/hurd-i386/submitted-hurdsig-fixes.diff @@ -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. reverted: --- eglibc-2.15/debian/patches/hurd-i386/submitted-null-pathname.diff +++ eglibc-2.15.orig/debian/patches/hurd-i386/submitted-null-pathname.diff @@ -1,46 +0,0 @@ -http://sources.redhat.com/ml/libc-alpha/2009-09/msg00025.html - -2009-09-13 Samuel Thibault - - * hurd/hurdchdir.c (_hurd_change_directory_port_from_name): - Return ENOENT when name is empty. - * sysdeps/mach/hurd/chroot.c (chroot): Return ENOENT when path - is empty. - -No topgit branch, TODO. - ---- - hurd/hurdchdir.c | 6 ++++++ - sysdeps/mach/hurd/chroot.c | 6 ++++++ - 2 files changed, 12 insertions(+) - ---- a/hurd/hurdchdir.c -+++ b/hurd/hurdchdir.c -@@ -38,6 +38,12 @@ - len = strlen (name); - if (len >= 2 && name[len - 2] == '/' && name[len - 1] == '.') - lookup = name; -+ else if (len == 0) -+ { -+ /* Special-case null pathname according to POSIX */ -+ errno = ENOENT; -+ return -1; -+ } - else - { - char *n = alloca (len + 3); ---- a/sysdeps/mach/hurd/chroot.c -+++ b/sysdeps/mach/hurd/chroot.c -@@ -38,6 +38,12 @@ - len = strlen (path); - if (len >= 2 && path[len - 2] == '/' && path[len - 1] == '.') - lookup = path; -+ else if (len == 0) -+ { -+ /* Special-case null pathname according to POSIX */ -+ errno = ENOENT; -+ return -1; -+ } - else - { - char *n = alloca (len + 3); reverted: --- eglibc-2.15/debian/patches/hurd-i386/submitted-hurdsig-fixes-2.diff +++ eglibc-2.15.orig/debian/patches/hurd-i386/submitted-hurdsig-fixes-2.diff @@ -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. */ reverted: --- eglibc-2.15/debian/patches/hurd-i386/submitted-mach-nanosleep.diff +++ eglibc-2.15.orig/debian/patches/hurd-i386/submitted-mach-nanosleep.diff @@ -1,37 +0,0 @@ -http://cygwin.com/ml/libc-alpha/2011-12/msg00020.html - -mach: nanosleep: check for invalid parameter values - -Check for invalid values of the `requested_time' parameters; move the -calculation of `ms' after the validation of `requested_time'. - -2011-12-10 Pino Toscano - - * sysdeps/mach/nanosleep.c (__nanosleep): Return EINVAL for negative - seconds or nanoseconds of `requested_time', or for nanoseconds equal - or greater than 1000000000. ---- a/sysdeps/mach/nanosleep.c -+++ b/sysdeps/mach/nanosleep.c -@@ -28,11 +28,19 @@ __nanosleep (const struct timespec *requ - { - mach_port_t recv; - struct timeval before, after; -- const mach_msg_timeout_t ms -- = requested_time->tv_sec * 1000 -- + (requested_time->tv_nsec + 999999) / 1000000; -+ mach_msg_timeout_t ms; -+ -+ if (requested_time->tv_sec < 0 -+ || requested_time->tv_nsec < 0 -+ || requested_time->tv_nsec >= 1000000000) -+ { -+ errno = EINVAL; -+ return -1; -+ } - - recv = __mach_reply_port (); -+ ms = requested_time->tv_sec * 1000 -+ + (requested_time->tv_nsec + 999999) / 1000000; - - if (remaining && __gettimeofday (&before, NULL) < 0) - return -1; reverted: --- eglibc-2.15/debian/patches/hurd-i386/submitted-dup2-fix.diff +++ eglibc-2.15.orig/debian/patches/hurd-i386/submitted-dup2-fix.diff @@ -1,44 +0,0 @@ -Mutex locking fix. - -http://sources.redhat.com/ml/libc-alpha/2009-01/msg00030.html - ---- - sysdeps/mach/hurd/dup3.c | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - ---- a/sysdeps/mach/hurd/dup3.c -+++ b/sysdeps/mach/hurd/dup3.c -@@ -71,15 +71,14 @@ - /* Get a hold of the destination descriptor. */ - struct hurd_fd *d2; - -+ __mutex_lock (&_hurd_dtable_lock); -+ - if (fd2 >= _hurd_dtablesize) - { - /* The table is not large enough to hold the destination - descriptor. Enlarge it as necessary to allocate this - descriptor. */ - __mutex_unlock (&_hurd_dtable_lock); -- /* We still hold FD1's lock, but this is safe because -- _hurd_alloc_fd will only examine the cells starting -- at FD2. */ - d2 = _hurd_alloc_fd (NULL, fd2); - if (d2) - __spin_unlock (&d2->port.lock); -@@ -99,6 +98,7 @@ - MACH_PORT_NULL); - } - } -+ __mutex_unlock (&_hurd_dtable_lock); - - if (d2 == NULL) - { -@@ -126,7 +126,6 @@ - _hurd_port_locked_set (&d2->port, port); /* Unlocks D2. */ - } - } -- __mutex_unlock (&_hurd_dtable_lock); - - _hurd_port_free (&d->port, &ulink, port); - if (ctty != MACH_PORT_NULL) reverted: --- eglibc-2.15/debian/patches/hurd-i386/submitted-critical-sections.diff +++ eglibc-2.15.orig/debian/patches/hurd-i386/submitted-critical-sections.diff @@ -1,63 +0,0 @@ -Missing critical region locks. - -http://sources.redhat.com/ml/libc-alpha/2009-01/msg00030.html - -No topgit branch, TODO. - ---- - hurd/hurd/fd.h | 2 ++ - sysdeps/mach/hurd/dirfd.c | 3 +++ - sysdeps/mach/hurd/opendir.c | 2 ++ - 3 files changed, 7 insertions(+) - ---- a/hurd/hurd/fd.h -+++ b/hurd/hurd/fd.h -@@ -68,6 +68,7 @@ - { - struct hurd_fd *descriptor; - -+ HURD_CRITICAL_BEGIN; - __mutex_lock (&_hurd_dtable_lock); - if (fd < 0 || fd >= _hurd_dtablesize) - descriptor = NULL; -@@ -90,6 +91,7 @@ - } - } - __mutex_unlock (&_hurd_dtable_lock); -+ HURD_CRITICAL_END; - - return descriptor; - } ---- a/sysdeps/mach/hurd/dirfd.c -+++ b/sysdeps/mach/hurd/dirfd.c -@@ -26,6 +26,8 @@ - dirfd (DIR *dirp) - { - int fd; -+ -+ HURD_CRITICAL_BEGIN; - __mutex_lock (&_hurd_dtable_lock); - for (fd = 0; fd < _hurd_dtablesize; ++fd) - if (_hurd_dtable[fd] == dirp->__fd) -@@ -36,6 +38,7 @@ - fd = -1; - } - __mutex_unlock (&_hurd_dtable_lock); -+ HURD_CRITICAL_END; - - return fd; - } ---- a/sysdeps/mach/hurd/opendir.c -+++ b/sysdeps/mach/hurd/opendir.c -@@ -51,9 +51,11 @@ - return NULL; - - /* Set the descriptor to close on exec. */ -+ HURD_CRITICAL_BEGIN; - __spin_lock (&d->port.lock); - d->flags |= FD_CLOEXEC; - __spin_unlock (&d->port.lock); -+ HURD_CRITICAL_END; - - dirp->__fd = d; - dirp->__data = dirp->__ptr = NULL; reverted: --- eglibc-2.15/debian/patches/hurd-i386/unsubmitted-unlockpt-chroot.diff +++ eglibc-2.15.orig/debian/patches/hurd-i386/unsubmitted-unlockpt-chroot.diff @@ -1,19 +0,0 @@ -when e.g. using a chroot, the pty path is not so short. - -No topgit branch, TODO. - ---- - sysdeps/unix/bsd/unlockpt.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/sysdeps/unix/bsd/unlockpt.c -+++ b/sysdeps/unix/bsd/unlockpt.c -@@ -28,7 +28,7 @@ - int - unlockpt (int fd) - { -- char buf[sizeof (_PATH_TTY) + 2]; -+ char buf[1024]; /* XXX */ - - /* BSD doesn't have a lock, but it does have `revoke'. */ - if (__ptsname_r (fd, buf, sizeof (buf))) reverted: --- eglibc-2.15/debian/patches/hurd-i386/submitted-readlinkat.diff +++ eglibc-2.15.orig/debian/patches/hurd-i386/submitted-readlinkat.diff @@ -1,83 +0,0 @@ -http://cygwin.ru/ml/libc-alpha/2009-09/msg00058.html - -2009-09-27 Samuel Thibault - - * sysdeps/mach/hurd/readlinkat.c: New file, heavily inherited from - sysdeps/mach/hurd/readlink.c - -No topgit branch, TODO. - ---- - sysdeps/mach/hurd/readlinkat.c | 67 +++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 67 insertions(+) - ---- /dev/null -+++ b/sysdeps/mach/hurd/readlinkat.c -@@ -0,0 +1,67 @@ -+/* Copyright (C) 1991,92,93,94,95,97,2002,2009 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. */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* Read the contents of the symbolic link FILE_NAME relative to FD into no more -+ than LEN bytes of BUF. The contents are not null-terminated. -+ Returns the number of characters read, or -1 for errors. */ -+ssize_t -+readlinkat (fd, file_name, buf, len) -+ int fd; -+ const char *file_name; -+ char *buf; -+ size_t len; -+{ -+ error_t err; -+ file_t file; -+ struct stat64 st; -+ -+ file = __file_name_lookup_at (fd, 0, file_name, O_READ | O_NOLINK, 0); -+ if (file == MACH_PORT_NULL) -+ return -1; -+ -+ err = __io_stat (file, &st); -+ if (! err) -+ if (S_ISLNK (st.st_mode)) -+ { -+ char *rbuf = buf; -+ -+ err = __io_read (file, &rbuf, &len, 0, len); -+ if (!err && rbuf != buf) -+ { -+ memcpy (buf, rbuf, len); -+ __vm_deallocate (__mach_task_self (), (vm_address_t)rbuf, len); -+ } -+ } -+ else -+ err = EINVAL; -+ -+ __mach_port_deallocate (__mach_task_self (), file); -+ -+ if (err) -+ return __hurd_fail (err); -+ else -+ return len; -+} -+libc_hidden_def (readlinkat); reverted: --- eglibc-2.15/debian/patches/hurd-i386/unsubmitted-mlock.diff +++ eglibc-2.15.orig/debian/patches/hurd-i386/unsubmitted-mlock.diff @@ -1,24 +0,0 @@ -2006-01-18 Samuel Thibault - - Fix mlock() in all cases except non-readable pages. - - * glibc/sysdeps/mach/hurd/mlock.c (mlock): Give VM_PROT_READ - instead of VM_PROT_ALL as parameter to __vm_wire function. - -No topgit branch, TODO. - ---- - sysdeps/mach/hurd/mlock.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/sysdeps/mach/hurd/mlock.c -+++ b/sysdeps/mach/hurd/mlock.c -@@ -40,7 +40,7 @@ - page = trunc_page ((vm_address_t) addr); - len = round_page ((vm_address_t) addr + len) - page; - err = __vm_wire (hostpriv, __mach_task_self (), page, len, -- VM_PROT_ALL); /* XXX ? */ -+ VM_PROT_READ); - __mach_port_deallocate (__mach_task_self (), hostpriv); - - return err ? __hurd_fail (err) : 0; reverted: --- eglibc-2.15/debian/patches/hurd-i386/submitted-hurd-recvfrom.diff +++ eglibc-2.15.orig/debian/patches/hurd-i386/submitted-hurd-recvfrom.diff @@ -1,33 +0,0 @@ -http://cygwin.com/ml/libc-alpha/2011-11/msg00089.html - -hurd: recvfrom(): take into account null address ports - -Some kinds of sockets may return a null address port when calling the -`socket_recv' RPC, so avoid using it in case an address argument buffer is -asked to be filled. In such case, set the length of that address buffer to -zero. - -2011-11-26 Pino Toscano - - * sysdeps/mach/hurd/recvfrom.c (__recvfrom): Check also for a null - address port. Set `addr_len' to 0 when not filling `addrarg'. ---- a/sysdeps/mach/hurd/recvfrom.c -+++ b/sysdeps/mach/hurd/recvfrom.c -@@ -55,7 +55,7 @@ - return __hurd_sockfail (fd, flags, err); - - /* Get address data for the returned address port if requested. */ -- if (addr != NULL) -+ if (addr != NULL && addrport != MACH_PORT_NULL) - { - char *buf = (char *) addr; - mach_msg_type_number_t buflen = *addr_len; -@@ -89,6 +89,8 @@ - if (buflen > 0) - addr->sa_family = type; - } -+ else if (addr_len != NULL) -+ *addr_len = 0; - - __mach_port_deallocate (__mach_task_self (), addrport); - reverted: --- eglibc-2.15/debian/patches/hurd-i386/submitted-sbrk.diff +++ eglibc-2.15.orig/debian/patches/hurd-i386/submitted-sbrk.diff @@ -1,50 +0,0 @@ -http://sources.redhat.com/ml/libc-alpha/2009-09/msg00030.html - -2009-09-14 Samuel Thibault - - * sysdeps/mach/hurd/brk.c (_hurd_set_brk): When more space needs to be - allocated, call __vm_protect to finish enabling the existing space, and - pass a copy of _hurd_data_end instead of pagebrk to __vm_allocate to - allocate the remainder. - -No topgit branch, TODO. - ---- - sysdeps/mach/hurd/brk.c | 18 ++++++++++++++++-- - 1 file changed, 16 insertions(+), 2 deletions(-) - ---- a/sysdeps/mach/hurd/brk.c -+++ b/sysdeps/mach/hurd/brk.c -@@ -64,7 +64,7 @@ - int - _hurd_set_brk (vm_address_t addr) - { -- error_t err; -+ error_t err = 0; - vm_address_t pagend = round_page (addr); - vm_address_t pagebrk = round_page (_hurd_brk); - long int rlimit; -@@ -101,8 +101,22 @@ - - if (pagend > _hurd_data_end) - { -+ vm_address_t alloc_start = _hurd_data_end; -+ - /* We didn't allocate enough space! Hopefully we can get some more! */ -- err = __vm_allocate (__mach_task_self (), &pagebrk, pagend - pagebrk, 0); -+ -+ if (_hurd_data_end > pagebrk) -+ /* First finish allocation */ -+ err = __vm_protect (__mach_task_self (), pagebrk, -+ alloc_start - pagebrk, 0, -+ VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); -+ if (! err) -+ _hurd_brk = alloc_start; -+ -+ if (! err) -+ err = __vm_allocate (__mach_task_self (), &alloc_start, -+ pagend - alloc_start, 0); -+ - if (! err) - _hurd_data_end = pagend; - } reverted: --- eglibc-2.15/debian/patches/hurd-i386/unsubmitted-unwind-resume.diff +++ eglibc-2.15.orig/debian/patches/hurd-i386/unsubmitted-unwind-resume.diff @@ -1,100 +0,0 @@ -Unwind resume support - -No topgit branch, TODO. - ---- - sysdeps/mach/hurd/Makefile | 12 ++++++ - sysdeps/mach/hurd/rt-unwind-resume.c | 1 - sysdeps/mach/hurd/unwind-resume.c | 64 +++++++++++++++++++++++++++++++++++ - 3 files changed, 77 insertions(+) - ---- /dev/null -+++ b/sysdeps/mach/hurd/rt-unwind-resume.c -@@ -0,0 +1 @@ -+#include ---- /dev/null -+++ b/sysdeps/mach/hurd/unwind-resume.c -@@ -0,0 +1,64 @@ -+/* Copyright (C) 2003 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Jakub Jelinek . -+ -+ 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; see the file COPYING.LIB. If not, -+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -+ Boston, MA 02111-1307, USA. */ -+ -+#include -+#include -+#include -+ -+static void (*libgcc_s_resume) (struct _Unwind_Exception *exc); -+static _Unwind_Reason_Code (*libgcc_s_personality) -+ (int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *, -+ struct _Unwind_Context *); -+ -+static void -+init (void) -+{ -+ void *resume, *personality; -+ void *handle; -+ -+ handle = __libc_dlopen ("libgcc_s.so.1"); -+ -+ if (handle == NULL -+ || (resume = __libc_dlsym (handle, "_Unwind_Resume")) == NULL -+ || (personality = __libc_dlsym (handle, "__gcc_personality_v0")) == NULL) -+ __libc_fatal ("libgcc_s.so.1 must be installed for pthread_cancel to work\n"); -+ -+ libgcc_s_resume = resume; -+ libgcc_s_personality = personality; -+} -+ -+void -+_Unwind_Resume (struct _Unwind_Exception *exc) -+{ -+ if (__builtin_expect (libgcc_s_resume == NULL, 0)) -+ init (); -+ libgcc_s_resume (exc); -+} -+ -+_Unwind_Reason_Code -+__gcc_personality_v0 (int version, _Unwind_Action actions, -+ _Unwind_Exception_Class exception_class, -+ struct _Unwind_Exception *ue_header, -+ struct _Unwind_Context *context) -+{ -+ if (__builtin_expect (libgcc_s_personality == NULL, 0)) -+ init (); -+ return libgcc_s_personality (version, actions, exception_class, -+ ue_header, context); -+} ---- a/sysdeps/mach/hurd/Makefile -+++ b/sysdeps/mach/hurd/Makefile -@@ -211,4 +211,16 @@ - net/route.h - endif - -+ifeq ($(subdir),csu) -+routines += unwind-resume -+shared-only-routines += unwind-resume -+CFLAGS-unwind-resume.c += -fexceptions -fasynchronous-unwind-tables -+endif -+ -+ifeq ($(subdir),rt) -+librt-sysdep_routines += rt-unwind-resume -+librt-shared-only-routines += rt-unwind-resume -+CFLAGS-rt-unwind-resume.c += -fexceptions -fasynchronous-unwind-tables -+endif -+ - endif # in-Makerules reverted: --- eglibc-2.15/debian/patches/hurd-i386/submitted-posix2008.diff +++ eglibc-2.15.orig/debian/patches/hurd-i386/submitted-posix2008.diff @@ -1,63 +0,0 @@ -http://cygwin.com/ml/libc-alpha/2011-12/msg00005.html - -2011-12-04 Samuel Thibault - -* bits/sigaction.h [__USE_XOPEN2K8]: Define SA_RESTART, SA_NODEFER, -SA_RESETHAND. -* sysdeps/mach/hurd/bits/fcntl.h [__USE_XOPEN2K8]: Define O_NOFOLLOW, -O_DIRECTORY, O_CLOEXEC, F_GETOWN, F_SETOWN, F_DUPFD_CLOEXEC. - -diff --git a/bits/sigaction.h b/bits/sigaction.h -index adcc276..97242a6 100644 ---- a/bits/sigaction.h -+++ b/bits/sigaction.h -@@ -55,6 +55,8 @@ struct sigaction - /* 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. */ -diff --git a/sysdeps/mach/hurd/bits/fcntl.h b/sysdeps/mach/hurd/bits/fcntl.h -index b4147ce..74cf913 100644 ---- a/sysdeps/mach/hurd/bits/fcntl.h -+++ b/sysdeps/mach/hurd/bits/fcntl.h -@@ -55,7 +55,9 @@ - #ifdef __USE_GNU - # define O_NOLINK 0x0040 /* No name mappings on final component. */ - # define O_NOTRANS 0x0080 /* No translator on final component. */ -+#endif - -+#ifdef __USE_XOPEN2K8 - # define O_NOFOLLOW 0x00100000 /* Produce ENOENT if file is a symlink. */ - # define O_DIRECTORY 0x00200000 /* Produce ENOTDIR if not a directory. */ - #endif -@@ -119,7 +121,7 @@ - once the file has been opened. */ - - #define O_TRUNC 0x00010000 /* Truncate file to zero length. */ --#ifdef __USE_GNU -+#ifdef __USE_XOPEN2K8 - # define O_CLOEXEC 0x00400000 /* Set FD_CLOEXEC. */ - #endif - -@@ -159,7 +161,7 @@ - #define F_SETFD 2 /* Set file descriptor flags. */ - #define F_GETFL 3 /* Get file status flags. */ - #define F_SETFL 4 /* Set file status flags. */ --#if defined __USE_BSD || defined __USE_UNIX98 -+#if defined __USE_BSD || defined __USE_UNIX98 || defined __USE_XOPEN2K8 - # define F_GETOWN 5 /* Get owner (receiver of SIGIO). */ - # define F_SETOWN 6 /* Set owner (receiver of SIGIO). */ - #endif -@@ -167,7 +169,7 @@ - #define F_SETLK 8 /* Set record locking info (non-blocking). */ - #define F_SETLKW 9 /* Set record locking info (blocking). */ - --#ifdef __USE_GNU -+#ifdef __USE_XOPEN2K8 - # define F_DUPFD_CLOEXEC 1030 /* Duplicate, set FD_CLOEXEC on new one. */ - #endif - reverted: --- eglibc-2.15/debian/patches/hurd-i386/unsubmitted-no-hp-timing.diff +++ eglibc-2.15.orig/debian/patches/hurd-i386/unsubmitted-no-hp-timing.diff @@ -1,56 +0,0 @@ -2010-08-21 Samuel Thibault - -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 , 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 */ reverted: --- eglibc-2.15/debian/patches/hurd-i386/unsubmitted-locarchive.diff +++ eglibc-2.15.orig/debian/patches/hurd-i386/unsubmitted-locarchive.diff @@ -1,45 +0,0 @@ -Dirty hack to fix installation of locales-all: instead of just locking the -archive extension (which is not supported on hurd-i386), lock it all. - -No topgit branch, TODO. - ---- - locale/programs/locarchive.c | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - ---- a/locale/programs/locarchive.c -+++ b/locale/programs/locarchive.c -@@ -416,7 +416,16 @@ - } - - /* Lock the new file. */ -+#ifdef __GNU__ -+ struct flock fl; -+ fl.l_whence = SEEK_SET; -+ fl.l_start = 0; -+ fl.l_len = 0; -+ fl.l_type = F_WRLCK; -+ if (fcntl(fd, F_SETLKW, &fl) != 0) -+#else - if (lockf64 (fd, F_LOCK, total) != 0) -+#endif - { - int errval = errno; - unlink (fname); -@@ -564,7 +573,16 @@ - error (EXIT_FAILURE, errno, _("cannot stat locale archive \"%s\""), - archivefname); - -+#ifdef __GNU__ -+ struct flock fl; -+ fl.l_whence = SEEK_SET; -+ fl.l_start = 0; -+ fl.l_len = 0; -+ fl.l_type = F_WRLCK; -+ if (!readonly && fcntl(fd, F_SETLKW, &fl) == -1) -+#else - if (!readonly && lockf64 (fd, F_LOCK, sizeof (struct locarhead)) == -1) -+#endif - { - close (fd); - reverted: --- eglibc-2.15/debian/patches/hurd-i386/submitted-hurdsig-global-dispositions.diff +++ eglibc-2.15.orig/debian/patches/hurd-i386/submitted-hurdsig-global-dispositions.diff @@ -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_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 . -@@ -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 - --/* 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) reverted: --- eglibc-2.15/debian/patches/hurd-i386/submitted-posix_opt.h.diff +++ eglibc-2.15.orig/debian/patches/hurd-i386/submitted-posix_opt.h.diff @@ -1,124 +0,0 @@ -http://cygwin.ru/ml/libc-alpha/2010-01/msg00012.html - -2010-01-10 Samuel Thibault - - * posix/tst-sysconf.c (posix_options): Only use - _POSIX_PRIORITIZED_IO, _POSIX_PRIORITY_SCHEDULING, and - _POSIX_SYNCHRONIZED_IO when they are defined - * sysdeps/mach/hurd/bits/posix_opt.h: - (_POSIX_PRIORITY_SCHEDULING): Undefine macro. - (_XOPEN_REALTIME): Undefine macro. - (_XOPEN_REALTIME_THREADS): Undefine macro. - (_XOPEN_SHM): Undefine macro. - [__USE_XOPEN2K8] (_POSIX_THREAD_ROBUST_PRIO_INHERIT): Define - macro to -1. - [__USE_XOPEN2K8] (_POSIX_THREAD_ROBUST_PRIO_PROTECT): Define - macro to -1. - (_POSIX_ASYNC_IO): Undefine macro. - (_POSIX_PRIORITIZED_IO): Undefine macro. - (_POSIX_SPIN_LOCKS): Define macro to -1. - -No topgit branch, TODO. - ---- - posix/tst-sysconf.c | 6 ++++++ - sysdeps/mach/hurd/bits/posix_opt.h | 28 +++++++++++++++++++++++----- - 2 files changed, 29 insertions(+), 5 deletions(-) - ---- a/posix/tst-sysconf.c -+++ b/posix/tst-sysconf.c -@@ -29,8 +29,12 @@ - N (MEMORY_PROTECTION), - N (MESSAGE_PASSING), - N (MONOTONIC_CLOCK), -+#ifdef _POSIX_PRIORITIZED_IO - N (PRIORITIZED_IO), -+#endif -+#ifdef _POSIX_PRIORITY_SCHEDULING - N (PRIORITY_SCHEDULING), -+#endif - N (RAW_SOCKETS), - N (READER_WRITER_LOCKS), - N (REALTIME_SIGNALS), -@@ -42,7 +46,9 @@ - N (SPAWN), - N (SPIN_LOCKS), - N (SPORADIC_SERVER), -+#ifdef _POSIX_SYNCHRONIZED_IO - N (SYNCHRONIZED_IO), -+#endif - N (THREAD_ATTR_STACKADDR), - N (THREAD_ATTR_STACKSIZE), - N (THREAD_CPUTIME), ---- a/sysdeps/mach/hurd/bits/posix_opt.h -+++ b/sysdeps/mach/hurd/bits/posix_opt.h -@@ -31,6 +31,9 @@ - /* Processes have a saved set-user-ID and a saved set-group-ID. */ - #define _POSIX_SAVED_IDS 1 - -+/* Priority scheduling is not supported. */ -+#undef _POSIX_PRIORITY_SCHEDULING -+ - /* Synchronizing file data is supported, but msync is missing. */ - #undef _POSIX_SYNCHRONIZED_IO - -@@ -60,6 +63,14 @@ - #undef _POSIX_NO_TRUNC /* Overlong file names get error? */ - #undef _POSIX_SYNC_IO /* File supports O_SYNC et al? */ - -+/* X/Open realtime support is not supported. */ -+#undef _XOPEN_REALTIME -+ -+/* X/Open thread realtime support is not supported. */ -+#undef _XOPEN_REALTIME_THREADS -+ -+/* XPG4.2 shared memory is not supported. */ -+#undef _XOPEN_SHM - - /* We do not have the POSIX threads interface. */ - #define _POSIX_THREADS -1 -@@ -72,6 +83,12 @@ - #define _POSIX_THREAD_PRIORITY_SCHEDULING -1 - #define _POSIX_THREAD_ATTR_STACKSIZE -1 - #define _POSIX_THREAD_ATTR_STACKADDR -1 -+#define _POSIX_THREAD_PRIO_INHERIT -1 -+#define _POSIX_THREAD_PRIO_PROTECT -1 -+#ifdef __USE_XOPEN2K8 -+# define _POSIX_THREAD_ROBUST_PRIO_INHERIT -1 -+# define _POSIX_THREAD_ROBUST_PRIO_PROTECT -1 -+#endif - #define _POSIX_SEMAPHORES -1 - - /* Real-time signals are not yet supported. */ -@@ -79,8 +96,11 @@ - - /* Asynchronous I/O might supported with the existing ABI. */ - #define _POSIX_ASYNCHRONOUS_IO 0 -+#undef _POSIX_ASYNC_IO - /* Alternative name for Unix98. */ - #define _LFS_ASYNCHRONOUS_IO _POSIX_ASYNCHRONOUS_IO -+/* Support for prioritization is not available. */ -+#undef _POSIX_PRIORITIZED_IO - - /* The LFS support in asynchronous I/O is also available. */ - #define _LFS64_ASYNCHRONOUS_IO _POSIX_ASYNCHRONOUS_IO -@@ -111,6 +131,9 @@ - /* We cannot support the Timeouts option without _POSIX_THREADS. */ - #define _POSIX_TIMEOUTS -1 - -+/* We do not support spinlocks. */ -+#define _POSIX_SPIN_LOCKS -1 -+ - /* The `spawn' function family is supported. */ - #define _POSIX_SPAWN 200809L - -@@ -157,9 +180,4 @@ - /* Typed memory objects are not available. */ - #define _POSIX_TYPED_MEMORY_OBJECTS -1 - --/* No support for priority inheritance or protection so far. */ --#define _POSIX_THREAD_PRIO_INHERIT -1 --#define _POSIX_THREAD_PRIO_PROTECT -1 -- -- - #endif /* bits/posix_opt.h */ diff -u eglibc-2.15/debian/patches/kfreebsd/local-sysdeps.diff eglibc-2.15/debian/patches/kfreebsd/local-sysdeps.diff --- eglibc-2.15/debian/patches/kfreebsd/local-sysdeps.diff +++ eglibc-2.15/debian/patches/kfreebsd/local-sysdeps.diff @@ -3110,7 +3110,7 @@ +#endif /* ! _SIGSET_H_fns. */ --- /dev/null +++ b/ports/sysdeps/unix/bsd/bsd4.4/kfreebsd/bits/socket.h -@@ -0,0 +1,388 @@ +@@ -0,0 +1,397 @@ +/* System-specific socket constants and types. FreeBSD version. + Copyright (C) 1991-1992,1994-1999,2000-2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. @@ -3169,6 +3169,15 @@ +#define SOCK_SEQPACKET SOCK_SEQPACKET +}; + ++/* ++ * Structure used by kernel to pass protocol ++ * information in raw sockets. ++ */ ++struct sockproto { ++ unsigned short sp_family; /* address family */ ++ unsigned short sp_protocol; /* protocol */ ++}; ++ +/* Protocol families. */ +#define PF_UNSPEC 0 /* Unspecified. */ +#define PF_LOCAL 1 /* Local to host (pipes and file-domain). */ @@ -21184,7 +21193,7 @@ + + if (sysctlbyname("vfs.conflist", NULL, &buflen, NULL, 0) < 0) + return (-1); -+ xvfsp = malloc(buflen); ++ xvfsp = (struct xvfsconf *) malloc(buflen); + if (xvfsp == NULL) + return (-1); + if (sysctlbyname("vfs.conflist", xvfsp, &buflen, NULL, 0) < 0) { diff -u eglibc-2.15/debian/patches/localedata/first_weekday.diff eglibc-2.15/debian/patches/localedata/first_weekday.diff --- eglibc-2.15/debian/patches/localedata/first_weekday.diff +++ eglibc-2.15/debian/patches/localedata/first_weekday.diff @@ -652,7 +652,7 @@ / " +% FIXME: found in CLDR -+first_weekday 2 ++first_weekday 1 END LC_TIME LC_PAPER only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/mips/cvs-dlopen-lazy.diff +++ eglibc-2.15/debian/patches/mips/cvs-dlopen-lazy.diff @@ -0,0 +1,61 @@ +2012-02-15 Viju Vincent + + * ports/sysdeps/mips/dl-trampoline.c (__dl_runtime_resolve): Use locking + around calls to _dl_lookup_symbol_x. + +--- a/ports/sysdeps/mips/dl-trampoline.c ++++ b/ports/sysdeps/mips/dl-trampoline.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + + /* Get link map for callers object containing STUB_PC. */ + static inline struct link_map * +@@ -153,17 +154,44 @@ __dl_runtime_resolve (ElfW(Word) sym_index, + + if (version->hash != 0) + { ++ /* We need to keep the scope around so do some locking. This is ++ not necessary for objects which cannot be unloaded or when ++ we are not using any threads (yet). */ ++ if (!RTLD_SINGLE_THREAD_P) ++ THREAD_GSCOPE_SET_FLAG (); ++ + sym_map = _dl_lookup_symbol_x (strtab + sym->st_name, l, + &sym, l->l_scope, version, + ELF_RTYPE_CLASS_PLT, 0, 0); ++ ++ /* We are done with the global scope. */ ++ if (!RTLD_SINGLE_THREAD_P) ++ THREAD_GSCOPE_RESET_FLAG (); ++ + break; + } + /* Fall through. */ + } + case 0: ++ { ++ /* We need to keep the scope around so do some locking. This is ++ not necessary for objects which cannot be unloaded or when ++ we are not using any threads (yet). */ ++ int flags = DL_LOOKUP_ADD_DEPENDENCY; ++ if (!RTLD_SINGLE_THREAD_P) ++ { ++ THREAD_GSCOPE_SET_FLAG (); ++ flags |= DL_LOOKUP_GSCOPE_LOCK; ++ } ++ + sym_map = _dl_lookup_symbol_x (strtab + sym->st_name, l, &sym, + l->l_scope, 0, ELF_RTYPE_CLASS_PLT, +- DL_LOOKUP_ADD_DEPENDENCY, 0); ++ flags, 0); ++ ++ /* We are done with the global scope. */ ++ if (!RTLD_SINGLE_THREAD_P) ++ THREAD_GSCOPE_RESET_FLAG (); ++ } + } + + /* Currently value contains the base load address of the object only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/hurd-i386/tg-catch-signal.diff +++ eglibc-2.15/debian/patches/hurd-i386/tg-catch-signal.diff @@ -0,0 +1,56 @@ +From: Samuel Thibault +Subject: [PATCH] Fix signal-catching functions. + +2010-09-13 Samuel Thibault + + Fix signal-catching functions. + + We need to restore the signal mask, because else the signal handling + code will have blocked the catched signal and for instance calling + hurd_catch_signal again would then dump core. There was also a trivial + inverted logic. + + * hurd/catch-signal.c (hurd_catch_signal): Use sigsetjmp/siglongjmp + instead of setjmp/longjmp to restore the signal mask. Call sigsetjmp + when handler == SIG_ERR, not when handler != SIG_ERR. + +--- + +http://sourceware.org/ml/libc-alpha/2010-09/msg00015.html + + hurd/catch-signal.c | 8 ++++---- + 1 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/hurd/catch-signal.c b/hurd/catch-signal.c +index 583f99e..42f490e 100644 +--- a/hurd/catch-signal.c ++++ b/hurd/catch-signal.c +@@ -28,9 +28,9 @@ hurd_catch_signal (sigset_t sigset, + error_t (*operate) (struct hurd_signal_preemptor *), + sighandler_t handler) + { +- jmp_buf buf; ++ sigjmp_buf buf; + void throw (int signo, long int sigcode, struct sigcontext *scp) +- { longjmp (buf, scp->sc_error ?: EGRATUITOUS); } ++ { siglongjmp (buf, scp->sc_error ?: EGRATUITOUS); } + + struct hurd_signal_preemptor preemptor = + { +@@ -41,12 +41,12 @@ hurd_catch_signal (sigset_t sigset, + struct hurd_sigstate *const ss = _hurd_self_sigstate (); + error_t error; + +- if (handler == SIG_ERR) ++ if (handler != SIG_ERR) + /* Not our handler; don't bother saving state. */ + error = 0; + else + /* This returns again with nonzero value when we preempt a signal. */ +- error = setjmp (buf); ++ error = sigsetjmp (buf, 1); + + if (error == 0) + { +-- +tg: (0234227..) t/catch-signal (depends on: baseline) only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/hurd-i386/tg-SOL_IP.diff +++ eglibc-2.15/debian/patches/hurd-i386/tg-SOL_IP.diff @@ -0,0 +1,41 @@ +From: Samuel Thibault +Subject: [PATCH] Add SOL_IP, SOL_IPV6, SOL_ICMPV6 + +The patch below defines the SOL_IP, SOL_IPV6 and SOL_ICMPV6 macros for +socket options. + +2009-09-28 Samuel Thibault + + * bits/in.h (SOL_IP, SOL_IPV6, SOL_ICMPV6): New macros. + +--- + bits/in.h | 7 +++++++ + 1 files changed, 7 insertions(+), 0 deletions(-) + +diff --git a/bits/in.h b/bits/in.h +index 4687a29..4b22e92 100644 +--- a/bits/in.h ++++ b/bits/in.h +@@ -22,6 +22,9 @@ + # error "Never use directly; include instead." + #endif + ++/* To select the IP level. */ ++#define SOL_IP 0 ++ + /* Options for use with `getsockopt' and `setsockopt' at the IP level. + The first word in the comment at the right is the data type used; + "bool" means a boolean value stored in an `int'. */ +@@ -48,6 +51,10 @@ struct ip_opts + char ip_opts[40]; /* Actually variable in size. */ + }; + ++/* Socket level values for IPv6. */ ++#define SOL_IPV6 41 ++#define SOL_ICMPV6 58 ++ + /* IPV6 socket options. */ + #define IPV6_ADDRFORM 1 + #define IPV6_PKTINFO 2 +-- +tg: (0234227..) t/SOL_IP (depends on: baseline) only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/hurd-i386/tg-pthread_types.diff +++ eglibc-2.15/debian/patches/hurd-i386/tg-pthread_types.diff @@ -0,0 +1,16 @@ +From: Samuel Thibault +Subject: [PATCH] We do have pthread types. + +--- + sysdeps/mach/hurd/bits/pthreadtypes.h | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) + +diff --git a/sysdeps/mach/hurd/bits/pthreadtypes.h b/sysdeps/mach/hurd/bits/pthreadtypes.h +new file mode 100644 +index 0000000..741f3eb +--- /dev/null ++++ b/sysdeps/mach/hurd/bits/pthreadtypes.h +@@ -0,0 +1 @@ ++#include +-- +tg: (0234227..) t/pthread_types (depends on: baseline) only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/hurd-i386/tg-null-pathname.diff +++ eglibc-2.15/debian/patches/hurd-i386/tg-null-pathname.diff @@ -0,0 +1,56 @@ +From: Samuel Thibault +Subject: [PATCH] null pathnames shall return ENOENT + +Here is a patch to fix chdir("") and chroot("") into returning ENOENT as +required by POSIX. + +2009-09-13 Samuel Thibault + + * hurd/hurdchdir.c (_hurd_change_directory_port_from_name): + Return ENOENT when name is empty. + * sysdeps/mach/hurd/chroot.c (chroot): Return ENOENT when path + is empty. + +--- +http://sources.redhat.com/ml/libc-alpha/2009-09/msg00025.html + + hurd/hurdchdir.c | 6 ++++++ + sysdeps/mach/hurd/chroot.c | 6 ++++++ + 2 files changed, 12 insertions(+), 0 deletions(-) + +diff --git a/hurd/hurdchdir.c b/hurd/hurdchdir.c +index 5115e4d..b1cc7a5 100644 +--- a/hurd/hurdchdir.c ++++ b/hurd/hurdchdir.c +@@ -38,6 +38,12 @@ _hurd_change_directory_port_from_name (struct hurd_port *portcell, + len = strlen (name); + if (len >= 2 && name[len - 2] == '/' && name[len - 1] == '.') + lookup = name; ++ else if (len == 0) ++ { ++ /* Special-case null pathname according to POSIX */ ++ errno = ENOENT; ++ return -1; ++ } + else + { + char *n = alloca (len + 3); +diff --git a/sysdeps/mach/hurd/chroot.c b/sysdeps/mach/hurd/chroot.c +index fde0164..cabeb7d 100644 +--- a/sysdeps/mach/hurd/chroot.c ++++ b/sysdeps/mach/hurd/chroot.c +@@ -38,6 +38,12 @@ chroot (const char *path) + len = strlen (path); + if (len >= 2 && path[len - 2] == '/' && path[len - 1] == '.') + lookup = path; ++ else if (len == 0) ++ { ++ /* Special-case null pathname according to POSIX */ ++ errno = ENOENT; ++ return -1; ++ } + else + { + char *n = alloca (len + 3); +-- +tg: (0234227..) t/null-pathname (depends on: baseline) only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/hurd-i386/tg-libc_stack_end.diff +++ eglibc-2.15/debian/patches/hurd-i386/tg-libc_stack_end.diff @@ -0,0 +1,70 @@ +From: Samuel Thibault +Subject: [PATCH] Fix value of __libc_stack_end + +When using some libthread, we need to update the value of __libc_stack_end +to what the libthread allocated. This requires making __libc_stack_end +non-relro to be able to modify it. + +2011-08-24 Samuel Thibault + +* sysdeps/generic/ldsodefs.h [LIBC_STACK_END_NOT_RELRO] (__libc_stack_end): Do +not use attribute_relro. +* sysdeps/mach/hurd/dl-sysdep.h (LIBC_STACK_END_NOT_RELRO): Define. +* sysdeps/mach/hurd/i386/init-first.c (init): Update __libc_stack_end to +libthread-provided value. +* sysdeps/mach/hurd/dl-sysdep.c (__libc_stack_end): Do not use attribute_relro. + +--- +http://www.cygwin.com/ml/libc-alpha/2011-08/msg00124.html + + sysdeps/generic/ldsodefs.h | 6 +++++- + sysdeps/mach/hurd/dl-sysdep.h | 3 ++- + sysdeps/mach/hurd/i386/init-first.c | 2 ++ + 3 files changed, 9 insertions(+), 2 deletions(-) + +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index b24bff3..804d9ee 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -724,7 +724,11 @@ rtld_hidden_proto (_dl_make_stack_executable) + might use the variable which results in copy relocations on some + platforms. But this does not matter, ld.so can always use the local + copy. */ +-extern void *__libc_stack_end attribute_relro; ++extern void *__libc_stack_end ++#ifndef LIBC_STACK_END_NOT_RELRO ++ attribute_relro ++#endif ++ ; + rtld_hidden_proto (__libc_stack_end) + + /* Parameters passed to the dynamic linker. */ +diff --git a/sysdeps/mach/hurd/dl-sysdep.h b/sysdeps/mach/hurd/dl-sysdep.h +index 4b21b77..5b86fec 100644 +--- a/sysdeps/mach/hurd/dl-sysdep.h ++++ b/sysdeps/mach/hurd/dl-sysdep.h +@@ -25,7 +25,8 @@ + #define RTLD_PRIVATE_ERRNO 0 + + #ifdef SHARED +-/* _dl_argv cannot be attribute_relro, because the stack-switching ++/* _dl_argv and __libc_stack_end cannot be attribute_relro, because the stack-switching + libc initializer for using cthreads might write into it. */ + # define DL_ARGV_NOT_RELRO 1 ++# define LIBC_STACK_END_NOT_RELRO 1 + #endif +diff --git a/sysdeps/mach/hurd/i386/init-first.c b/sysdeps/mach/hurd/i386/init-first.c +index 60823bd..9e5b723 100644 +--- a/sysdeps/mach/hurd/i386/init-first.c ++++ b/sysdeps/mach/hurd/i386/init-first.c +@@ -212,6 +212,8 @@ init (int *data) + + void switch_stacks (void); + ++ __libc_stack_end = newsp; ++ + /* Copy per-thread variables from that temporary + area onto the new cthread stack. */ + memcpy (__hurd_threadvar_location_from_sp (0, newsp), +-- +tg: (0234227..) t/libc_stack_end (depends on: baseline) only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/hurd-i386/tg-sendmsg-SCM_RIGHTS.diff +++ eglibc-2.15/debian/patches/hurd-i386/tg-sendmsg-SCM_RIGHTS.diff @@ -0,0 +1,278 @@ +From 1b911148009f696717da0b676d6d10af85d5aefb Mon Sep 17 00:00:00 2001 +From: Emilio Pozuelo Monfort +Date: Sat, 17 Jul 2010 22:09:13 +0200 +Subject: [PATCH] Add support to send file descriptors over Unix sockets + +--- + sysdeps/mach/hurd/recvmsg.c | 105 +++++++++++++++++++++++++++++++++++++++++- + sysdeps/mach/hurd/sendmsg.c | 73 +++++++++++++++++++++++++----- + 2 files changed, 163 insertions(+), 15 deletions(-) + +diff --git a/sysdeps/mach/hurd/recvmsg.c b/sysdeps/mach/hurd/recvmsg.c +index 33897b8..ee7d8bb 100644 +--- a/sysdeps/mach/hurd/recvmsg.c ++++ b/sysdeps/mach/hurd/recvmsg.c +@@ -1,4 +1,4 @@ +-/* Copyright (C) 2001, 2002 Free Software Foundation, Inc. ++/* Copyright (C) 2001, 2002, 2010 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 +@@ -33,13 +33,33 @@ __libc_recvmsg (int fd, struct msghdr *message, int flags) + addr_port_t aport; + char *data = NULL; + mach_msg_type_number_t len = 0; +- mach_port_t *ports; ++ mach_port_t *ports, *newports; + mach_msg_type_number_t nports = 0; ++ struct cmsghdr *cmsg; + char *cdata = NULL; + mach_msg_type_number_t clen = 0; + size_t amount; + char *buf; +- int i; ++ int nfds, *fds; ++ int i, j; ++ ++ error_t reauthenticate (mach_port_t port, mach_port_t *result) ++ { ++ error_t err; ++ mach_port_t ref; ++ ref = __mach_reply_port (); ++ do ++ err = __io_reauthenticate (port, ref, MACH_MSG_TYPE_MAKE_SEND); ++ while (err == EINTR); ++ if (!err) ++ do ++ err = __USEPORT (AUTH, __auth_user_authenticate (port, ++ ref, MACH_MSG_TYPE_MAKE_SEND, ++ result)); ++ while (err == EINTR); ++ __mach_port_destroy (__mach_task_self (), ref); ++ return err; ++ } + + /* Find the total number of bytes to be read. */ + amount = 0; +@@ -136,6 +156,85 @@ __libc_recvmsg (int fd, struct msghdr *message, int flags) + message->msg_controllen = clen; + memcpy (message->msg_control, cdata, message->msg_controllen); + ++ /* SCM_RIGHTS ports. */ ++ if (nports > 0) ++ { ++ newports = __alloca (nports * sizeof (mach_port_t)); ++ ++ /* Reauthenticate all ports here. */ ++ for (i = 0; i < nports; i++) ++ { ++ err = reauthenticate (ports[i], &newports[i]); ++ __mach_port_deallocate (__mach_task_self (), ports[i]); ++ if (err) ++ { ++ for (j = 0; j < i; j++) ++ __mach_port_deallocate (__mach_task_self (), newports[j]); ++ for (j = i+1; j < nports; j++) ++ __mach_port_deallocate (__mach_task_self (), ports[j]); ++ ++ __vm_deallocate (__mach_task_self (), (vm_address_t) cdata, clen); ++ __hurd_fail (err); ++ } ++ } ++ ++ j = 0; ++ for (cmsg = CMSG_FIRSTHDR (message); ++ cmsg; ++ cmsg = CMSG_NXTHDR (message, cmsg)) ++ { ++ if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) ++ { ++ fds = (int *) CMSG_DATA (cmsg); ++ nfds = (cmsg->cmsg_len - CMSG_ALIGN (sizeof (struct cmsghdr))) ++ / sizeof (int); ++ ++ for (i = 0; i < nfds && j < nports; i++) ++ { ++ /* The fd's flags are passed in the control data. */ ++ fds[i] = _hurd_intern_fd (newports[j++], fds[i], 0); ++ if (fds[i] == -1) ++ { ++ err = errno; ++ goto cleanup; ++ } ++ } ++ } ++ } ++ ++ if (j != nports) ++ err = EGRATUITOUS; ++ ++ if (err) ++ cleanup: ++ { ++ /* Clean up all the file descriptors. */ ++ nports = j; ++ j = 0; ++ for (cmsg = CMSG_FIRSTHDR (message); ++ cmsg; ++ cmsg = CMSG_NXTHDR (message, cmsg)) ++ { ++ if (cmsg->cmsg_level == SOL_SOCKET ++ && cmsg->cmsg_type == SCM_RIGHTS) ++ { ++ fds = (int *) CMSG_DATA (cmsg); ++ nfds = (cmsg->cmsg_len ++ - CMSG_ALIGN (sizeof (struct cmsghdr))) ++ / sizeof (int); ++ for (i = 0; i < nfds && j < nports; i++, j++) ++ _hurd_fd_close (_hurd_fd_get (fds[i])); ++ } ++ } ++ ++ for (; j < nports; j++) ++ __mach_port_deallocate (__mach_task_self (), newports[j]); ++ ++ __vm_deallocate (__mach_task_self (), (vm_address_t) cdata, clen); ++ __hurd_fail (err); ++ } ++ } ++ + __vm_deallocate (__mach_task_self (), (vm_address_t) cdata, clen); + + return (buf - data); +diff --git a/sysdeps/mach/hurd/sendmsg.c b/sysdeps/mach/hurd/sendmsg.c +index 118fd59..fb8dd2d 100644 +--- a/sysdeps/mach/hurd/sendmsg.c ++++ b/sysdeps/mach/hurd/sendmsg.c +@@ -1,4 +1,4 @@ +-/* Copyright (C) 2001,2002,2004 Free Software Foundation, Inc. ++/* Copyright (C) 2001,2002,2004,2010 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 +@@ -32,6 +32,10 @@ ssize_t + __libc_sendmsg (int fd, const struct msghdr *message, int flags) + { + error_t err = 0; ++ struct cmsghdr *cmsg; ++ mach_port_t *ports = NULL; ++ mach_msg_type_number_t nports = 0; ++ int *fds, nfds; + struct sockaddr_un *addr = message->msg_name; + socklen_t addr_len = message->msg_namelen; + addr_port_t aport = MACH_PORT_NULL; +@@ -44,6 +48,7 @@ __libc_sendmsg (int fd, const struct msghdr *message, int flags) + mach_msg_type_number_t len; + mach_msg_type_number_t amount; + int dealloc = 0; ++ int socketrpc = 0; + int i; + + /* Find the total number of bytes to be written. */ +@@ -101,6 +106,46 @@ __libc_sendmsg (int fd, const struct msghdr *message, int flags) + } + } + ++ /* SCM_RIGHTS support: get the number of fds to send. */ ++ cmsg = CMSG_FIRSTHDR (message); ++ for (; cmsg; cmsg = CMSG_NXTHDR (message, cmsg)) ++ if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) ++ nports += (cmsg->cmsg_len - CMSG_ALIGN (sizeof (struct cmsghdr))) ++ / sizeof (int); ++ ++ if (nports) ++ ports = __alloca (nports * sizeof (mach_port_t)); ++ ++ nports = 0; ++ for (cmsg = CMSG_FIRSTHDR (message); ++ cmsg; ++ cmsg = CMSG_NXTHDR (message, cmsg)) ++ { ++ if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) ++ { ++ fds = (int *) CMSG_DATA (cmsg); ++ nfds = (cmsg->cmsg_len - CMSG_ALIGN (sizeof (struct cmsghdr))) ++ / sizeof (int); ++ ++ for (i = 0; i < nfds; i++) ++ { ++ err = HURD_DPORT_USE ++ (fds[i], ++ ({ ++ err = __io_restrict_auth (port, &ports[nports], ++ 0, 0, 0, 0); ++ if (! err) ++ nports++; ++ /* We pass the flags in the control data. */ ++ fds[i] = descriptor->flags; ++ })); ++ ++ if (err) ++ goto out; ++ } ++ } ++ } ++ + if (addr) + { + if (addr->sun_family == AF_LOCAL) +@@ -110,9 +155,8 @@ __libc_sendmsg (int fd, const struct msghdr *message, int flags) + file_t file = __file_name_lookup (addr->sun_path, 0, 0); + if (file == MACH_PORT_NULL) + { +- if (dealloc) +- __vm_deallocate (__mach_task_self (), data.addr, len); +- return -1; ++ err = errno; ++ goto out; + } + err = __ifsock_getsockaddr (file, &aport); + __mach_port_deallocate (__mach_task_self (), file); +@@ -120,11 +164,7 @@ __libc_sendmsg (int fd, const struct msghdr *message, int flags) + /* The file did not grok the ifsock protocol. */ + err = ENOTSOCK; + if (err) +- { +- if (dealloc) +- __vm_deallocate (__mach_task_self (), data.addr, len); +- return __hurd_fail (err); +- } ++ goto out; + } + else + err = EIEIO; +@@ -143,8 +183,9 @@ __libc_sendmsg (int fd, const struct msghdr *message, int flags) + /* Send the data. */ + err = __socket_send (port, aport, + flags, data.ptr, len, +- NULL, +- MACH_MSG_TYPE_COPY_SEND, 0, ++ ports, ++ MACH_MSG_TYPE_COPY_SEND, ++ nports, + message->msg_control, + message->msg_controllen, + &amount); +@@ -153,11 +194,19 @@ __libc_sendmsg (int fd, const struct msghdr *message, int flags) + } + err; + })); ++ socketrpc = 1; ++ ++ out: ++ for (i = 0; i < nports; i++) ++ __mach_port_deallocate (__mach_task_self (), ports[i]); + + if (dealloc) + __vm_deallocate (__mach_task_self (), data.addr, len); + +- return err ? __hurd_sockfail (fd, flags, err) : amount; ++ if (socketrpc) ++ return err ? __hurd_sockfail (fd, flags, err) : amount; ++ else ++ return __hurd_fail (err); + } + + weak_alias (__libc_sendmsg, sendmsg) +-- +tg: (0234227..) t/sendmsg-SCM_RIGHTS (depends on: baseline) only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/hurd-i386/tg-hurdsig-SA_SIGINFO.diff +++ eglibc-2.15/debian/patches/hurd-i386/tg-hurdsig-SA_SIGINFO.diff @@ -0,0 +1,549 @@ +From: Jeremie Koenig +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 +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 directly; use 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 + #include + #include ++#include + #include + #include + #include + #include "hurdfault.h" + #include ++#include + + ++/* 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) only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/hurd-i386/tg-unlockpt-chroot.diff +++ eglibc-2.15/debian/patches/hurd-i386/tg-unlockpt-chroot.diff @@ -0,0 +1,24 @@ +From: Samuel Thibault +Subject: [PATCH] Fix pty path in chroot + +when e.g. using a chroot, the pty path is not so short. + +--- + sysdeps/unix/bsd/unlockpt.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/sysdeps/unix/bsd/unlockpt.c b/sysdeps/unix/bsd/unlockpt.c +index 59fc739..4c3dc5b 100644 +--- a/sysdeps/unix/bsd/unlockpt.c ++++ b/sysdeps/unix/bsd/unlockpt.c +@@ -28,7 +28,7 @@ + int + unlockpt (int fd) + { +- char buf[sizeof (_PATH_TTY) + 2]; ++ char buf[1024]; /* XXX */ + + /* BSD doesn't have a lock, but it does have `revoke'. */ + if (__ptsname_r (fd, buf, sizeof (buf))) +-- +tg: (0234227..) t/unlockpt-chroot (depends on: baseline) only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/hurd-i386/tg-setresid.diff +++ eglibc-2.15/debian/patches/hurd-i386/tg-setresid.diff @@ -0,0 +1,235 @@ +From: Samuel Thibault +Subject: [PATCH] Fix setres[ug]id handling of -1 + +When passed -1, setres[ug]id are supposed not to change the existing +value. The patch below does this the same way as setre[ug]id. + +2011-10-17 Samuel Thibault + +* sysdeps/mach/hurd/setresgid.c (__setresgid): Handle the -1 case, which +shall preserve existing values. +* sysdeps/mach/hurd/setresuid.c (__setresuid): Likewise. + +--- +http://cygwin.com/ml/libc-alpha/2011-10/msg00031.html + + sysdeps/mach/hurd/setresgid.c | 73 +++++++++++++++++++++++++++++++++-------- + sysdeps/mach/hurd/setresuid.c | 73 +++++++++++++++++++++++++++++++++-------- + 2 files changed, 118 insertions(+), 28 deletions(-) + +diff --git a/sysdeps/mach/hurd/setresgid.c b/sysdeps/mach/hurd/setresgid.c +index 8fcf26e..2a0dd90 100644 +--- a/sysdeps/mach/hurd/setresgid.c ++++ b/sysdeps/mach/hurd/setresgid.c +@@ -1,5 +1,5 @@ + /* setresgid -- set real group ID, effective group ID, and saved-set group ID +- Copyright (C) 2002, 2005, 2006 Free Software Foundation, Inc. ++ Copyright (C) 2002, 2005, 2006, 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 +@@ -29,7 +29,6 @@ __setresgid (gid_t rgid, gid_t egid, gid_t sgid) + { + auth_t newauth; + error_t err; +- gid_t agids[2] = { rgid, sgid }; + + HURD_CRITICAL_BEGIN; + __mutex_lock (&_hurd_id.lock); +@@ -40,29 +39,75 @@ __setresgid (gid_t rgid, gid_t egid, gid_t sgid) + /* Make a new auth handle which has EGID as the first element in the + list of effective gids. */ + +- if (_hurd_id.gen.ngids > 0) ++ uid_t *newgen, *newaux; ++ uid_t auxs[2] = { rgid, sgid }; ++ size_t ngen, naux; ++ ++ newgen = _hurd_id.gen.gids; ++ ngen = _hurd_id.gen.ngids; ++ if (egid != -1) ++ { ++ if (_hurd_id.gen.ngids == 0) ++ { ++ /* No effective gids now. The new set will be just UID. */ ++ newgen = &egid; ++ ngen = 1; ++ } ++ else ++ { ++ _hurd_id.gen.gids[0] = egid; ++ _hurd_id.valid = 0; ++ } ++ } ++ ++ newaux = _hurd_id.aux.gids; ++ naux = _hurd_id.aux.ngids; ++ if (rgid != -1) + { +- _hurd_id.gen.gids[0] = egid; +- _hurd_id.valid = 0; ++ if (_hurd_id.aux.ngids == 0) ++ { ++ newaux = &rgid; ++ naux = 1; ++ } ++ else ++ { ++ _hurd_id.aux.gids[0] = rgid; ++ _hurd_id.valid = 0; ++ } + } +- if (_hurd_id.aux.ngids > 1) ++ ++ if (sgid != -1) + { +- _hurd_id.aux.gids[0] = rgid; +- _hurd_id.aux.gids[1] = sgid; +- _hurd_id.valid = 0; ++ if (rgid == -1) ++ { ++ if (_hurd_id.aux.ngids >= 1) ++ auxs[0] = _hurd_id.aux.gids[0]; ++ else if (_hurd_id.gen.ngids >= 1) ++ auxs[0] = _hurd_id.gen.gids[0]; ++ else ++ /* Not even an effective gid, fallback to the only UID we have. */ ++ auxs[0] = sgid; ++ } ++ if (_hurd_id.aux.ngids <= 1) ++ { ++ /* No saved gids now. The new set will be just UID. */ ++ newaux = auxs; ++ naux = 2; ++ } ++ else ++ { ++ _hurd_id.aux.gids[1] = sgid; ++ _hurd_id.valid = 0; ++ } + } + + err = __USEPORT (AUTH, __auth_makeauth + (port, NULL, MACH_MSG_TYPE_COPY_SEND, 0, + _hurd_id.gen.uids, _hurd_id.gen.nuids, + _hurd_id.aux.uids, _hurd_id.aux.nuids, +- _hurd_id.gen.ngids ? _hurd_id.gen.gids : &egid, +- _hurd_id.gen.ngids ?: 1, +- _hurd_id.aux.ngids > 1 ? _hurd_id.aux.gids : agids, +- _hurd_id.aux.ngids > 1 ? _hurd_id.aux.ngids : 2, ++ newgen, ngen, newaux, naux, + &newauth)); + } +- + __mutex_unlock (&_hurd_id.lock); + HURD_CRITICAL_END; + +diff --git a/sysdeps/mach/hurd/setresuid.c b/sysdeps/mach/hurd/setresuid.c +index ccf8d08..e254437 100644 +--- a/sysdeps/mach/hurd/setresuid.c ++++ b/sysdeps/mach/hurd/setresuid.c +@@ -1,5 +1,5 @@ + /* setresuid -- set real user ID, effective user ID, and saved-set user ID +- Copyright (C) 2002, 2005, 2006 Free Software Foundation, Inc. ++ Copyright (C) 2002, 2005, 2006, 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 +@@ -29,7 +29,6 @@ __setresuid (uid_t ruid, uid_t euid, uid_t suid) + { + auth_t newauth; + error_t err; +- uid_t auids[2] = { ruid, suid }; + + HURD_CRITICAL_BEGIN; + __mutex_lock (&_hurd_id.lock); +@@ -40,29 +39,75 @@ __setresuid (uid_t ruid, uid_t euid, uid_t suid) + /* Make a new auth handle which has EUID as the first element in the + list of effective uids. */ + +- if (_hurd_id.gen.nuids > 0) ++ uid_t *newgen, *newaux; ++ uid_t auxs[2] = { ruid, suid }; ++ size_t ngen, naux; ++ ++ newgen = _hurd_id.gen.uids; ++ ngen = _hurd_id.gen.nuids; ++ if (euid != -1) ++ { ++ if (_hurd_id.gen.nuids == 0) ++ { ++ /* No effective uids now. The new set will be just UID. */ ++ newgen = &euid; ++ ngen = 1; ++ } ++ else ++ { ++ _hurd_id.gen.uids[0] = euid; ++ _hurd_id.valid = 0; ++ } ++ } ++ ++ newaux = _hurd_id.aux.uids; ++ naux = _hurd_id.aux.nuids; ++ if (ruid != -1) + { +- _hurd_id.gen.uids[0] = euid; +- _hurd_id.valid = 0; ++ if (_hurd_id.aux.nuids == 0) ++ { ++ newaux = &ruid; ++ naux = 1; ++ } ++ else ++ { ++ _hurd_id.aux.uids[0] = ruid; ++ _hurd_id.valid = 0; ++ } + } +- if (_hurd_id.aux.nuids > 1) ++ ++ if (suid != -1) + { +- _hurd_id.aux.uids[0] = ruid; +- _hurd_id.aux.uids[1] = suid; +- _hurd_id.valid = 0; ++ if (ruid == -1) ++ { ++ if (_hurd_id.aux.nuids >= 1) ++ auxs[0] = _hurd_id.aux.uids[0]; ++ else if (_hurd_id.gen.nuids >= 1) ++ auxs[0] = _hurd_id.gen.uids[0]; ++ else ++ /* Not even an effective uid, fallback to the only UID we have. */ ++ auxs[0] = suid; ++ } ++ if (_hurd_id.aux.nuids <= 1) ++ { ++ /* No saved uids now. The new set will be just UID. */ ++ newaux = auxs; ++ naux = 2; ++ } ++ else ++ { ++ _hurd_id.aux.uids[1] = suid; ++ _hurd_id.valid = 0; ++ } + } + + err = __USEPORT (AUTH, __auth_makeauth + (port, NULL, MACH_MSG_TYPE_COPY_SEND, 0, +- _hurd_id.gen.nuids ? _hurd_id.gen.uids : &euid, +- _hurd_id.gen.nuids ?: 1, +- _hurd_id.aux.nuids > 1 ? _hurd_id.aux.uids : auids, +- _hurd_id.aux.nuids > 1 ? _hurd_id.aux.nuids : 2, ++ newgen, ngen, newaux, naux, + _hurd_id.gen.gids, _hurd_id.gen.ngids, + _hurd_id.aux.gids, _hurd_id.aux.ngids, + &newauth)); + } +- + __mutex_unlock (&_hurd_id.lock); + HURD_CRITICAL_END; + +-- +tg: (0234227..) t/setresid (depends on: baseline) only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/hurd-i386/tg-mlock.diff +++ eglibc-2.15/debian/patches/hurd-i386/tg-mlock.diff @@ -0,0 +1,29 @@ +From: Samuel Thibault +Subject: [PATCH] Fix mlock() in all cases except non-readable pages. + +2006-01-18 Samuel Thibault + + Fix mlock() in all cases except non-readable pages. + + * glibc/sysdeps/mach/hurd/mlock.c (mlock): Give VM_PROT_READ + instead of VM_PROT_ALL as parameter to __vm_wire function. + +--- + sysdeps/mach/hurd/mlock.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/sysdeps/mach/hurd/mlock.c b/sysdeps/mach/hurd/mlock.c +index bb96c9c..ef81efa 100644 +--- a/sysdeps/mach/hurd/mlock.c ++++ b/sysdeps/mach/hurd/mlock.c +@@ -40,7 +40,7 @@ mlock (const void *addr, size_t len) + page = trunc_page ((vm_address_t) addr); + len = round_page ((vm_address_t) addr + len) - page; + err = __vm_wire (hostpriv, __mach_task_self (), page, len, +- VM_PROT_ALL); /* XXX ? */ ++ VM_PROT_READ); + __mach_port_deallocate (__mach_task_self (), hostpriv); + + return err ? __hurd_fail (err) : 0; +-- +tg: (0234227..) t/mlock (depends on: baseline) only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/hurd-i386/tg-mach-nanosleep.diff +++ eglibc-2.15/debian/patches/hurd-i386/tg-mach-nanosleep.diff @@ -0,0 +1,49 @@ +From: Pino Toscano +Subject: [PATCH] nanosleep: check for invalid parameter values + +mach: nanosleep: check for invalid parameter values + +Check for invalid values of the `requested_time' parameters; move the +calculation of `ms' after the validation of `requested_time'. + +2011-12-10 Pino Toscano + + * sysdeps/mach/nanosleep.c (__nanosleep): Return EINVAL for negative + seconds or nanoseconds of `requested_time', or for nanoseconds equal + or greater than 1000000000. + +--- +http://cygwin.com/ml/libc-alpha/2011-12/msg00020.html + + sysdeps/mach/nanosleep.c | 14 +++++++++++--- + 1 files changed, 11 insertions(+), 3 deletions(-) + +diff --git a/sysdeps/mach/nanosleep.c b/sysdeps/mach/nanosleep.c +index e433adb..124af98 100644 +--- a/sysdeps/mach/nanosleep.c ++++ b/sysdeps/mach/nanosleep.c +@@ -28,11 +28,19 @@ __nanosleep (const struct timespec *requested_time, + { + mach_port_t recv; + struct timeval before, after; +- const mach_msg_timeout_t ms +- = requested_time->tv_sec * 1000 +- + (requested_time->tv_nsec + 999999) / 1000000; ++ mach_msg_timeout_t ms; ++ ++ if (requested_time->tv_sec < 0 ++ || requested_time->tv_nsec < 0 ++ || requested_time->tv_nsec >= 1000000000) ++ { ++ errno = EINVAL; ++ return -1; ++ } + + recv = __mach_reply_port (); ++ ms = requested_time->tv_sec * 1000 ++ + (requested_time->tv_nsec + 999999) / 1000000; + + if (remaining && __gettimeofday (&before, NULL) < 0) + return -1; +-- +tg: (0234227..) t/mach-nanosleep (depends on: baseline) only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/hurd-i386/tg-ttyname_ERANGE.diff +++ eglibc-2.15/debian/patches/hurd-i386/tg-ttyname_ERANGE.diff @@ -0,0 +1,29 @@ +From: Samuel Thibault +Subject: [PATCH] ttyname_r returning EINVAL + +2011-08-05 Samuel Thibault + + * sysdeps/mach/hurd/ttyname_r.c (__ttyname_r): Return ERANGE instead of + EINVAL when BUFLEN is too smal. + +--- +http://sourceware.org/ml/libc-alpha/2011-08/msg00013.html + + sysdeps/mach/hurd/ttyname_r.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/sysdeps/mach/hurd/ttyname_r.c b/sysdeps/mach/hurd/ttyname_r.c +index 5f6c9c3..5718fca 100644 +--- a/sysdeps/mach/hurd/ttyname_r.c ++++ b/sysdeps/mach/hurd/ttyname_r.c +@@ -43,7 +43,7 @@ __ttyname_r (int fd, char *buf, size_t buflen) + len = strlen (nodename) + 1; + if (len > buflen) + { +- errno = EINVAL; ++ errno = ERANGE; + return errno; + } + +-- +tg: (0234227..) t/ttyname_ERANGE (depends on: baseline) only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/hurd-i386/tg-posix_opt.h.diff +++ eglibc-2.15/debian/patches/hurd-i386/tg-posix_opt.h.diff @@ -0,0 +1,134 @@ +From: Samuel Thibault +Subject: [PATCH] Update posix_opt.h + +The patch below brings Hurd's posix_opt.h up to date with newer standard +macros. + +2010-01-10 Samuel Thibault + + * posix/tst-sysconf.c (posix_options): Only use + _POSIX_PRIORITIZED_IO, _POSIX_PRIORITY_SCHEDULING, and + _POSIX_SYNCHRONIZED_IO when they are defined + * sysdeps/mach/hurd/bits/posix_opt.h: + (_POSIX_PRIORITY_SCHEDULING): Undefine macro. + (_XOPEN_REALTIME): Undefine macro. + (_XOPEN_REALTIME_THREADS): Undefine macro. + (_XOPEN_SHM): Undefine macro. + [__USE_XOPEN2K8] (_POSIX_THREAD_ROBUST_PRIO_INHERIT): Define + macro to -1. + [__USE_XOPEN2K8] (_POSIX_THREAD_ROBUST_PRIO_PROTECT): Define + macro to -1. + (_POSIX_ASYNC_IO): Undefine macro. + (_POSIX_PRIORITIZED_IO): Undefine macro. + (_POSIX_SPIN_LOCKS): Define macro to -1. + +--- +http://cygwin.com/ml/libc-alpha/2010-01/msg00012.html + + posix/tst-sysconf.c | 6 ++++++ + sysdeps/mach/hurd/bits/posix_opt.h | 28 +++++++++++++++++++++++----- + 2 files changed, 29 insertions(+), 5 deletions(-) + +diff --git a/posix/tst-sysconf.c b/posix/tst-sysconf.c +index e297229..105c7c2 100644 +--- a/posix/tst-sysconf.c ++++ b/posix/tst-sysconf.c +@@ -29,8 +29,12 @@ static struct + N (MEMORY_PROTECTION), + N (MESSAGE_PASSING), + N (MONOTONIC_CLOCK), ++#ifdef _POSIX_PRIORITIZED_IO + N (PRIORITIZED_IO), ++#endif ++#ifdef _POSIX_PRIORITY_SCHEDULING + N (PRIORITY_SCHEDULING), ++#endif + N (RAW_SOCKETS), + N (READER_WRITER_LOCKS), + N (REALTIME_SIGNALS), +@@ -42,7 +46,9 @@ static struct + N (SPAWN), + N (SPIN_LOCKS), + N (SPORADIC_SERVER), ++#ifdef _POSIX_SYNCHRONIZED_IO + N (SYNCHRONIZED_IO), ++#endif + N (THREAD_ATTR_STACKADDR), + N (THREAD_ATTR_STACKSIZE), + N (THREAD_CPUTIME), +diff --git a/sysdeps/mach/hurd/bits/posix_opt.h b/sysdeps/mach/hurd/bits/posix_opt.h +index 775c921..4c1b06b 100644 +--- a/sysdeps/mach/hurd/bits/posix_opt.h ++++ b/sysdeps/mach/hurd/bits/posix_opt.h +@@ -31,6 +31,9 @@ + /* Processes have a saved set-user-ID and a saved set-group-ID. */ + #define _POSIX_SAVED_IDS 1 + ++/* Priority scheduling is not supported. */ ++#undef _POSIX_PRIORITY_SCHEDULING ++ + /* Synchronizing file data is supported, but msync is missing. */ + #undef _POSIX_SYNCHRONIZED_IO + +@@ -60,6 +63,14 @@ + #undef _POSIX_NO_TRUNC /* Overlong file names get error? */ + #undef _POSIX_SYNC_IO /* File supports O_SYNC et al? */ + ++/* X/Open realtime support is not supported. */ ++#undef _XOPEN_REALTIME ++ ++/* X/Open thread realtime support is not supported. */ ++#undef _XOPEN_REALTIME_THREADS ++ ++/* XPG4.2 shared memory is not supported. */ ++#undef _XOPEN_SHM + + /* We do not have the POSIX threads interface. */ + #define _POSIX_THREADS -1 +@@ -72,6 +83,12 @@ + #define _POSIX_THREAD_PRIORITY_SCHEDULING -1 + #define _POSIX_THREAD_ATTR_STACKSIZE -1 + #define _POSIX_THREAD_ATTR_STACKADDR -1 ++#define _POSIX_THREAD_PRIO_INHERIT -1 ++#define _POSIX_THREAD_PRIO_PROTECT -1 ++#ifdef __USE_XOPEN2K8 ++# define _POSIX_THREAD_ROBUST_PRIO_INHERIT -1 ++# define _POSIX_THREAD_ROBUST_PRIO_PROTECT -1 ++#endif + #define _POSIX_SEMAPHORES -1 + + /* Real-time signals are not yet supported. */ +@@ -79,8 +96,11 @@ + + /* Asynchronous I/O might supported with the existing ABI. */ + #define _POSIX_ASYNCHRONOUS_IO 0 ++#undef _POSIX_ASYNC_IO + /* Alternative name for Unix98. */ + #define _LFS_ASYNCHRONOUS_IO _POSIX_ASYNCHRONOUS_IO ++/* Support for prioritization is not available. */ ++#undef _POSIX_PRIORITIZED_IO + + /* The LFS support in asynchronous I/O is also available. */ + #define _LFS64_ASYNCHRONOUS_IO _POSIX_ASYNCHRONOUS_IO +@@ -111,6 +131,9 @@ + /* We cannot support the Timeouts option without _POSIX_THREADS. */ + #define _POSIX_TIMEOUTS -1 + ++/* We do not support spinlocks. */ ++#define _POSIX_SPIN_LOCKS -1 ++ + /* The `spawn' function family is supported. */ + #define _POSIX_SPAWN 200809L + +@@ -157,9 +180,4 @@ + /* Typed memory objects are not available. */ + #define _POSIX_TYPED_MEMORY_OBJECTS -1 + +-/* No support for priority inheritance or protection so far. */ +-#define _POSIX_THREAD_PRIO_INHERIT -1 +-#define _POSIX_THREAD_PRIO_PROTECT -1 +- +- + #endif /* bits/posix_opt.h */ +-- +tg: (0234227..) t/posix_opt.h (depends on: baseline) only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/hurd-i386/tg-thread-cancel.diff +++ eglibc-2.15/debian/patches/hurd-i386/tg-thread-cancel.diff @@ -0,0 +1,21 @@ +From: Samuel Thibault +Subject: [PATCH] The critical section lock _can_ be held in that place. + +--- + hurd/thread-cancel.c | 1 - + 1 files changed, 0 insertions(+), 1 deletions(-) + +diff --git a/hurd/thread-cancel.c b/hurd/thread-cancel.c +index c8b6cf5..f463f92 100644 +--- a/hurd/thread-cancel.c ++++ b/hurd/thread-cancel.c +@@ -52,7 +52,6 @@ hurd_thread_cancel (thread_t thread) + return 0; + } + +- assert (! __spin_lock_locked (&ss->critical_section_lock)); + __spin_lock (&ss->critical_section_lock); + __spin_lock (&ss->lock); + err = __thread_suspend (thread); +-- +tg: (0234227..) t/thread-cancel (depends on: baseline) only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/hurd-i386/tg-hurd-recvfrom.diff +++ eglibc-2.15/debian/patches/hurd-i386/tg-hurd-recvfrom.diff @@ -0,0 +1,44 @@ +From: Pino Toscano +Subject: [PATCH] recvfrom(): take into account null address ports + +Some kinds of sockets may return a null address port when calling the +`socket_recv' RPC, so avoid using it in case an address argument buffer is +asked to be filled. In such case, set the length of that address buffer to +zero. + +2011-11-26 Pino Toscano + + * sysdeps/mach/hurd/recvfrom.c (__recvfrom): Check also for a null + address port. Set `addr_len' to 0 when not filling `addrarg'. + +--- + +http://cygwin.com/ml/libc-alpha/2011-11/msg00089.html + + sysdeps/mach/hurd/recvfrom.c | 4 +++- + 1 files changed, 3 insertions(+), 1 deletions(-) + +diff --git a/sysdeps/mach/hurd/recvfrom.c b/sysdeps/mach/hurd/recvfrom.c +index 2aca570..94de4e7 100644 +--- a/sysdeps/mach/hurd/recvfrom.c ++++ b/sysdeps/mach/hurd/recvfrom.c +@@ -55,7 +55,7 @@ __recvfrom (fd, buf, n, flags, addrarg, addr_len) + return __hurd_sockfail (fd, flags, err); + + /* Get address data for the returned address port if requested. */ +- if (addr != NULL) ++ if (addr != NULL && addrport != MACH_PORT_NULL) + { + char *buf = (char *) addr; + mach_msg_type_number_t buflen = *addr_len; +@@ -89,6 +89,8 @@ __recvfrom (fd, buf, n, flags, addrarg, addr_len) + if (buflen > 0) + addr->sa_family = type; + } ++ else if (addr_len != NULL) ++ *addr_len = 0; + + __mach_port_deallocate (__mach_task_self (), addrport); + +-- +tg: (0234227..) t/recvfrom (depends on: baseline) only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/hurd-i386/tg-hurdsig-global-dispositions.diff +++ eglibc-2.15/debian/patches/hurd-i386/tg-hurdsig-global-dispositions.diff @@ -0,0 +1,1226 @@ +From: Jeremie Koenig +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 . +@@ -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 + +-/* 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) only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/hurd-i386/tg-posix2008.diff +++ eglibc-2.15/debian/patches/hurd-i386/tg-posix2008.diff @@ -0,0 +1,80 @@ +From: Samuel Thibault +Subject: [PATCH] Fix POSIX 2008 visibility + +Here are a few POSIX 2008 visibility updates, to align the core & hurd +with the Linux headers. + +Samuel + + +2011-12-04 Samuel Thibault + + * bits/sigaction.h [__USE_XOPEN2K8]: Define SA_RESTART, + SA_NODEFER, SA_RESETHAND. + * sysdeps/mach/hurd/bits/fcntl.h [__USE_XOPEN2K8]: Define + O_NOFOLLOW, O_DIRECTORY, O_CLOEXEC, F_GETOWN, F_SETOWN, + F_DUPFD_CLOEXEC. + +--- +http://cygwin.com/ml/libc-alpha/2011-12/msg00005.html + + bits/sigaction.h | 2 ++ + sysdeps/mach/hurd/bits/fcntl.h | 8 +++++--- + 2 files changed, 7 insertions(+), 3 deletions(-) + +diff --git a/bits/sigaction.h b/bits/sigaction.h +index adcc276..97242a6 100644 +--- a/bits/sigaction.h ++++ b/bits/sigaction.h +@@ -55,6 +55,8 @@ struct sigaction + /* 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. */ +diff --git a/sysdeps/mach/hurd/bits/fcntl.h b/sysdeps/mach/hurd/bits/fcntl.h +index b4147ce..74cf913 100644 +--- a/sysdeps/mach/hurd/bits/fcntl.h ++++ b/sysdeps/mach/hurd/bits/fcntl.h +@@ -55,7 +55,9 @@ + #ifdef __USE_GNU + # define O_NOLINK 0x0040 /* No name mappings on final component. */ + # define O_NOTRANS 0x0080 /* No translator on final component. */ ++#endif + ++#ifdef __USE_XOPEN2K8 + # define O_NOFOLLOW 0x00100000 /* Produce ENOENT if file is a symlink. */ + # define O_DIRECTORY 0x00200000 /* Produce ENOTDIR if not a directory. */ + #endif +@@ -119,7 +121,7 @@ + once the file has been opened. */ + + #define O_TRUNC 0x00010000 /* Truncate file to zero length. */ +-#ifdef __USE_GNU ++#ifdef __USE_XOPEN2K8 + # define O_CLOEXEC 0x00400000 /* Set FD_CLOEXEC. */ + #endif + +@@ -159,7 +161,7 @@ + #define F_SETFD 2 /* Set file descriptor flags. */ + #define F_GETFL 3 /* Get file status flags. */ + #define F_SETFL 4 /* Set file status flags. */ +-#if defined __USE_BSD || defined __USE_UNIX98 ++#if defined __USE_BSD || defined __USE_UNIX98 || defined __USE_XOPEN2K8 + # define F_GETOWN 5 /* Get owner (receiver of SIGIO). */ + # define F_SETOWN 6 /* Set owner (receiver of SIGIO). */ + #endif +@@ -167,7 +169,7 @@ + #define F_SETLK 8 /* Set record locking info (non-blocking). */ + #define F_SETLKW 9 /* Set record locking info (blocking). */ + +-#ifdef __USE_GNU ++#ifdef __USE_XOPEN2K8 + # define F_DUPFD_CLOEXEC 1030 /* Duplicate, set FD_CLOEXEC on new one. */ + #endif + +-- +tg: (0234227..) t/posix2008 (depends on: baseline) only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/hurd-i386/tg-IPV6_PKTINFO.diff +++ eglibc-2.15/debian/patches/hurd-i386/tg-IPV6_PKTINFO.diff @@ -0,0 +1,36 @@ +From: Samuel Thibault +Subject: [PATCH] Add more ipv6 macros. + +http://www.sourceware.org/bugzilla/show_bug.cgi?id=3906 + +--- + bits/in.h | 7 ++++--- + 1 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/bits/in.h b/bits/in.h +index 4687a29..d2d123c 100644 +--- a/bits/in.h ++++ b/bits/in.h +@@ -50,7 +50,7 @@ struct ip_opts + + /* IPV6 socket options. */ + #define IPV6_ADDRFORM 1 +-#define IPV6_RXINFO 2 ++#define IPV6_PKTINFO 2 + #define IPV6_HOPOPTS 3 + #define IPV6_DSTOPTS 4 + #define IPV6_RTHDR 5 +@@ -58,8 +58,9 @@ struct ip_opts + #define IPV6_CHECKSUM 7 + #define IPV6_HOPLIMIT 8 + +-#define IPV6_TXINFO IPV6_RXINFO +-#define SCM_SRCINFO IPV6_TXINFO ++#define IPV6_RXINFO IPV6_PKTINFO ++#define IPV6_TXINFO IPV6_PKTINFO ++#define SCM_SRCINFO IPV6_PKTINFO + #define SCM_SRCRT IPV6_RXSRCRT + + #define IPV6_UNICAST_HOPS 16 +-- +tg: (0234227..) t/IPV6_PKTINFO (depends on: baseline) only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/hurd-i386/tg-readlinkat.diff +++ eglibc-2.15/debian/patches/hurd-i386/tg-readlinkat.diff @@ -0,0 +1,89 @@ +From: Samuel Thibault +Subject: [PATCH] readlinkat + +2009-09-27 Samuel Thibault + + * sysdeps/mach/hurd/readlinkat.c: New file, heavily inherited from + sysdeps/mach/hurd/readlink.c + +--- +http://cygwin.com/ml/libc-alpha/2009-09/msg00058.html + + sysdeps/mach/hurd/readlinkat.c | 67 ++++++++++++++++++++++++++++++++++++++++ + 1 files changed, 67 insertions(+), 0 deletions(-) + +diff --git a/sysdeps/mach/hurd/readlinkat.c b/sysdeps/mach/hurd/readlinkat.c +new file mode 100644 +index 0000000..59aeede +--- /dev/null ++++ b/sysdeps/mach/hurd/readlinkat.c +@@ -0,0 +1,67 @@ ++/* Copyright (C) 1991,92,93,94,95,97,2002,2009 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. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Read the contents of the symbolic link FILE_NAME relative to FD into no more ++ than LEN bytes of BUF. The contents are not null-terminated. ++ Returns the number of characters read, or -1 for errors. */ ++ssize_t ++readlinkat (fd, file_name, buf, len) ++ int fd; ++ const char *file_name; ++ char *buf; ++ size_t len; ++{ ++ error_t err; ++ file_t file; ++ struct stat64 st; ++ ++ file = __file_name_lookup_at (fd, 0, file_name, O_READ | O_NOLINK, 0); ++ if (file == MACH_PORT_NULL) ++ return -1; ++ ++ err = __io_stat (file, &st); ++ if (! err) ++ if (S_ISLNK (st.st_mode)) ++ { ++ char *rbuf = buf; ++ ++ err = __io_read (file, &rbuf, &len, 0, len); ++ if (!err && rbuf != buf) ++ { ++ memcpy (buf, rbuf, len); ++ __vm_deallocate (__mach_task_self (), (vm_address_t)rbuf, len); ++ } ++ } ++ else ++ err = EINVAL; ++ ++ __mach_port_deallocate (__mach_task_self (), file); ++ ++ if (err) ++ return __hurd_fail (err); ++ else ++ return len; ++} ++libc_hidden_def (readlinkat); +-- +tg: (0234227..) t/readlinkat (depends on: baseline) only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/hurd-i386/tg-bigmem.diff +++ eglibc-2.15/debian/patches/hurd-i386/tg-bigmem.diff @@ -0,0 +1,48 @@ +From: Samuel Thibault +Subject: [PATCH] Allow the kernel to start earlier than VM_MAX_ADDRESS + +A bit hackish. + +--- + sysdeps/mach/hurd/dl-sysdep.c | 26 ++++++++++++++++++++------ + 1 files changed, 20 insertions(+), 6 deletions(-) + +diff --git a/sysdeps/mach/hurd/dl-sysdep.c b/sysdeps/mach/hurd/dl-sysdep.c +index 6f27874..2923832 100644 +--- a/sysdeps/mach/hurd/dl-sysdep.c ++++ b/sysdeps/mach/hurd/dl-sysdep.c +@@ -102,12 +102,26 @@ static void fmh(void) { + max=a; break;} + fmha=a+=fmhs;} + if (err) assert(err==KERN_NO_SPACE); +- if (!fmha)fmhs=0;else{ +- fmhs=max-fmha; +- err = __vm_map (__mach_task_self (), +- &fmha, fmhs, 0, 0, MACH_PORT_NULL, 0, 1, +- VM_PROT_NONE, VM_PROT_NONE, VM_INHERIT_COPY); +- assert_perror(err);} ++ if (!fmha) ++ fmhs=0; ++ else ++ while (1) { ++ fmhs=max-fmha; ++ err = __vm_map (__mach_task_self (), ++ &fmha, fmhs, 0, 0, MACH_PORT_NULL, 0, 1, ++ VM_PROT_NONE, VM_PROT_NONE, VM_INHERIT_COPY); ++ if (!err) ++ break; ++ if (err != KERN_INVALID_ADDRESS && err != KERN_NO_SPACE) ++ assert_perror(err); ++ vm_address_t new_max = (max - 1) & 0xf0000000U; ++ if (new_max >= max) { ++ fmhs = 0; ++ fmha = 0; ++ break; ++ } ++ max = new_max; ++ } + } + /* XXX loser kludge for vm_map kernel bug */ + #endif +-- +tg: (0234227..) t/bigmem (depends on: baseline) only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/hurd-i386/tg-itimer-lock.diff +++ eglibc-2.15/debian/patches/hurd-i386/tg-itimer-lock.diff @@ -0,0 +1,32 @@ +From: Samuel Thibault +Subject: [PATCH] setitimer.c: Fix unlock in error patch + +In some error path, setitimer_locked would not perform unlocking, here +is a patch. + +2009-02-01 Samuel Thibault + + * sysdeps/mach/hurd/setitimer.c (setitimer_locked): Use common exit path + instead of returning without unlocking. + +--- +http://sourceware.org/ml/libc-alpha/2009-02/msg00003.html + + sysdeps/mach/hurd/setitimer.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/sysdeps/mach/hurd/setitimer.c b/sysdeps/mach/hurd/setitimer.c +index fec64a8..7de968d 100644 +--- a/sysdeps/mach/hurd/setitimer.c ++++ b/sysdeps/mach/hurd/setitimer.c +@@ -220,7 +220,7 @@ setitimer_locked (const struct itimerval *new, struct itimerval *old, + /* Start up the itimer thread running `timer_thread' (below). */ + if (err = __thread_create (__mach_task_self (), + &_hurd_itimer_thread)) +- return __hurd_fail (err); ++ goto out; + _hurd_itimer_thread_stack_base = 0; /* Anywhere. */ + _hurd_itimer_thread_stack_size = __vm_page_size; /* Small stack. */ + if (err = __mach_setup_thread (__mach_task_self (), +-- +tg: (0234227..) t/itimer-lock (depends on: baseline) only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/hurd-i386/tg-dup3-lock.diff +++ eglibc-2.15/debian/patches/hurd-i386/tg-dup3-lock.diff @@ -0,0 +1,56 @@ +From: Samuel Thibault +Subject: [PATCH] Fix __dup3 _hurd_dtable_lock usage. + +2009-01-12 Samuel Thibault + + * sysdeps/mach/hurd/dup3.c (__dup2): Lock _hurd_dtable_lock + before checking for _hurd_dtablesize. Unlock it right after + having finished _hurd_dtable allocation. + +--- + +http://sources.redhat.com/ml/libc-alpha/2009-01/msg00030.html + + sysdeps/mach/hurd/dup3.c | 7 +++---- + 1 files changed, 3 insertions(+), 4 deletions(-) + +diff --git a/sysdeps/mach/hurd/dup3.c b/sysdeps/mach/hurd/dup3.c +index 178ee16..71a0a81 100644 +--- a/sysdeps/mach/hurd/dup3.c ++++ b/sysdeps/mach/hurd/dup3.c +@@ -71,15 +71,14 @@ dup3 (int fd, int fd2, int flags) + /* Get a hold of the destination descriptor. */ + struct hurd_fd *d2; + ++ __mutex_lock (&_hurd_dtable_lock); ++ + if (fd2 >= _hurd_dtablesize) + { + /* The table is not large enough to hold the destination + descriptor. Enlarge it as necessary to allocate this + descriptor. */ + __mutex_unlock (&_hurd_dtable_lock); +- /* We still hold FD1's lock, but this is safe because +- _hurd_alloc_fd will only examine the cells starting +- at FD2. */ + d2 = _hurd_alloc_fd (NULL, fd2); + if (d2) + __spin_unlock (&d2->port.lock); +@@ -99,6 +98,7 @@ dup3 (int fd, int fd2, int flags) + MACH_PORT_NULL); + } + } ++ __mutex_unlock (&_hurd_dtable_lock); + + if (d2 == NULL) + { +@@ -126,7 +126,6 @@ dup3 (int fd, int fd2, int flags) + _hurd_port_locked_set (&d2->port, port); /* Unlocks D2. */ + } + } +- __mutex_unlock (&_hurd_dtable_lock); + + _hurd_port_free (&d->port, &ulink, port); + if (ctty != MACH_PORT_NULL) +-- +tg: (d801e4c..) tg/dup3-lock (depends on: t/dup3) only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/hurd-i386/tg-ioctl-base-types.diff +++ eglibc-2.15/debian/patches/hurd-i386/tg-ioctl-base-types.diff @@ -0,0 +1,55 @@ +From: Samuel Thibault +Subject: [PATCH] Add some basic types for ioctls. + +--- + +http://sources.redhat.com/ml/libc-alpha/2007-07/msg00078.html + + sysdeps/mach/hurd/bits/ioctls.h | 23 ++++++++++++++++++++++- + 1 files changed, 22 insertions(+), 1 deletions(-) + +diff --git a/sysdeps/mach/hurd/bits/ioctls.h b/sysdeps/mach/hurd/bits/ioctls.h +index 8718aac..b057dc7 100644 +--- a/sysdeps/mach/hurd/bits/ioctls.h ++++ b/sysdeps/mach/hurd/bits/ioctls.h +@@ -149,9 +149,26 @@ enum __ioctl_datum { IOC_8, IOC_16, IOC_32, IOC_64 }; + #define _IOT_SIMPLE(type) _IOT (_IOTS (type), 1, 0, 0, 0, 0) + + /* Basic C types. */ +-#define _IOT__IOTBASE_int _IOT_SIMPLE (int) + #define _IOT__IOTBASE_char _IOT_SIMPLE (char) + #define _IOT__IOTBASE_short _IOT_SIMPLE (short) ++#define _IOT__IOTBASE_int _IOT_SIMPLE (int) ++#define _IOT__IOTBASE_long _IOT_SIMPLE (long) ++#define _IOT_char _IOT_SIMPLE (char) ++#define _IOT_short _IOT_SIMPLE (short) ++#define _IOT_int _IOT_SIMPLE (int) ++#define _IOT_long _IOT_SIMPLE (long) ++ ++#define _IOT__IOTBASE_int8_t _IOT_SIMPLE (int8_t) ++#define _IOT__IOTBASE_uint8_t _IOT_SIMPLE (uint8_t) ++#define _IOT__IOTBASE_int16_t _IOT_SIMPLE (int16_t) ++#define _IOT__IOTBASE_uint16_t _IOT_SIMPLE (uint16_t) ++#define _IOT__IOTBASE_int32_t _IOT_SIMPLE (int32_t) ++#define _IOT__IOTBASE_uint32_t _IOT_SIMPLE (uint32_t) ++#define _IOT__IOTBASE_int64_t _IOT_SIMPLE (int64_t) ++#define _IOT__IOTBASE_uint64_t _IOT_SIMPLE (uint64_t) ++ ++#define _IOT__IOTBASE_size_t _IOT_SIMPLE (size_t) ++#define _IOT__IOTBASE_ssize_t _IOT_SIMPLE (ssize_t) + + + /* Standard flavors of ioctls. +@@ -173,6 +190,10 @@ enum __ioctl_datum { IOC_8, IOC_16, IOC_32, IOC_64 }; + #define _IOC_ENCODE_TYPE_1(typespec) _IOC_ENCODE_TYPE_2(typespec) + #define _IOC_ENCODE_TYPE_2(typespec) _IOT_##typespec + ++/* Also, ignore signedness. */ ++#define _IOTBASE_unsigned ++#define _IOTBASE_signed ++ + + /* ioctls verbatim from 4.4 . */ + +-- +tg: (0234227..) t/ioctl-base-types (depends on: baseline) only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/hurd-i386/tg-select-inputcheck.diff +++ eglibc-2.15/debian/patches/hurd-i386/tg-select-inputcheck.diff @@ -0,0 +1,62 @@ +From: Pino Toscano +Subject: [PATCH] _hurd_select: check for invalid parameter values + +Check for invalid values of the `timeout' and `nfds' parameters; move the +calculation of `to' right after the validation of `timeout'. + +2011-11-26 Pino Toscano + + * hurd/hurdselect.c (_hurd_select): Return EINVAL for negative + `timeout' values. + Return EINVAL for `nfds' values either negative or greater than + FD_SETSIZE. + +--- +http://cygwin.com/ml/libc-alpha/2011-12/msg00012.html + + hurd/hurdselect.c | 23 +++++++++++++++++++---- + 1 files changed, 19 insertions(+), 4 deletions(-) + +diff --git a/hurd/hurdselect.c b/hurd/hurdselect.c +index a7228f0..ccc275d 100644 +--- a/hurd/hurdselect.c ++++ b/hurd/hurdselect.c +@@ -50,10 +50,7 @@ _hurd_select (int nfds, + error_t err; + fd_set rfds, wfds, xfds; + int firstfd, lastfd; +- mach_msg_timeout_t to = (timeout != NULL ? +- (timeout->tv_sec * 1000 + +- (timeout->tv_nsec + 999999) / 1000000) : +- 0); ++ mach_msg_timeout_t to = 0; + struct + { + struct hurd_userlink ulink; +@@ -72,6 +69,24 @@ _hurd_select (int nfds, + assert (sizeof (union typeword) == sizeof (mach_msg_type_t)); + assert (sizeof (uint32_t) == sizeof (mach_msg_type_t)); + ++ if (nfds < 0 || nfds > FD_SETSIZE) ++ { ++ errno = EINVAL; ++ return -1; ++ } ++ ++ if (timeout != NULL) ++ { ++ if (timeout->tv_sec < 0 || timeout->tv_nsec < 0) ++ { ++ errno = EINVAL; ++ return -1; ++ } ++ ++ to = timeout->tv_sec * 1000 + ++ (timeout->tv_nsec + 999999) / 1000000; ++ } ++ + if (sigmask && __sigprocmask (SIG_SETMASK, sigmask, &oset)) + return -1; + +-- +tg: (0234227..) t/select-inputcheck (depends on: baseline) only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/hurd-i386/local-hurdsig-global-dispositions-version.diff +++ eglibc-2.15/debian/patches/hurd-i386/local-hurdsig-global-dispositions-version.diff @@ -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_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 { only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/hurd-i386/tg-hurd_socket_server_indexcheck.diff +++ eglibc-2.15/debian/patches/hurd-i386/tg-hurd_socket_server_indexcheck.diff @@ -0,0 +1,38 @@ +From: Pino Toscano +Subject: [PATCH] hurdsock: reject negative domains + +Reject negative socket domains right away; otherwise, it is possible to read +and set out-of-bounds locations of the `servers' array (returning the values +at those invalid memory locations), and even try to deallocate ports with +random values if the `dead' parameter is different than zero. + +2011-11-21 Pino Toscano + + * hurd/hurdsock.c (_hurd_socket_server): Check for negative domains, + and reject them. + +--- +http://cygwin.com/ml/libc-alpha/2011-11/msg00076.html + + hurd/hurdsock.c | 6 ++++++ + 1 files changed, 6 insertions(+), 0 deletions(-) + +diff --git a/hurd/hurdsock.c b/hurd/hurdsock.c +index a01b8aa..f2817e3 100644 +--- a/hurd/hurdsock.c ++++ b/hurd/hurdsock.c +@@ -47,6 +47,12 @@ _hurd_socket_server (int domain, int dead) + { + socket_t server; + ++ if (domain < 0) ++ { ++ errno = EAFNOSUPPORT; ++ return MACH_PORT_NULL; ++ } ++ + HURD_CRITICAL_BEGIN; + __mutex_lock (&lock); + +-- +tg: (0234227..) t/socket_server_indexcheck (depends on: baseline) only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/hurd-i386/tg-locarchive.diff +++ eglibc-2.15/debian/patches/hurd-i386/tg-locarchive.diff @@ -0,0 +1,50 @@ +From: Samuel Thibault +Subject: [PATCH] Fix installation of locales-all + +Dirty hack to fix installation of locales-all: instead of just locking the +archive extension (which is not supported on hurd-i386), lock it all. + +--- + locale/programs/locarchive.c | 18 ++++++++++++++++++ + 1 files changed, 18 insertions(+), 0 deletions(-) + +diff --git a/locale/programs/locarchive.c b/locale/programs/locarchive.c +index 770a731..4af9fe1 100644 +--- a/locale/programs/locarchive.c ++++ b/locale/programs/locarchive.c +@@ -414,7 +414,16 @@ enlarge_archive (struct locarhandle *ah, const struct locarhead *head) + } + + /* Lock the new file. */ ++#ifdef __GNU__ ++ struct flock fl; ++ fl.l_whence = SEEK_SET; ++ fl.l_start = 0; ++ fl.l_len = 0; ++ fl.l_type = F_WRLCK; ++ if (fcntl(fd, F_SETLKW, &fl) != 0) ++#else + if (lockf64 (fd, F_LOCK, total) != 0) ++#endif + { + int errval = errno; + unlink (fname); +@@ -560,7 +569,16 @@ open_archive (struct locarhandle *ah, bool readonly) + error (EXIT_FAILURE, errno, _("cannot stat locale archive \"%s\""), + archivefname); + ++#ifdef __GNU__ ++ struct flock fl; ++ fl.l_whence = SEEK_SET; ++ fl.l_start = 0; ++ fl.l_len = 0; ++ fl.l_type = F_WRLCK; ++ if (!readonly && fcntl(fd, F_SETLKW, &fl) == -1) ++#else + if (!readonly && lockf64 (fd, F_LOCK, sizeof (struct locarhead)) == -1) ++#endif + { + close (fd); + +-- +tg: (0234227..) t/locarchive (depends on: baseline) only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/hurd-i386/tg-ioctl-decode-argument.diff +++ eglibc-2.15/debian/patches/hurd-i386/tg-ioctl-decode-argument.diff @@ -0,0 +1,74 @@ +From: Samuel Thibault +Subject: [PATCH] ioctl() incorrectly decodes argument + +2005-07-28 Samuel Thibault + + * ioctl.c (__ioctl): Add handling of parameter-less ioctls. + +2005-07-28 Samuel Thibault + + * ioctls.h (_IOIW): New macro for immediate-write ioctls. + +--- +http://www.sourceware.org/bugzilla/show_bug.cgi?id=766 + + sysdeps/mach/hurd/ioctl.c | 16 ++++++++++------ + sysdeps/mach/hurd/bits/ioctls.h | 1 + + 2 files changed, 11 insertions(+), 6 deletions(-) + +diff --git a/sysdeps/mach/hurd/ioctl.c b/sysdeps/mach/hurd/ioctl.c +index bcc78bc..769eb68 100644 +--- a/sysdeps/mach/hurd/ioctl.c ++++ b/sysdeps/mach/hurd/ioctl.c +@@ -89,7 +89,7 @@ __ioctl (int fd, unsigned long int request, ...) + void *p; + #endif + +- void *arg; ++ void *arg = NULL; + + error_t err; + +@@ -140,7 +140,7 @@ __ioctl (int fd, unsigned long int request, ...) + in (_IOT_COUNT1 (type), _IOT_TYPE1 (type)); + in (_IOT_COUNT2 (type), _IOT_TYPE2 (type)); + } +- else if (_IOC_INOUT (request) == IOC_VOID) ++ else if ((_IOC_INOUT (request) == IOC_VOID) && _IOT_COUNT0 (type)) + { + /* The RPC takes a single integer_t argument. + Rather than pointing to the value, ARG is the value itself. */ +@@ -209,11 +209,15 @@ __ioctl (int fd, unsigned long int request, ...) + return msg.header.RetCode; + } + +- va_list ap; ++ if (_IOT_COUNT0 (type)) ++ { ++ /* Data need either be sent, received, or even both. */ ++ va_list ap; + +- va_start (ap, request); +- arg = va_arg (ap, void *); +- va_end (ap); ++ va_start (ap, request); ++ arg = va_arg (ap, void *); ++ va_end (ap); ++ } + + { + /* Check for a registered handler for REQUEST. */ +diff --git a/sysdeps/mach/hurd/bits/ioctls.h b/sysdeps/mach/hurd/bits/ioctls.h +index 8718aac..d35e272 100644 +--- a/sysdeps/mach/hurd/bits/ioctls.h ++++ b/sysdeps/mach/hurd/bits/ioctls.h +@@ -158,6 +158,7 @@ enum __ioctl_datum { IOC_8, IOC_16, IOC_32, IOC_64 }; + _IOT_foobar is defined either in this file, + or where struct foobar is defined. */ + #define _IO(g, n) _IOC (IOC_VOID, (g), (n), 0) ++#define _IOIW(g, n, t) _IOC (IOC_VOID, (g), (n), _IOC_ENCODE_TYPE (t)) + #define _IOR(g, n, t) _IOC (IOC_OUT, (g), (n), _IOC_ENCODE_TYPE (t)) + #define _IOW(g, n, t) _IOC (IOC_IN, (g), (n), _IOC_ENCODE_TYPE (t)) + #define _IOWR(g, n, t) _IOC (IOC_INOUT, (g), (n), _IOC_ENCODE_TYPE (t)) +-- +tg: (0234227..) t/ioctl_decode_argument (depends on: baseline) only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/hurd-i386/tg-hurdsig-fixes.diff +++ eglibc-2.15/debian/patches/hurd-i386/tg-hurdsig-fixes.diff @@ -0,0 +1,374 @@ +From: Jeremie Koenig +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) only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/hurd-i386/tg-hurdsig-fixes-2.diff +++ eglibc-2.15/debian/patches/hurd-i386/tg-hurdsig-fixes-2.diff @@ -0,0 +1,59 @@ +From: Jeremie Koenig +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) only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/hurd-i386/tg-sysvshm.diff +++ eglibc-2.15/debian/patches/hurd-i386/tg-sysvshm.diff @@ -0,0 +1,798 @@ +From: Marcus Brinkmann +Subject: [PATCH] Implement SysV shared memory for GNU/Hurd. + +2005-07-11 Marcus Brinkmann + + * hurd/Makefile (routines): Add sysvshm. + (distribute): Add sysvshm.h. + * hurd/sysvshm.h: New file. + * hurd/sysvshm.c: New file. + * sysdeps/mach/hurd/bits/stat.h (S_IMMAP0): New macro. + (S_ISPARE): Unset the S_IMMAP0 flag. + * sysdeps/mach/hurd/ftok.c: New file. + * sysdeps/mach/hurd/shmat.c: New file. + * sysdeps/mach/hurd/shmctl.c: New file. + * sysdeps/mach/hurd/shmdt.c: New file. + * sysdeps/mach/hurd/bits/posix_opt.h: Define _XOPEN_SHM to 1. + +--- + hurd/Makefile | 3 +- + hurd/sysvshm.c | 96 ++++++++++++++ + hurd/sysvshm.h | 47 +++++++ + sysdeps/mach/hurd/bits/posix_opt.h | 4 +-- + sysdeps/mach/hurd/ftok.c | 43 +++++++ + sysdeps/mach/hurd/shmat.c | 78 ++++++++++++ + sysdeps/mach/hurd/shmctl.c | 132 ++++++++++++++++++++ + sysdeps/mach/hurd/shmdt.c | 51 ++++++++ + sysdeps/mach/hurd/shmget.c | 242 ++++++++++++++++++++++++++++++++++++ + 9 files changed, 693 insertions(+), 3 deletions(-) + +diff --git a/hurd/Makefile b/hurd/Makefile +index ab5a848..ff6b7cb 100644 +--- a/hurd/Makefile ++++ b/hurd/Makefile +@@ -60,6 +60,7 @@ routines = hurdstartup hurdinit \ + vpprintf \ + ports-get ports-set hurdports hurdmsg \ + errno-loc \ ++ sysvshm \ + $(sig) $(dtable) $(inlines) port-cleanup report-wait xattr + sig = hurdsig hurdfault siginfo hurd-raise preempt-sig \ + trampoline longjmp-ts catch-exc exc2signal hurdkill sigunwind \ +@@ -68,7 +69,7 @@ dtable = dtable port2fd new-fd alloc-fd intern-fd \ + getdport openport \ + fd-close fd-read fd-write hurdioctl ctty-input ctty-output + inlines = $(inline-headers:%.h=%-inlines) +-distribute = hurdstartup.h hurdfault.h hurdhost.h \ ++distribute = hurdstartup.h hurdfault.h hurdhost.h sysvshm.h \ + faultexc.defs intr-rpc.defs intr-rpc.h intr-msg.h Notes + + # XXX this is a temporary hack; see hurdmalloc.h +diff --git a/hurd/sysvshm.c b/hurd/sysvshm.c +new file mode 100644 +index 0000000..292cc01 +--- /dev/null ++++ b/hurd/sysvshm.c +@@ -0,0 +1,96 @@ ++/* Copyright (C) 2005 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. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++/* Description of an shm attachment. */ ++struct sysvshm_attach ++{ ++ /* Linked list. */ ++ struct sysvshm_attach *next; ++ ++ /* Map address. */ ++ void *addr; ++ ++ /* Map size. */ ++ size_t size; ++}; ++ ++/* List of attachments. */ ++static struct sysvshm_attach *attach_list; ++ ++/* A lock to protect the linked list of shared memory attachments. */ ++static struct mutex sysvshm_lock = MUTEX_INITIALIZER; ++ ++ ++/* Adds a segment attachment. */ ++error_t ++__sysvshm_add (void *addr, size_t size) ++{ ++ struct sysvshm_attach *shm; ++ ++ shm = malloc (sizeof (*shm)); ++ if (!shm) ++ return errno; ++ ++ __mutex_lock (&sysvshm_lock); ++ shm->addr = addr; ++ shm->size = size; ++ shm->next = attach_list; ++ attach_list = shm; ++ __mutex_unlock (&sysvshm_lock); ++ ++ return 0; ++} ++ ++/* Removes a segment attachment. Returns its size if found, or EINVAL ++ otherwise. */ ++error_t ++__sysvshm_remove (void *addr, size_t *size) ++{ ++ struct sysvshm_attach *shm; ++ struct sysvshm_attach **pshm = &attach_list; ++ ++ __mutex_lock (&sysvshm_lock); ++ shm = attach_list; ++ while (shm) ++ { ++ shm = *pshm; ++ if (shm->addr == addr) ++ { ++ *pshm = shm->next; ++ *size = shm->size; ++ __mutex_unlock (&sysvshm_lock); ++ return 0; ++ } ++ pshm = &shm->next; ++ shm = shm->next; ++ } ++ __mutex_unlock (&sysvshm_lock); ++ return EINVAL; ++} +diff --git a/hurd/sysvshm.h b/hurd/sysvshm.h +new file mode 100644 +index 0000000..0c561c8 +--- /dev/null ++++ b/hurd/sysvshm.h +@@ -0,0 +1,47 @@ ++/* Copyright (C) 2005 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. */ ++ ++#include ++#include ++ ++/* The area (from top to bottom) that is used for private keys. These ++ are all keys that have the second highest bit set. */ ++#define SHM_PRIV_KEY_START INT_MAX ++#define SHM_PRIV_KEY_END ((INT_MAX / 2) + 1) ++ ++#define SHM_PREFIX "shm-" ++#define SHM_DIR _PATH_DEV "shm/" ++ ++/* The maximum number of characters in a shared memory segment file name. ++ 32 is the max number of characters in a 128 bit number in hex. */ ++#if __WORDSIZE > 128 ++#error Need to increase SHM_NAMEMAX. ++#else ++#define SHM_NAMEMAX (sizeof (SHM_PREFIX) - 1 + 32 + 1) ++#endif ++ ++/* Use this with printf and its variants. */ ++#define SHM_NAMEPRI SHM_PREFIX "%0x" ++ ++ ++/* Adds a segment attachment. */ ++error_t __sysvshm_add (void *addr, size_t size); ++ ++/* Removes a segment attachment. Returns its size if found, or EINVAL ++ otherwise. */ ++error_t __sysvshm_remove (void *addr, size_t *size); +diff --git a/sysdeps/mach/hurd/ftok.c b/sysdeps/mach/hurd/ftok.c +new file mode 100644 +index 0000000..8d8b5cb +--- /dev/null ++++ b/sysdeps/mach/hurd/ftok.c +@@ -0,0 +1,43 @@ ++/* Copyright (C) 1995, 1996, 2000, 2005 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Ulrich Drepper , August 1995. ++ ++ 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. */ ++ ++#include ++#include ++ ++ ++/* In the Hurd, we use the second-to-most-significant bit as flag for ++ private keys. We use a different order of the components so that ++ the biggest one---the inode number---is affected by this. */ ++ ++key_t ++ftok (pathname, proj_id) ++ const char *pathname; ++ int proj_id; ++{ ++ struct stat64 st; ++ key_t key; ++ ++ if (__xstat64 (_STAT_VER, pathname, &st) < 0) ++ return (key_t) -1; ++ ++ key = ((st.st_dev & 0xff) | ((proj_id & 0xff) << 8) ++ | ((st.st_ino & 0x3fff) << 16)); ++ ++ return key; ++} +diff --git a/sysdeps/mach/hurd/shmat.c b/sysdeps/mach/hurd/shmat.c +new file mode 100644 +index 0000000..148a60c +--- /dev/null ++++ b/sysdeps/mach/hurd/shmat.c +@@ -0,0 +1,78 @@ ++/* Copyright (C) 2005 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. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "sysvshm.h" ++ ++/* Attach the shared memory segment associated with SHMID to the data ++ segment of the calling process. SHMADDR and SHMFLG determine how ++ and where the segment is attached. */ ++void * ++__shmat (int shmid, const void *shmaddr, int shmflg) ++{ ++ error_t err; ++ char filename[sizeof (SHM_DIR) - 1 + SHM_NAMEMAX]; ++ int fd; ++ void *addr; ++ struct stat statbuf; ++ int res; ++ ++ sprintf (filename, SHM_DIR SHM_NAMEPRI, shmid); ++ fd = __open (filename, (shmflg & SHM_RDONLY) ? O_RDONLY : O_RDWR); ++ if (fd < 0) ++ { ++ if (errno == ENOENT) ++ errno = EINVAL; ++ return (void *) -1; ++ } ++ ++ res = __fstat (fd, &statbuf); ++ if (res < 0) ++ { ++ __close (fd); ++ return (void *) -1; ++ } ++ ++ addr = __mmap ((void *) shmaddr, statbuf.st_size, ++ PROT_READ | ((shmflg & SHM_RDONLY) ? 0 : PROT_WRITE), ++ MAP_SHARED, fd, 0); ++ __close (fd); ++ if (addr == MAP_FAILED) ++ return (void *) -1; ++ ++ err = __sysvshm_add (addr, statbuf.st_size); ++ if (err) ++ { ++ munmap (addr, statbuf.st_size); ++ return (void *) -1; ++ } ++ ++ return addr; ++} ++ ++weak_alias(__shmat, shmat) +diff --git a/sysdeps/mach/hurd/shmctl.c b/sysdeps/mach/hurd/shmctl.c +new file mode 100644 +index 0000000..0d8eea6 +--- /dev/null ++++ b/sysdeps/mach/hurd/shmctl.c +@@ -0,0 +1,132 @@ ++/* Copyright (C) 2005 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. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "sysvshm.h" ++ ++/* Provide operations to control over shared memory segments. */ ++int ++__shmctl (int id, int cmd, struct shmid_ds *buf) ++{ ++ error_t err = 0; ++ int fd; ++ int res; ++ char filename[sizeof (SHM_DIR) - 1 + SHM_NAMEMAX]; ++ struct stat statbuf; ++ ++ sprintf (filename, SHM_DIR SHM_NAMEPRI, id); ++ /* SysV requires read access for IPC_STAT. */ ++ fd = __open (filename, O_NORW); ++ if (fd < 0) ++ { ++ if (errno == ENOENT) ++ errno = EINVAL; ++ return -1; ++ } ++ ++ res = __fstat (fd, &statbuf); ++ if (res < 0) ++ { ++ err = errno; ++ __close (fd); ++ errno = err; ++ return -1; ++ } ++ ++ switch (cmd) ++ { ++ case IPC_STAT: ++ ++ buf->shm_perm.__key = id; ++ buf->shm_perm.uid = statbuf.st_uid; ++ buf->shm_perm.gid = statbuf.st_gid; ++ ++ /* We do not support the creator. */ ++ buf->shm_perm.cuid = statbuf.st_uid; ++ buf->shm_perm.cgid = statbuf.st_gid; ++ ++ /* We just want the protection bits. */ ++ buf->shm_perm.mode = statbuf.st_mode & 0777; ++ /* Hopeless. We do not support a sequence number. */ ++ buf->shm_perm.__seq = statbuf.st_ino; ++ buf->shm_segsz = statbuf.st_size; ++ ++ /* Hopeless. We do not support any of these. */ ++ buf->shm_atime = statbuf.st_atime; ++ buf->shm_dtime = statbuf.st_mtime; ++ /* Well, this comes at least close. */ ++ buf->shm_ctime = statbuf.st_ctime; ++ ++ /* We do not support the PID. */ ++ buf->shm_cpid = 0; ++ buf->shm_lpid = 0; ++ ++ if (statbuf.st_mode & S_IMMAP0) ++ buf->shm_nattch = 0; ++ else ++ /* 42 is the answer. Of course this is bogus, but for most ++ applications, this should be fine. */ ++ buf->shm_nattch = 42; ++ ++ break; ++ ++ case IPC_SET: ++ if (statbuf.st_uid != buf->shm_perm.uid ++ || statbuf.st_gid != buf->shm_perm.gid) ++ { ++ res = __fchown (fd, ++ (statbuf.st_uid != buf->shm_perm.uid) ++ ? buf->shm_perm.uid : -1, ++ (statbuf.st_gid != buf->shm_perm.gid) ++ ? buf->shm_perm.gid : -1); ++ if (res < 0) ++ err = errno; ++ } ++ ++ if (!err && statbuf.st_mode & 0777 != buf->shm_perm.mode & 0777) ++ { ++ res = __fchmod (fd, (statbuf.st_mode & ~0777) ++ | (buf->shm_perm.mode & 0777)); ++ if (res < 0) ++ err = errno; ++ } ++ break; ++ ++ case IPC_RMID: ++ res = __unlink (filename); ++ /* FIXME: Check error (mapping ENOENT to EINVAL). */ ++ break; ++ ++ default: ++ err = EINVAL; ++ } ++ ++ __close (fd); ++ errno = err; ++ return err ? -1 : 0; ++} ++ ++weak_alias(__shmctl, shmctl) +diff --git a/sysdeps/mach/hurd/shmdt.c b/sysdeps/mach/hurd/shmdt.c +new file mode 100644 +index 0000000..cdafef0 +--- /dev/null ++++ b/sysdeps/mach/hurd/shmdt.c +@@ -0,0 +1,51 @@ ++/* Copyright (C) 2005 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. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "sysvshm.h" ++ ++/* Detach shared memory segment starting at address specified by ++ SHMADDR from the caller's data segment. */ ++int ++__shmdt (const void *shmaddr) ++{ ++ error_t err; ++ size_t size; ++ ++ err = __sysvshm_remove ((void *) shmaddr, &size); ++ if (err) ++ { ++ errno = err; ++ return -1; ++ } ++ ++ __munmap ((void *) shmaddr, size); ++ return 0; ++} ++ ++weak_alias(__shmdt, shmdt) +diff --git a/sysdeps/mach/hurd/shmget.c b/sysdeps/mach/hurd/shmget.c +new file mode 100644 +index 0000000..6620472 +--- /dev/null ++++ b/sysdeps/mach/hurd/shmget.c +@@ -0,0 +1,242 @@ ++/* Copyright (C) 2005 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. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include "sysvshm.h" ++ ++/* Create a new shared memory segment file without linking it into the ++ filesystem. Return the directory and file ports in R_DIR and R_FILE. */ ++static error_t ++create_shm_file (size_t size, int flags, file_t *r_dir, file_t *r_file) ++{ ++ error_t err; ++ file_t dir; ++ file_t file; ++ ++ flags &= 0777; ++ ++ /* Get a port to the directory that will contain the file. */ ++ dir = __file_name_lookup (SHM_DIR, 0, 0); ++ if (dir == MACH_PORT_NULL) ++ return errno; ++ ++ /* Create an unnamed file in the directory. */ ++ err = __dir_mkfile (dir, O_RDWR, flags, &file); ++ if (err) ++ { ++ __mach_port_deallocate (__mach_task_self (), dir); ++ return err; ++ } ++ ++ err = __file_set_size (file, size); ++ if (err) ++ { ++ __mach_port_deallocate (__mach_task_self (), file); ++ __mach_port_deallocate (__mach_task_self (), dir); ++ ++ return err; ++ } ++ ++ *r_dir = dir; ++ *r_file = file; ++ ++ return 0; ++} ++ ++ ++/* Open the shared memory segment *R_KEY and return a file descriptor ++ to it in R_FD. If KEY is IPC_PRIVATE, use a private key and return ++ it in R_KEY. */ ++static error_t ++get_exclusive (int shmflags, size_t size, key_t *r_key, int *r_fd) ++{ ++ error_t err; ++ file_t dir; ++ file_t file; ++ char filename[SHM_NAMEMAX]; ++ key_t key = *r_key; ++ bool is_private; ++ ++ /* Create the shared memory segment. */ ++ err = create_shm_file (size, shmflags, &dir, &file); ++ if (err) ++ return err; ++ ++ if (key == IPC_PRIVATE) ++ { ++ is_private = true; ++ key = SHM_PRIV_KEY_START; ++ ++ /* Try to link the shared memory segment into the filesystem ++ (exclusively). Private segments have negative keys. */ ++ do ++ { ++ sprintf (filename, SHM_NAMEPRI, key); ++ err = __dir_link (dir, file, filename, 1); ++ if (!err) ++ { ++ /* We are done. */ ++ *r_key = key; ++ break; ++ } ++ else if (err == EEXIST) ++ { ++ /* Check if we ran out of keys. If not, try again with new ++ key. */ ++ if (key == SHM_PRIV_KEY_END) ++ err = ENOSPC; ++ else ++ err = 0; ++ ++ key--; ++ } ++ } ++ while (!err); ++ } ++ else ++ { ++ /* Try to link the shared memory segment into the filesystem ++ (exclusively) under the given key. */ ++ sprintf (filename, SHM_NAMEPRI, key); ++ err = __dir_link (dir, file, filename, 1); ++ } ++ ++ __mach_port_deallocate (__mach_task_self (), dir); ++ ++ if (!err) ++ { ++ int fd; ++ ++ /* Get a file descriptor for that port. */ ++ fd = _hurd_intern_fd (file, O_RDWR, 1); /* dealloc on error */ ++ if (fd < 0) ++ err = errno; ++ else ++ *r_fd = fd; ++ } ++ ++ return err; ++} ++ ++ ++/* Open the shared memory segment KEY (creating it if it doesn't yet ++ exist) and return a file descriptor to it in R_FD. */ ++static error_t ++get_shared (int shmflags, size_t size, key_t key, int *r_fd) ++{ ++ error_t err = 0; ++ char filename[sizeof (SHM_DIR) - 1 + SHM_NAMEMAX]; ++ int fd = -1; ++ sprintf (filename, SHM_DIR SHM_NAMEPRI, key); ++ ++ do ++ { ++ fd = __open (filename, O_NORW, shmflags & 0777); ++ ++ if (fd < 0 && errno != ENOENT) ++ /* We give up. */ ++ return errno; ++ else if (fd >= 0) ++ { ++ int res; ++ struct stat statbuf; ++ ++ /* Check the size (we only need to do this if we did not ++ create the shared memory segment file ourselves). */ ++ res = __fstat (fd, &statbuf); ++ if (res < 0) ++ { ++ err = errno; ++ __close (fd); ++ return err; ++ } ++ ++ if (statbuf.st_size < size) ++ { ++ __close (fd); ++ return EINVAL; ++ } ++ } ++ else ++ { ++ /* The memory segment doesn't exist. */ ++ if (shmflags & IPC_CREAT) ++ { ++ /* Try to create it exclusively. */ ++ err = get_exclusive (shmflags, size, &key, &fd); ++ if (err == EEXIST) ++ /* If somebody created it in the meanwhile, just try again. */ ++ err = 0; ++ } ++ else ++ err = ENOENT; ++ } ++ } ++ while (fd < 0 && !err); ++ ++ if (!err) ++ *r_fd = fd; ++ else ++ *r_fd = -1; ++ ++ return err; ++} ++ ++/* Return an identifier for an shared memory segment of at least size ++ SIZE which is associated with KEY. */ ++int ++__shmget (key_t key, size_t size, int shmflags) ++{ ++ error_t err; ++ int fd; ++ ++ if (key == IPC_PRIVATE || shmflags & IPC_EXCL) ++ /* An exclusive shared memory segment must be created. */ ++ err = get_exclusive (shmflags, size, &key, &fd); ++ else ++ err = get_shared (shmflags, size, key, &fd); ++ ++ if (err) ++ { ++ errno = err; ++ return -1; ++ } ++ ++ /* From here, we can't fail. That's important, as otherwise we ++ would need to unlink the file if we created it (in that case, the ++ code above would have to be changed to pass a "created" flag down ++ to the caller). */ ++ ++ __close (fd); ++ ++ return key; ++} ++ ++weak_alias(__shmget, shmget) +diff --git a/sysdeps/mach/hurd/bits/posix_opt.h b/sysdeps/mach/hurd/bits/posix_opt.h +index 775c921..e25ceb5 100644 +--- a/sysdeps/mach/hurd/bits/posix_opt.h ++++ b/sysdeps/mach/hurd/bits/posix_opt.h +@@ -60,8 +60,8 @@ + /* X/Open thread realtime support is not supported. */ + #undef _XOPEN_REALTIME_THREADS + +-/* XPG4.2 shared memory is not supported. */ +-#undef _XOPEN_SHM ++/* XPG4.2 shared memory is supported. */ ++#define _XOPEN_SHM 1 + + /* We do not have the POSIX threads interface. */ + #define _POSIX_THREADS -1 +-- +tg: (0234227..) t/sysvshm (depends on: baseline) only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/hurd-i386/tg-no-hp-timing.diff +++ eglibc-2.15/debian/patches/hurd-i386/tg-no-hp-timing.diff @@ -0,0 +1,62 @@ +From: Samuel Thibault +Subject: [PATCH] No hp timing + +2010-08-21 Samuel Thibault + +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 , 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) only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/hurd-i386/tg-sbrk.diff +++ eglibc-2.15/debian/patches/hurd-i386/tg-sbrk.diff @@ -0,0 +1,60 @@ +From: Samuel Thibault +Subject: [PATCH] Fix sbrk beyond 128MB + +The patch below fixes sbrk() calls beyond the initial allocation of +128MB: passing pagebrk makes the kernel return an error when there is +some room (but not enough for the desired increase) between pagebrk and +_hurd_data_end where vm is already allocated. + +2009-09-14 Samuel Thibault + + * sysdeps/mach/hurd/brk.c (_hurd_set_brk): When more space needs to be + allocated, call __vm_protect to finish enabling the existing space, and + pass a copy of _hurd_data_end instead of pagebrk to __vm_allocate to + allocate the remainder. + +--- +http://sources.redhat.com/ml/libc-alpha/2009-09/msg00030.html + + sysdeps/mach/hurd/brk.c | 18 ++++++++++++++++-- + 1 files changed, 16 insertions(+), 2 deletions(-) + +diff --git a/sysdeps/mach/hurd/brk.c b/sysdeps/mach/hurd/brk.c +index 931b260..4a135d3 100644 +--- a/sysdeps/mach/hurd/brk.c ++++ b/sysdeps/mach/hurd/brk.c +@@ -64,7 +64,7 @@ weak_alias (__brk, brk) + int + _hurd_set_brk (vm_address_t addr) + { +- error_t err; ++ error_t err = 0; + vm_address_t pagend = round_page (addr); + vm_address_t pagebrk = round_page (_hurd_brk); + long int rlimit; +@@ -101,8 +101,22 @@ _hurd_set_brk (vm_address_t addr) + + if (pagend > _hurd_data_end) + { ++ vm_address_t alloc_start = _hurd_data_end; ++ + /* We didn't allocate enough space! Hopefully we can get some more! */ +- err = __vm_allocate (__mach_task_self (), &pagebrk, pagend - pagebrk, 0); ++ ++ if (_hurd_data_end > pagebrk) ++ /* First finish allocation */ ++ err = __vm_protect (__mach_task_self (), pagebrk, ++ alloc_start - pagebrk, 0, ++ VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); ++ if (! err) ++ _hurd_brk = alloc_start; ++ ++ if (! err) ++ err = __vm_allocate (__mach_task_self (), &alloc_start, ++ pagend - alloc_start, 0); ++ + if (! err) + _hurd_data_end = pagend; + } +-- +tg: (0234227..) t/sbrk (depends on: baseline) only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/hurd-i386/tg-critical-sections.diff +++ eglibc-2.15/debian/patches/hurd-i386/tg-critical-sections.diff @@ -0,0 +1,80 @@ +From: Samuel Thibault +Subject: [PATCH] Missing critical region locks. + +2009-01-12 Samuel Thibault + + * hurd/hurd/fd.h (_hurd_fd_get): Call HURD_CRITICAL_BEGIN/ + HURD_CRITICAL_END around holding _hurd_dtable_lock. + * sysdeps/mach/hurd/dirfd (dirfd): Likewise. + * sysdeps/mach/hurd/opendir.c (_hurd_fd_opendir): Call + HURD_CRITICAL_BEGIN/HURD_CRITICAL_END around holding + d->port.lock. + +--- + +http://sources.redhat.com/ml/libc-alpha/2009-01/msg00030.html + + hurd/hurd/fd.h | 2 ++ + sysdeps/mach/hurd/dirfd.c | 3 +++ + sysdeps/mach/hurd/opendir.c | 2 ++ + 3 files changed, 7 insertions(+), 0 deletions(-) + +diff --git a/hurd/hurd/fd.h b/hurd/hurd/fd.h +index 2473476..e1b1a5d 100644 +--- a/hurd/hurd/fd.h ++++ b/hurd/hurd/fd.h +@@ -65,6 +65,7 @@ _hurd_fd_get (int fd) + { + struct hurd_fd *descriptor; + ++ HURD_CRITICAL_BEGIN; + __mutex_lock (&_hurd_dtable_lock); + if (fd < 0 || fd >= _hurd_dtablesize) + descriptor = NULL; +@@ -87,6 +88,7 @@ _hurd_fd_get (int fd) + } + } + __mutex_unlock (&_hurd_dtable_lock); ++ HURD_CRITICAL_END; + + return descriptor; + } +diff --git a/sysdeps/mach/hurd/dirfd.c b/sysdeps/mach/hurd/dirfd.c +index fde13fa..be2a6a9 100644 +--- a/sysdeps/mach/hurd/dirfd.c ++++ b/sysdeps/mach/hurd/dirfd.c +@@ -26,6 +26,8 @@ int + dirfd (DIR *dirp) + { + int fd; ++ ++ HURD_CRITICAL_BEGIN; + __mutex_lock (&_hurd_dtable_lock); + for (fd = 0; fd < _hurd_dtablesize; ++fd) + if (_hurd_dtable[fd] == dirp->__fd) +@@ -36,6 +38,7 @@ dirfd (DIR *dirp) + fd = -1; + } + __mutex_unlock (&_hurd_dtable_lock); ++ HURD_CRITICAL_END; + + return fd; + } +diff --git a/sysdeps/mach/hurd/opendir.c b/sysdeps/mach/hurd/opendir.c +index 23e04ed..3a1b48e 100644 +--- a/sysdeps/mach/hurd/opendir.c ++++ b/sysdeps/mach/hurd/opendir.c +@@ -51,9 +51,11 @@ _hurd_fd_opendir (struct hurd_fd *d) + return NULL; + + /* Set the descriptor to close on exec. */ ++ HURD_CRITICAL_BEGIN; + __spin_lock (&d->port.lock); + d->flags |= FD_CLOEXEC; + __spin_unlock (&d->port.lock); ++ HURD_CRITICAL_END; + + dirp->__fd = d; + dirp->__data = dirp->__ptr = NULL; +-- +tg: (0234227..) t/critical-sections (depends on: baseline) only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/hurd-i386/tg-unwind-resume.diff +++ eglibc-2.15/debian/patches/hurd-i386/tg-unwind-resume.diff @@ -0,0 +1,108 @@ +Subject: [PATCH] Unwind resume support + +--- + sysdeps/mach/hurd/Makefile | 12 ++++++ + sysdeps/mach/hurd/rt-unwind-resume.c | 1 + + sysdeps/mach/hurd/unwind-resume.c | 64 ++++++++++++++++++++++++++++++++++ + 3 files changed, 77 insertions(+), 0 deletions(-) + +diff --git a/sysdeps/mach/hurd/rt-unwind-resume.c b/sysdeps/mach/hurd/rt-unwind-resume.c +new file mode 100644 +index 0000000..743e675 +--- /dev/null ++++ b/sysdeps/mach/hurd/rt-unwind-resume.c +@@ -0,0 +1 @@ ++#include +diff --git a/sysdeps/mach/hurd/unwind-resume.c b/sysdeps/mach/hurd/unwind-resume.c +new file mode 100644 +index 0000000..088f4c6 +--- /dev/null ++++ b/sysdeps/mach/hurd/unwind-resume.c +@@ -0,0 +1,64 @@ ++/* Copyright (C) 2003 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Jakub Jelinek . ++ ++ 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; see the file COPYING.LIB. If not, ++ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ++ Boston, MA 02111-1307, USA. */ ++ ++#include ++#include ++#include ++ ++static void (*libgcc_s_resume) (struct _Unwind_Exception *exc); ++static _Unwind_Reason_Code (*libgcc_s_personality) ++ (int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *, ++ struct _Unwind_Context *); ++ ++static void ++init (void) ++{ ++ void *resume, *personality; ++ void *handle; ++ ++ handle = __libc_dlopen ("libgcc_s.so.1"); ++ ++ if (handle == NULL ++ || (resume = __libc_dlsym (handle, "_Unwind_Resume")) == NULL ++ || (personality = __libc_dlsym (handle, "__gcc_personality_v0")) == NULL) ++ __libc_fatal ("libgcc_s.so.1 must be installed for pthread_cancel to work\n"); ++ ++ libgcc_s_resume = resume; ++ libgcc_s_personality = personality; ++} ++ ++void ++_Unwind_Resume (struct _Unwind_Exception *exc) ++{ ++ if (__builtin_expect (libgcc_s_resume == NULL, 0)) ++ init (); ++ libgcc_s_resume (exc); ++} ++ ++_Unwind_Reason_Code ++__gcc_personality_v0 (int version, _Unwind_Action actions, ++ _Unwind_Exception_Class exception_class, ++ struct _Unwind_Exception *ue_header, ++ struct _Unwind_Context *context) ++{ ++ if (__builtin_expect (libgcc_s_personality == NULL, 0)) ++ init (); ++ return libgcc_s_personality (version, actions, exception_class, ++ ue_header, context); ++} +diff --git a/sysdeps/mach/hurd/Makefile b/sysdeps/mach/hurd/Makefile +index 93058ff..c0b1400 100644 +--- a/sysdeps/mach/hurd/Makefile ++++ b/sysdeps/mach/hurd/Makefile +@@ -207,4 +207,16 @@ sysdep_headers += net/ethernet.h net/if_arp.h net/if_ether.h net/if_ppp.h \ + net/route.h + endif + ++ifeq ($(subdir),csu) ++routines += unwind-resume ++shared-only-routines += unwind-resume ++CFLAGS-unwind-resume.c += -fexceptions -fasynchronous-unwind-tables ++endif ++ ++ifeq ($(subdir),rt) ++librt-sysdep_routines += rt-unwind-resume ++librt-shared-only-routines += rt-unwind-resume ++CFLAGS-rt-unwind-resume.c += -fexceptions -fasynchronous-unwind-tables ++endif ++ + endif # in-Makerules +-- +tg: (0234227..) t/unwind-resume (depends on: baseline) only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/hurd-i386/tg-mkdir_root.diff +++ eglibc-2.15/debian/patches/hurd-i386/tg-mkdir_root.diff @@ -0,0 +1,64 @@ +From: Samuel Thibault +Subject: [PATCH] Fix mkdir / error value + +(needed for busybox's mkdir -p) + +In the / case, directory_name_split can't really split that into an +absolute ROOT file_t and ".", since name is supposed to be a pointer in +file_name... Changing the interface is being proposed. + +--- + sysdeps/mach/hurd/mkdir.c | 6 +++++- + sysdeps/mach/hurd/mkdirat.c | 6 +++++- + 2 files changed, 10 insertions(+), 2 deletions(-) + +diff --git a/sysdeps/mach/hurd/mkdir.c b/sysdeps/mach/hurd/mkdir.c +index b7e8074..cf6dda3 100644 +--- a/sysdeps/mach/hurd/mkdir.c ++++ b/sysdeps/mach/hurd/mkdir.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + + /* Create a directory named FILE_NAME with protections MODE. */ + int +@@ -29,7 +30,10 @@ __mkdir (file_name, mode) + { + error_t err; + const char *name; +- file_t parent = __directory_name_split (file_name, (char **) &name); ++ file_t parent; ++ if (!strcmp(file_name, "/")) ++ return EEXIST; ++ parent = __directory_name_split (file_name, (char **) &name); + if (parent == MACH_PORT_NULL) + return -1; + err = __dir_mkdir (parent, name, mode & ~_hurd_umask); +diff --git a/sysdeps/mach/hurd/mkdirat.c b/sysdeps/mach/hurd/mkdirat.c +index a300745..8256ef8 100644 +--- a/sysdeps/mach/hurd/mkdirat.c ++++ b/sysdeps/mach/hurd/mkdirat.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + int + mkdirat (fd, path, mode) +@@ -32,7 +33,10 @@ mkdirat (fd, path, mode) + { + error_t err; + const char *name; +- file_t parent = __directory_name_split_at (fd, path, (char **) &name); ++ file_t parent; ++ if (!strcmp(path, "/")) ++ return EEXIST; ++ parent = __directory_name_split_at (fd, path, (char **) &name); + if (parent == MACH_PORT_NULL) + return -1; + err = __dir_mkdir (parent, name, mode & ~_hurd_umask); +-- +tg: (0234227..) t/mkdir_root (depends on: baseline) only in patch2: unchanged: --- eglibc-2.15.orig/debian/patches/sparc/cvs-fcntl_h.diff +++ eglibc-2.15/debian/patches/sparc/cvs-fcntl_h.diff @@ -0,0 +1,17 @@ +2012-02-16 David S. Miller + + [BZ #11494] + * sysdeps/unix/sysv/linux/sparc/bits/fcntl.h (O_FSYNC): Define. + +diff --git a/sysdeps/unix/sysv/linux/sparc/bits/fcntl.h b/sysdeps/unix/sysv/linux/sparc/bits/fcntl.h +index 7f6c8cd..7ce09da 100644 +--- a/sysdeps/unix/sysv/linux/sparc/bits/fcntl.h ++++ b/sysdeps/unix/sysv/linux/sparc/bits/fcntl.h +@@ -39,6 +39,7 @@ + #define O_TRUNC 0x0400 /* not fcntl */ + #define O_EXCL 0x0800 /* not fcntl */ + #define O_SYNC 0x802000 ++#define O_FSYNC O_SYNC + #define O_NONBLOCK 0x4000 + #define O_NDELAY (0x0004 | O_NONBLOCK) + #define O_NOCTTY 0x8000 /* not fcntl */