mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-28 00:21:52 +03:00
linux: Use pthread_sigmask on sigprocmask
With pthread_sigmask on libc.so, it allows implement sigprocmask on top of pthread_sigmask. Checked on x86_64-linux-gnu.
This commit is contained in:
@ -482,6 +482,8 @@ extern void __pthread_testcancel (void);
|
|||||||
extern int __pthread_clockjoin_ex (pthread_t, void **, clockid_t,
|
extern int __pthread_clockjoin_ex (pthread_t, void **, clockid_t,
|
||||||
const struct timespec *, bool)
|
const struct timespec *, bool)
|
||||||
attribute_hidden;
|
attribute_hidden;
|
||||||
|
extern int __pthread_sigmask (int, const sigset_t *, sigset_t *);
|
||||||
|
libc_hidden_proto (__pthread_sigmask);
|
||||||
|
|
||||||
|
|
||||||
#if IS_IN (libpthread)
|
#if IS_IN (libpthread)
|
||||||
|
@ -46,6 +46,7 @@ __pthread_sigmask (int how, const sigset_t *newmask, sigset_t *oldmask)
|
|||||||
? INTERNAL_SYSCALL_ERRNO (result)
|
? INTERNAL_SYSCALL_ERRNO (result)
|
||||||
: 0);
|
: 0);
|
||||||
}
|
}
|
||||||
|
libc_hidden_def (__pthread_sigmask)
|
||||||
|
|
||||||
versioned_symbol (libc, __pthread_sigmask, pthread_sigmask, GLIBC_2_32);
|
versioned_symbol (libc, __pthread_sigmask, pthread_sigmask, GLIBC_2_32);
|
||||||
#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_32)
|
#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_32)
|
||||||
|
@ -22,21 +22,11 @@
|
|||||||
int
|
int
|
||||||
__sigprocmask (int how, const sigset_t *set, sigset_t *oset)
|
__sigprocmask (int how, const sigset_t *set, sigset_t *oset)
|
||||||
{
|
{
|
||||||
sigset_t local_newmask;
|
int result = __pthread_sigmask (how, set, oset);
|
||||||
|
if (result == 0)
|
||||||
/* The only thing we have to make sure here is that SIGCANCEL and
|
return 0;
|
||||||
SIGSETXID are not blocked. */
|
__set_errno (result);
|
||||||
if (set != NULL
|
return -1;
|
||||||
&& __glibc_unlikely (__sigismember (set, SIGCANCEL)
|
|
||||||
|| __glibc_unlikely (__sigismember (set, SIGSETXID))))
|
|
||||||
{
|
|
||||||
local_newmask = *set;
|
|
||||||
__sigdelset (&local_newmask, SIGCANCEL);
|
|
||||||
__sigdelset (&local_newmask, SIGSETXID);
|
|
||||||
set = &local_newmask;
|
|
||||||
}
|
|
||||||
|
|
||||||
return INLINE_SYSCALL_CALL (rt_sigprocmask, how, set, oset, _NSIG / 8);
|
|
||||||
}
|
}
|
||||||
libc_hidden_def (__sigprocmask)
|
libc_hidden_def (__sigprocmask)
|
||||||
weak_alias (__sigprocmask, sigprocmask)
|
weak_alias (__sigprocmask, sigprocmask)
|
||||||
|
@ -120,6 +120,17 @@ check_error_in_list (int code, int *codes, size_t count)
|
|||||||
#define test_wrp2(experr, syscall, ...) \
|
#define test_wrp2(experr, syscall, ...) \
|
||||||
test_wrp_rv(int, "%d", LIST_FORWARD (experr), syscall, __VA_ARGS__)
|
test_wrp_rv(int, "%d", LIST_FORWARD (experr), syscall, __VA_ARGS__)
|
||||||
|
|
||||||
|
static int
|
||||||
|
invalid_sigprocmask_how (void)
|
||||||
|
{
|
||||||
|
int n = 0;
|
||||||
|
const int how[] = { SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASK };
|
||||||
|
for (int i = 0; i < array_length (how); i++)
|
||||||
|
if (how[i] == n)
|
||||||
|
n++;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
do_test (void)
|
do_test (void)
|
||||||
{
|
{
|
||||||
@ -133,10 +144,13 @@ do_test (void)
|
|||||||
struct sched_param sch_param;
|
struct sched_param sch_param;
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
sigset_t sigs;
|
||||||
unsigned char vec[16];
|
unsigned char vec[16];
|
||||||
ss.ss_flags = ~SS_DISABLE;
|
ss.ss_flags = ~SS_DISABLE;
|
||||||
ts.tv_sec = -1;
|
ts.tv_sec = -1;
|
||||||
|
|
||||||
|
sigemptyset (&sigs);
|
||||||
|
|
||||||
int fails = 0;
|
int fails = 0;
|
||||||
fails |= test_wrp (EINVAL, epoll_create, -1);
|
fails |= test_wrp (EINVAL, epoll_create, -1);
|
||||||
fails |= test_wrp (EINVAL, epoll_create1, EPOLL_CLOEXEC + 1);
|
fails |= test_wrp (EINVAL, epoll_create1, EPOLL_CLOEXEC + 1);
|
||||||
@ -175,6 +189,11 @@ do_test (void)
|
|||||||
fails |= test_wrp (EBADF, sendfile, -1, -1, &off, 0);
|
fails |= test_wrp (EBADF, sendfile, -1, -1, &off, 0);
|
||||||
fails |= test_wrp (EINVAL, sigaltstack, &ss, NULL);
|
fails |= test_wrp (EINVAL, sigaltstack, &ss, NULL);
|
||||||
fails |= test_wrp (ECHILD, wait4, -1, &status, 0, NULL);
|
fails |= test_wrp (ECHILD, wait4, -1, &status, 0, NULL);
|
||||||
|
/* Austin Group issue #1132 states EINVAL should be returned for invalid
|
||||||
|
how argument iff the new set mask is non-null. And Linux follows the
|
||||||
|
standard on this regard. */
|
||||||
|
fails |= test_wrp (EINVAL, sigprocmask, invalid_sigprocmask_how (), &sigs,
|
||||||
|
NULL);
|
||||||
|
|
||||||
return fails;
|
return fails;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user