Merge "Clean up the sigprocmask/pthread_sigmask implementation."

This commit is contained in:
Elliott Hughes 2013-10-15 21:10:20 +00:00 committed by Gerrit Code Review
commit 22b83da476
12 changed files with 46 additions and 97 deletions

View file

@ -247,6 +247,7 @@ libc_bionic_src_files := \
bionic/seteuid.cpp \
bionic/setlocale.cpp \
bionic/signalfd.cpp \
bionic/sigprocmask.cpp \
bionic/sigwait.cpp \
bionic/statvfs.cpp \
bionic/strerror.cpp \

View file

@ -233,7 +233,6 @@ int timerfd_gettime(int, struct itimerspec*) all
# signals
int sigaction(int, const struct sigaction*, struct sigaction*) arm,x86,mips
int sigprocmask(int, const sigset_t*, sigset_t*) arm,x86,mips
int __sigsuspend:sigsuspend(int unused1, int unused2, unsigned mask) arm,x86
int __sigsuspend:sigsuspend(const sigset_t* mask) mips
int __rt_sigsuspend:rt_sigsuspend(const sigset_t *unewset, size_t sigset_size) x86_64

View file

@ -152,7 +152,6 @@ syscall_src += arch-arm/syscalls/timerfd_create.S
syscall_src += arch-arm/syscalls/timerfd_settime.S
syscall_src += arch-arm/syscalls/timerfd_gettime.S
syscall_src += arch-arm/syscalls/sigaction.S
syscall_src += arch-arm/syscalls/sigprocmask.S
syscall_src += arch-arm/syscalls/__sigsuspend.S
syscall_src += arch-arm/syscalls/__rt_sigaction.S
syscall_src += arch-arm/syscalls/__rt_sigprocmask.S

View file

@ -1,15 +0,0 @@
/* autogenerated by gensyscalls.py */
#include <asm/unistd.h>
#include <linux/err.h>
#include <machine/asm.h>
ENTRY(sigprocmask)
mov ip, r7
ldr r7, =__NR_sigprocmask
swi #0
mov r7, ip
cmn r0, #(MAX_ERRNO + 1)
bxls lr
neg r0, r0
b __set_errno
END(sigprocmask)

View file

@ -155,7 +155,6 @@ syscall_src += arch-mips/syscalls/timerfd_create.S
syscall_src += arch-mips/syscalls/timerfd_settime.S
syscall_src += arch-mips/syscalls/timerfd_gettime.S
syscall_src += arch-mips/syscalls/sigaction.S
syscall_src += arch-mips/syscalls/sigprocmask.S
syscall_src += arch-mips/syscalls/__sigsuspend.S
syscall_src += arch-mips/syscalls/__rt_sigaction.S
syscall_src += arch-mips/syscalls/__rt_sigprocmask.S

View file

@ -1,22 +0,0 @@
/* autogenerated by gensyscalls.py */
#include <asm/unistd.h>
.text
.globl sigprocmask
.align 4
.ent sigprocmask
sigprocmask:
.set noreorder
.cpload $t9
li $v0, __NR_sigprocmask
syscall
bnez $a3, 1f
move $a0, $v0
j $ra
nop
1:
la $t9,__set_errno
j $t9
nop
.set reorder
.end sigprocmask

View file

@ -156,7 +156,6 @@ syscall_src += arch-x86/syscalls/timerfd_create.S
syscall_src += arch-x86/syscalls/timerfd_settime.S
syscall_src += arch-x86/syscalls/timerfd_gettime.S
syscall_src += arch-x86/syscalls/sigaction.S
syscall_src += arch-x86/syscalls/sigprocmask.S
syscall_src += arch-x86/syscalls/__sigsuspend.S
syscall_src += arch-x86/syscalls/__rt_sigaction.S
syscall_src += arch-x86/syscalls/__rt_sigprocmask.S

View file

@ -1,27 +0,0 @@
/* autogenerated by gensyscalls.py */
#include <asm/unistd.h>
#include <linux/err.h>
#include <machine/asm.h>
ENTRY(sigprocmask)
pushl %ebx
pushl %ecx
pushl %edx
mov 16(%esp), %ebx
mov 20(%esp), %ecx
mov 24(%esp), %edx
movl $__NR_sigprocmask, %eax
int $0x80
cmpl $-MAX_ERRNO, %eax
jb 1f
negl %eax
pushl %eax
call __set_errno
addl $4, %esp
orl $-1, %eax
1:
popl %edx
popl %ecx
popl %ebx
ret
END(sigprocmask)

