summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWaldemar Brodkorb <wbx@uclibc-ng.org>2017-11-22 21:30:24 +0100
committerWaldemar Brodkorb <wbx@uclibc-ng.org>2017-11-22 21:31:41 +0100
commit71b3a63b641716165f664cf112be0673a122cea0 (patch)
treee8350273c4889d1067e2eb4824dfaa0358604a6d
parent2fcffe26e815b7125a357c83b59617ab93c16b41 (diff)
librt: fix broken posix_spawn
Fix iteration over signals, synced with GNU C library code and pending patches. Issues found when running dhcpcd with hook scripts. (exit status 127) Reported-By: kapeka <kapeka@bering-uclibc.de>
-rw-r--r--libc/sysdeps/linux/common/internal-signals.h (renamed from libpthread/nptl/sysdeps/unix/sysv/linux/nptl-signals.h)21
-rw-r--r--libpthread/nptl/pthreadP.h3
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/raise.c3
-rw-r--r--librt/spawn.c32
4 files changed, 36 insertions, 23 deletions
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/nptl-signals.h b/libc/sysdeps/linux/common/internal-signals.h
index 43aa1a939..65e8de34b 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/nptl-signals.h
+++ b/libc/sysdeps/linux/common/internal-signals.h
@@ -1,6 +1,4 @@
-/* Special use of signals in NPTL internals. Linux version.
- Copyright (C) 2014-2017 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
+/* Copyright (C) 2014-2017 Free Software Foundation, Inc.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -21,27 +19,24 @@
/* The signal used for asynchronous cancelation. */
#define SIGCANCEL __SIGRTMIN
-
/* Signal needed for the kernel-supported POSIX timer implementation.
We can reuse the cancellation signal since we can distinguish
cancellation from timer expirations. */
#define SIGTIMER SIGCANCEL
-
/* Signal used to implement the setuid et.al. functions. */
#define SIGSETXID (__SIGRTMIN + 1)
-
-/* Return is sig is used internally. */
+/* Return if sig is used internally. */
static inline int
-__nptl_is_internal_signal (int sig)
+__is_internal_signal (int sig)
{
return (sig == SIGCANCEL) || (sig == SIGTIMER) || (sig == SIGSETXID);
}
-/* Remove internal glibc signal from the mask. */
+/* Remove internal signal from the mask. */
static inline void
-__nptl_clear_internal_signals (sigset_t *set)
+__clear_internal_signals (sigset_t *set)
{
__sigdelset (set, SIGCANCEL);
__sigdelset (set, SIGTIMER);
@@ -51,7 +46,7 @@ __nptl_clear_internal_signals (sigset_t *set)
#define SIGALL_SET \
((__sigset_t) { .__val = {[0 ... _SIGSET_NWORDS-1 ] = -1 } })
-/* Block all signals, including internal glibc ones. */
+/* Block all signals, including internal ones. */
static inline int
__libc_signal_block_all (sigset_t *set)
{
@@ -60,12 +55,12 @@ __libc_signal_block_all (sigset_t *set)
set, _NSIG / 8);
}
-/* Block all application signals (excluding internal glibc ones). */
+/* Block all application signals (excluding internal ones). */
static inline int
__libc_signal_block_app (sigset_t *set)
{
sigset_t allset = SIGALL_SET;
- __nptl_clear_internal_signals (&allset);
+ __clear_internal_signals (&allset);
INTERNAL_SYSCALL_DECL (err);
return INTERNAL_SYSCALL (rt_sigprocmask, err, 4, SIG_BLOCK, &allset, set,
_NSIG / 8);
diff --git a/libpthread/nptl/pthreadP.h b/libpthread/nptl/pthreadP.h
index 4707f6548..13205512a 100644
--- a/libpthread/nptl/pthreadP.h
+++ b/libpthread/nptl/pthreadP.h
@@ -1,5 +1,4 @@
/* Copyright (C) 2002-2007, 2009 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
The GNU C Library is free software; you can redistribute it and/or
@@ -31,7 +30,7 @@
#include <atomic.h>
#include <bits/kernel-features.h>
#include <errno.h>
-#include <nptl-signals.h>
+#include <internal-signals.h>
/* Atomic operations on TLS memory. */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/raise.c b/libpthread/nptl/sysdeps/unix/sysv/linux/raise.c
index f74cd0be3..c0f6e277b 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/raise.c
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/raise.c
@@ -1,5 +1,4 @@
/* Copyright (C) 2002-2016 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
The GNU C Library is free software; you can redistribute it and/or
@@ -20,7 +19,7 @@
#include <limits.h>
#include <signal.h>
#include <sysdep.h>
-#include <nptl-signals.h>
+#include <internal-signals.h>
int
raise (int sig)
diff --git a/librt/spawn.c b/librt/spawn.c
index 25e3994e1..a2b8e061b 100644
--- a/librt/spawn.c
+++ b/librt/spawn.c
@@ -25,6 +25,7 @@
#include <sys/resource.h>
#include <not-cancel.h>
+#include <internal-signals.h>
#include <spawn.h>
#include "spawn_int.h"
@@ -153,13 +154,32 @@ __spawni(pid_t *pid, const char *file,
int sig;
memset(&sa, 0, sizeof(sa));
- sa.sa_handler = SIG_DFL;
- for (sig = 1; sig <= _NSIG; ++sig) {
- if (sigismember(&attrp->__sd, sig)) {
- if (sigaction(sig, &sa, NULL) != 0)
- goto error;
- }
+ sigset_t hset;
+ sigprocmask (SIG_BLOCK, 0, &hset);
+
+ for (int sig = 1; sig < _NSIG; ++sig) {
+ if ((flags & POSIX_SPAWN_SETSIGDEF)
+ && sigismember (&attrp->__sd, sig))
+ {
+ sa.sa_handler = SIG_DFL;
+ }
+ else if (sigismember (&hset, sig))
+ {
+ if (__is_internal_signal (sig))
+ sa.sa_handler = SIG_IGN;
+ else
+ {
+ __libc_sigaction (sig, 0, &sa);
+ if (sa.sa_handler == SIG_IGN)
+ continue;
+ sa.sa_handler = SIG_DFL;
+ }
+ }
+ else
+ continue;
+
+ __libc_sigaction (sig, &sa, 0);
}
}