aboutsummaryrefslogtreecommitdiff
path: root/nptl
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2019-10-18 14:29:04 +0200
committerFlorian Weimer <fweimer@redhat.com>2019-10-18 14:29:04 +0200
commite4b3707cea0eae2cf46a82534dd9279541e7415a (patch)
treec2246b8c9cf4f12e0de4e3cd050f15a751402fb3 /nptl
parent5e20aae5ee087f394f276bd556c5c1df52d76ff9 (diff)
downloadglibc-e4b3707cea0eae2cf46a82534dd9279541e7415a.zip
glibc-e4b3707cea0eae2cf46a82534dd9279541e7415a.tar.gz
glibc-e4b3707cea0eae2cf46a82534dd9279541e7415a.tar.bz2
nptl: SIGCANCEL, SIGTIMER, SIGSETXID are always defined
All nptl targets have these signal definitions nowadays. This changes also replaces the nptl-generic version of pthread_sigmask with the Linux version. Tested on x86_64-linux-gnu and i686-linux-gnu. Built with build-many-glibcs.py. Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Diffstat (limited to 'nptl')
-rw-r--r--nptl/allocatestack.c3
-rw-r--r--nptl/nptl-init.c16
-rw-r--r--nptl/pthread_cancel.c7
-rw-r--r--nptl/pthread_create.c2
-rw-r--r--nptl/pthread_setcanceltype.c5
-rw-r--r--nptl/pthread_sigmask.c40
-rw-r--r--nptl/tst-cancel25.c2
-rw-r--r--nptl/tst-signal7.c4
8 files changed, 29 insertions, 50 deletions
diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
index 64a9ae6..086efb7 100644
--- a/nptl/allocatestack.c
+++ b/nptl/allocatestack.c
@@ -963,7 +963,6 @@ __reclaim_stacks (void)
}
-#ifdef SIGSETXID
static void
setxid_mark_thread (struct xid_command *cmdp, struct pthread *t)
{
@@ -1174,8 +1173,6 @@ __nptl_setxid (struct xid_command *cmdp)
lll_unlock (stack_cache_lock, LLL_PRIVATE);
return result;
}
-#endif /* SIGSETXID. */
-
static inline void __attribute__((always_inline))
init_one_static_tls (struct pthread *curp, struct link_map *map)
diff --git a/nptl/nptl-init.c b/nptl/nptl-init.c
index ea91b9e..acc0f36 100644
--- a/nptl/nptl-init.c
+++ b/nptl/nptl-init.c
@@ -114,9 +114,7 @@ static const struct pthread_functions pthread_functions =
.ptr_nthreads = &__nptl_nthreads,
.ptr___pthread_unwind = &__pthread_unwind,
.ptr__nptl_deallocate_tsd = __nptl_deallocate_tsd,
-# ifdef SIGSETXID
.ptr__nptl_setxid = __nptl_setxid,
-# endif
.ptr_set_robust = __nptl_set_robust
};
# define ptr_pthread_functions &pthread_functions
@@ -139,7 +137,6 @@ __nptl_set_robust (struct pthread *self)
}
-#ifdef SIGCANCEL
/* For asynchronous cancellation we use a signal. This is the handler. */
static void
sigcancel_handler (int sig, siginfo_t *si, void *ctx)
@@ -185,10 +182,8 @@ sigcancel_handler (int sig, siginfo_t *si, void *ctx)
oldval = curval;
}
}
-#endif
-#ifdef SIGSETXID
struct xid_command *__xidcmd attribute_hidden;
/* We use the SIGSETXID signal in the setuid, setgid, etc. implementations to
@@ -234,7 +229,6 @@ sighandler_setxid (int sig, siginfo_t *si, void *ctx)
if (atomic_decrement_val (&__xidcmd->cntr) == 0)
futex_wake ((unsigned int *) &__xidcmd->cntr, 1, FUTEX_PRIVATE);
}
-#endif
/* When using __thread for this, we do it in libc so as not
@@ -285,41 +279,31 @@ __pthread_initialize_minimal_internal (void)
had to set __nptl_initial_report_events. Propagate its setting. */
THREAD_SETMEM (pd, report_events, __nptl_initial_report_events);
-#if defined SIGCANCEL || defined SIGSETXID
struct sigaction sa;
__sigemptyset (&sa.sa_mask);
-# ifdef SIGCANCEL
/* Install the cancellation signal handler. If for some reason we
cannot install the handler we do not abort. Maybe we should, but
it is only asynchronous cancellation which is affected. */
sa.sa_sigaction = sigcancel_handler;
sa.sa_flags = SA_SIGINFO;
(void) __libc_sigaction (SIGCANCEL, &sa, NULL);
-# endif
-# ifdef SIGSETXID
/* Install the handle to change the threads' uid/gid. */
sa.sa_sigaction = sighandler_setxid;
sa.sa_flags = SA_SIGINFO | SA_RESTART;
(void) __libc_sigaction (SIGSETXID, &sa, NULL);
-# endif
/* The parent process might have left the signals blocked. Just in
case, unblock it. We reuse the signal mask in the sigaction
structure. It is already cleared. */
-# ifdef SIGCANCEL
__sigaddset (&sa.sa_mask, SIGCANCEL);
-# endif
-# ifdef SIGSETXID
__sigaddset (&sa.sa_mask, SIGSETXID);
-# endif
{
INTERNAL_SYSCALL_DECL (err);
(void) INTERNAL_SYSCALL (rt_sigprocmask, err, 4, SIG_UNBLOCK, &sa.sa_mask,
NULL, _NSIG / 8);
}
-#endif
/* Get the size of the static and alignment requirements for the TLS
block. */
diff --git a/nptl/pthread_cancel.c b/nptl/pthread_cancel.c
index 64ac12e..f6be8c1 100644
--- a/nptl/pthread_cancel.c
+++ b/nptl/pthread_cancel.c
@@ -63,7 +63,6 @@ __pthread_cancel (pthread_t th)
oldval))
goto again;
-#ifdef SIGCANCEL
/* The cancellation handler will take care of marking the
thread as canceled. */
pid_t pid = __getpid ();
@@ -73,12 +72,6 @@ __pthread_cancel (pthread_t th)
SIGCANCEL);
if (INTERNAL_SYSCALL_ERROR_P (val, err))
result = INTERNAL_SYSCALL_ERRNO (val, err);
-#else
- /* It should be impossible to get here at all, since
- pthread_setcanceltype should never have allowed
- PTHREAD_CANCEL_ASYNCHRONOUS to be set. */
- abort ();
-#endif
break;
}
diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
index 130937c..5682c9c 100644
--- a/nptl/pthread_create.c
+++ b/nptl/pthread_create.c
@@ -402,7 +402,6 @@ START_THREAD_DEFN
}
#endif
-#ifdef SIGCANCEL
/* If the parent was running cancellation handlers while creating
the thread the new thread inherited the signal mask. Reset the
cancellation signal mask. */
@@ -415,7 +414,6 @@ START_THREAD_DEFN
(void) INTERNAL_SYSCALL (rt_sigprocmask, err, 4, SIG_UNBLOCK, &mask,
NULL, _NSIG / 8);
}
-#endif
/* This is where the try/finally block should be created. For
compilers without that support we do use setjmp. */
diff --git a/nptl/pthread_setcanceltype.c b/nptl/pthread_setcanceltype.c
index d771c31..99bc13e 100644
--- a/nptl/pthread_setcanceltype.c
+++ b/nptl/pthread_setcanceltype.c
@@ -27,11 +27,6 @@ __pthread_setcanceltype (int type, int *oldtype)
if (type < PTHREAD_CANCEL_DEFERRED || type > PTHREAD_CANCEL_ASYNCHRONOUS)
return EINVAL;
-#ifndef SIGCANCEL
- if (type == PTHREAD_CANCEL_ASYNCHRONOUS)
- return ENOTSUP;
-#endif
-
volatile struct pthread *self = THREAD_SELF;
int oldval = THREAD_GETMEM (self, cancelhandling);
diff --git a/nptl/pthread_sigmask.c b/nptl/pthread_sigmask.c
index c8df527..4aa774d 100644
--- a/nptl/pthread_sigmask.c
+++ b/nptl/pthread_sigmask.c
@@ -1,6 +1,6 @@
-/* Examine and change blocked signals for a thread. Generic POSIX version.
- Copyright (C) 2014-2019 Free Software Foundation, Inc.
+/* Copyright (C) 2002-2019 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
modify it under the terms of the GNU Lesser General Public
@@ -19,18 +19,36 @@
#include <errno.h>
#include <signal.h>
#include <pthreadP.h>
+#include <sysdep.h>
-#if defined SIGCANCEL || defined SIGTIMER || defined SIGSETXID
-# error "This implementation assumes no internal-only signal numbers."
-#endif
int
pthread_sigmask (int how, const sigset_t *newmask, sigset_t *oldmask)
{
- /* Here we assume that sigprocmask actually does everything right.
- The only difference is the return value protocol. */
- int result = sigprocmask (how, newmask, oldmask);
- if (result < 0)
- result = errno;
- return result;
+ sigset_t local_newmask;
+
+ /* The only thing we have to make sure here is that SIGCANCEL and
+ SIGSETXID is not blocked. */
+ if (newmask != NULL
+ && (__builtin_expect (__sigismember (newmask, SIGCANCEL), 0)
+ || __builtin_expect (__sigismember (newmask, SIGSETXID), 0)))
+ {
+ local_newmask = *newmask;
+ __sigdelset (&local_newmask, SIGCANCEL);
+ __sigdelset (&local_newmask, SIGSETXID);
+ newmask = &local_newmask;
+ }
+
+#ifdef INTERNAL_SYSCALL
+ /* We know that realtime signals are available if NPTL is used. */
+ INTERNAL_SYSCALL_DECL (err);
+ int result = INTERNAL_SYSCALL (rt_sigprocmask, err, 4, how, newmask,
+ oldmask, _NSIG / 8);
+
+ return (INTERNAL_SYSCALL_ERROR_P (result, err)
+ ? INTERNAL_SYSCALL_ERRNO (result, err)
+ : 0);
+#else
+ return sigprocmask (how, newmask, oldmask) == -1 ? errno : 0;
+#endif
}
diff --git a/nptl/tst-cancel25.c b/nptl/tst-cancel25.c
index 24ddd3c..c6e1c23 100644
--- a/nptl/tst-cancel25.c
+++ b/nptl/tst-cancel25.c
@@ -12,7 +12,6 @@ static pthread_t th2;
static void *
tf2 (void *arg)
{
-#ifdef SIGCANCEL
sigset_t mask;
if (pthread_sigmask (SIG_SETMASK, NULL, &mask) != 0)
{
@@ -24,7 +23,6 @@ tf2 (void *arg)
puts ("SIGCANCEL blocked in new thread");
exit (1);
}
-#endif
/* Sync with the main thread so that we do not test anything else. */
int e = pthread_barrier_wait (&b);
diff --git a/nptl/tst-signal7.c b/nptl/tst-signal7.c
index de67ab4..f42ff68 100644
--- a/nptl/tst-signal7.c
+++ b/nptl/tst-signal7.c
@@ -27,7 +27,6 @@ do_test (void)
{
int result = 0;
-#ifdef SIGCANCEL
errno = 0;
if (sigaction (SIGCANCEL, NULL, NULL) == 0)
{
@@ -39,9 +38,7 @@ do_test (void)
puts ("sigaction(SIGCANCEL) did not set errno to EINVAL");
result = 1;
}
-#endif
-#ifdef SIGSETXID
errno = 0;
if (sigaction (SIGSETXID, NULL, NULL) == 0)
{
@@ -53,7 +50,6 @@ do_test (void)
puts ("sigaction(SIGSETXID) did not set errno to EINVAL");
result = 1;
}
-#endif
return result;
}