View file

@ -8,7 +8,6 @@ _LIBC_ARCH_COMMON_SRC_FILES := \
arch-x86_64/bionic/setjmp.S \
arch-x86_64/bionic/__set_tls.c \
arch-x86_64/bionic/sigaction.c \
arch-x86_64/bionic/sigprocmask.c \
arch-x86_64/bionic/sigsetjmp.S \
arch-x86_64/bionic/sigsuspend.c \
arch-x86_64/bionic/syscall.S \

View file

@ -31,31 +31,9 @@
#include <signal.h>
#include "private/ErrnoRestorer.h"
#include "private/kernel_sigset_t.h"
extern "C" int __rt_sigprocmask(int, const kernel_sigset_t*, kernel_sigset_t*, size_t);
int pthread_sigmask(int how, const sigset_t* iset, sigset_t* oset) {
int pthread_sigmask(int how, const sigset_t* new_set, sigset_t* old_set) {
ErrnoRestorer errno_restorer;
// 'in_set_ptr' is the second parameter to __rt_sigprocmask. It must be NULL
// if 'set' is NULL to ensure correct semantics (which in this case would
// be to ignore 'how' and return the current signal set into 'oset').
kernel_sigset_t in_set;
kernel_sigset_t* in_set_ptr = NULL;
if (iset != NULL) {
in_set.set(iset);
in_set_ptr = &in_set;
}
kernel_sigset_t out_set;
if (__rt_sigprocmask(how, in_set_ptr, &out_set, sizeof(out_set)) == -1) {
return errno;
}
if (oset != NULL) {
*oset = out_set.bionic;
}
return 0;
int result = sigprocmask(how, new_set, old_set);
return (result == -1) ? errno : 0;
}

View file

@ -26,10 +26,30 @@
* SUCH DAMAGE.
*/
#include <errno.h>
#include <pthread.h>
#include <signal.h>
extern int __rt_sigprocmask(int, const sigset_t*, sigset_t*, size_t);
#include "private/kernel_sigset_t.h"
int sigprocmask(int how, const sigset_t* set, sigset_t* old_set) {
return __rt_sigprocmask(how, set, old_set, sizeof(sigset_t));
extern "C" int __rt_sigprocmask(int, const kernel_sigset_t*, kernel_sigset_t*, size_t);
int sigprocmask(int how, const sigset_t* bionic_new_set, sigset_t* bionic_old_set) {
kernel_sigset_t new_set;
kernel_sigset_t* new_set_ptr = NULL;
if (bionic_new_set != NULL) {
new_set.set(bionic_new_set);
new_set_ptr = &new_set;
}
kernel_sigset_t old_set;
if (__rt_sigprocmask(how, new_set_ptr, &old_set, sizeof(old_set)) == -1) {
return -1;
}
if (bionic_old_set != NULL) {
*bionic_old_set = old_set.bionic;
}
return 0;
}

View file

@ -173,12 +173,28 @@ static void* SignalHandlerFn(void* arg) {
}
TEST(pthread, pthread_sigmask) {
// Check that SIGUSR1 isn't blocked.
sigset_t original_set;
sigemptyset(&original_set);
ASSERT_EQ(0, pthread_sigmask(SIG_BLOCK, NULL, &original_set));
ASSERT_FALSE(sigismember(&original_set, SIGUSR1));
// Block SIGUSR1.
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGUSR1);
ASSERT_EQ(0, pthread_sigmask(SIG_BLOCK, &set, NULL));
// Check that SIGUSR1 is blocked.
sigset_t final_set;
sigemptyset(&final_set);
ASSERT_EQ(0, pthread_sigmask(SIG_BLOCK, NULL, &final_set));
ASSERT_TRUE(sigismember(&final_set, SIGUSR1));
// ...and that sigprocmask agrees with pthread_sigmask.
sigemptyset(&final_set);
ASSERT_EQ(0, sigprocmask(SIG_BLOCK, NULL, &final_set));
ASSERT_TRUE(sigismember(&final_set, SIGUSR1));
// Spawn a thread that calls sigwait and tells us what it received.
pthread_t signal_thread;
int received_signal = -1;
@ -192,6 +208,9 @@ TEST(pthread, pthread_sigmask) {
ASSERT_EQ(0, pthread_join(signal_thread, &join_result));
ASSERT_EQ(SIGUSR1, received_signal);
ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(join_result));
// Restore the original signal mask.
ASSERT_EQ(0, pthread_sigmask(SIG_SETMASK, &original_set, NULL));
}
#if __BIONIC__