Merge "Fix sigaction(3) for 64-bit."
This commit is contained in:
commit
967cd1bcaf
20 changed files with 358 additions and 126 deletions
|
@ -125,7 +125,6 @@ libc_common_src_files := \
|
||||||
bionic/sigblock.c \
|
bionic/sigblock.c \
|
||||||
bionic/siginterrupt.c \
|
bionic/siginterrupt.c \
|
||||||
bionic/siglist.c \
|
bionic/siglist.c \
|
||||||
bionic/signal.c \
|
|
||||||
bionic/signame.c \
|
bionic/signame.c \
|
||||||
bionic/sigsetmask.c \
|
bionic/sigsetmask.c \
|
||||||
bionic/sleep.c \
|
bionic/sleep.c \
|
||||||
|
@ -246,6 +245,13 @@ libc_bionic_src_files := \
|
||||||
bionic/seteuid.cpp \
|
bionic/seteuid.cpp \
|
||||||
bionic/setlocale.cpp \
|
bionic/setlocale.cpp \
|
||||||
bionic/signalfd.cpp \
|
bionic/signalfd.cpp \
|
||||||
|
bionic/sigaction.cpp \
|
||||||
|
bionic/sigaddset.cpp \
|
||||||
|
bionic/sigdelset.cpp \
|
||||||
|
bionic/sigemptyset.cpp \
|
||||||
|
bionic/sigfillset.cpp \
|
||||||
|
bionic/sigismember.cpp \
|
||||||
|
bionic/signal.cpp \
|
||||||
bionic/sigpending.cpp \
|
bionic/sigpending.cpp \
|
||||||
bionic/sigprocmask.cpp \
|
bionic/sigprocmask.cpp \
|
||||||
bionic/sigsuspend.cpp \
|
bionic/sigsuspend.cpp \
|
||||||
|
|
|
@ -224,7 +224,7 @@ int timerfd_settime(int, int, const struct itimerspec*, struct itimers
|
||||||
int timerfd_gettime(int, struct itimerspec*) all
|
int timerfd_gettime(int, struct itimerspec*) all
|
||||||
|
|
||||||
# signals
|
# signals
|
||||||
int sigaction(int, const struct sigaction*, struct sigaction*) arm,x86,mips
|
int __sigaction:sigaction(int, const struct sigaction*, struct sigaction*) arm,mips,x86
|
||||||
int __rt_sigaction:rt_sigaction(int, const struct sigaction*, struct sigaction*, size_t) all
|
int __rt_sigaction:rt_sigaction(int, const struct sigaction*, struct sigaction*, size_t) all
|
||||||
int __rt_sigpending:rt_sigpending(sigset_t*, size_t) all
|
int __rt_sigpending:rt_sigpending(sigset_t*, size_t) all
|
||||||
int __rt_sigprocmask:rt_sigprocmask(int, const sigset_t*, sigset_t*, size_t) all
|
int __rt_sigprocmask:rt_sigprocmask(int, const sigset_t*, sigset_t*, size_t) all
|
||||||
|
|
|
@ -22,6 +22,7 @@ syscall_src += arch-arm/syscalls/__rt_sigsuspend.S
|
||||||
syscall_src += arch-arm/syscalls/__rt_sigtimedwait.S
|
syscall_src += arch-arm/syscalls/__rt_sigtimedwait.S
|
||||||
syscall_src += arch-arm/syscalls/__sched_getaffinity.S
|
syscall_src += arch-arm/syscalls/__sched_getaffinity.S
|
||||||
syscall_src += arch-arm/syscalls/__set_tls.S
|
syscall_src += arch-arm/syscalls/__set_tls.S
|
||||||
|
syscall_src += arch-arm/syscalls/__sigaction.S
|
||||||
syscall_src += arch-arm/syscalls/__statfs64.S
|
syscall_src += arch-arm/syscalls/__statfs64.S
|
||||||
syscall_src += arch-arm/syscalls/__sys_clone.S
|
syscall_src += arch-arm/syscalls/__sys_clone.S
|
||||||
syscall_src += arch-arm/syscalls/__syslog.S
|
syscall_src += arch-arm/syscalls/__syslog.S
|
||||||
|
@ -178,7 +179,6 @@ syscall_src += arch-arm/syscalls/settimeofday.S
|
||||||
syscall_src += arch-arm/syscalls/setuid.S
|
syscall_src += arch-arm/syscalls/setuid.S
|
||||||
syscall_src += arch-arm/syscalls/setxattr.S
|
syscall_src += arch-arm/syscalls/setxattr.S
|
||||||
syscall_src += arch-arm/syscalls/shutdown.S
|
syscall_src += arch-arm/syscalls/shutdown.S
|
||||||
syscall_src += arch-arm/syscalls/sigaction.S
|
|
||||||
syscall_src += arch-arm/syscalls/sigaltstack.S
|
syscall_src += arch-arm/syscalls/sigaltstack.S
|
||||||
syscall_src += arch-arm/syscalls/signalfd4.S
|
syscall_src += arch-arm/syscalls/signalfd4.S
|
||||||
syscall_src += arch-arm/syscalls/socket.S
|
syscall_src += arch-arm/syscalls/socket.S
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <machine/asm.h>
|
#include <machine/asm.h>
|
||||||
|
|
||||||
ENTRY(sigaction)
|
ENTRY(__sigaction)
|
||||||
mov ip, r7
|
mov ip, r7
|
||||||
ldr r7, =__NR_sigaction
|
ldr r7, =__NR_sigaction
|
||||||
swi #0
|
swi #0
|
||||||
|
@ -13,4 +13,4 @@ ENTRY(sigaction)
|
||||||
bxls lr
|
bxls lr
|
||||||
neg r0, r0
|
neg r0, r0
|
||||||
b __set_errno
|
b __set_errno
|
||||||
END(sigaction)
|
END(__sigaction)
|
|
@ -22,6 +22,7 @@ syscall_src += arch-mips/syscalls/__rt_sigsuspend.S
|
||||||
syscall_src += arch-mips/syscalls/__rt_sigtimedwait.S
|
syscall_src += arch-mips/syscalls/__rt_sigtimedwait.S
|
||||||
syscall_src += arch-mips/syscalls/__sched_getaffinity.S
|
syscall_src += arch-mips/syscalls/__sched_getaffinity.S
|
||||||
syscall_src += arch-mips/syscalls/__set_thread_area.S
|
syscall_src += arch-mips/syscalls/__set_thread_area.S
|
||||||
|
syscall_src += arch-mips/syscalls/__sigaction.S
|
||||||
syscall_src += arch-mips/syscalls/__statfs64.S
|
syscall_src += arch-mips/syscalls/__statfs64.S
|
||||||
syscall_src += arch-mips/syscalls/__sys_clone.S
|
syscall_src += arch-mips/syscalls/__sys_clone.S
|
||||||
syscall_src += arch-mips/syscalls/__syslog.S
|
syscall_src += arch-mips/syscalls/__syslog.S
|
||||||
|
@ -179,7 +180,6 @@ syscall_src += arch-mips/syscalls/settimeofday.S
|
||||||
syscall_src += arch-mips/syscalls/setuid.S
|
syscall_src += arch-mips/syscalls/setuid.S
|
||||||
syscall_src += arch-mips/syscalls/setxattr.S
|
syscall_src += arch-mips/syscalls/setxattr.S
|
||||||
syscall_src += arch-mips/syscalls/shutdown.S
|
syscall_src += arch-mips/syscalls/shutdown.S
|
||||||
syscall_src += arch-mips/syscalls/sigaction.S
|
|
||||||
syscall_src += arch-mips/syscalls/sigaltstack.S
|
syscall_src += arch-mips/syscalls/sigaltstack.S
|
||||||
syscall_src += arch-mips/syscalls/signalfd4.S
|
syscall_src += arch-mips/syscalls/signalfd4.S
|
||||||
syscall_src += arch-mips/syscalls/socket.S
|
syscall_src += arch-mips/syscalls/socket.S
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
|
|
||||||
#include <asm/unistd.h>
|
#include <asm/unistd.h>
|
||||||
.text
|
.text
|
||||||
.globl sigaction
|
.globl __sigaction
|
||||||
.align 4
|
.align 4
|
||||||
.ent sigaction
|
.ent __sigaction
|
||||||
|
|
||||||
sigaction:
|
__sigaction:
|
||||||
.set noreorder
|
.set noreorder
|
||||||
.cpload $t9
|
.cpload $t9
|
||||||
li $v0, __NR_sigaction
|
li $v0, __NR_sigaction
|
||||||
|
@ -20,4 +20,4 @@ sigaction:
|
||||||
j $t9
|
j $t9
|
||||||
nop
|
nop
|
||||||
.set reorder
|
.set reorder
|
||||||
.end sigaction
|
.end __sigaction
|
|
@ -22,6 +22,7 @@ syscall_src += arch-x86/syscalls/__rt_sigsuspend.S
|
||||||
syscall_src += arch-x86/syscalls/__rt_sigtimedwait.S
|
syscall_src += arch-x86/syscalls/__rt_sigtimedwait.S
|
||||||
syscall_src += arch-x86/syscalls/__sched_getaffinity.S
|
syscall_src += arch-x86/syscalls/__sched_getaffinity.S
|
||||||
syscall_src += arch-x86/syscalls/__set_thread_area.S
|
syscall_src += arch-x86/syscalls/__set_thread_area.S
|
||||||
|
syscall_src += arch-x86/syscalls/__sigaction.S
|
||||||
syscall_src += arch-x86/syscalls/__statfs64.S
|
syscall_src += arch-x86/syscalls/__statfs64.S
|
||||||
syscall_src += arch-x86/syscalls/__sys_clone.S
|
syscall_src += arch-x86/syscalls/__sys_clone.S
|
||||||
syscall_src += arch-x86/syscalls/__syslog.S
|
syscall_src += arch-x86/syscalls/__syslog.S
|
||||||
|
@ -179,7 +180,6 @@ syscall_src += arch-x86/syscalls/settimeofday.S
|
||||||
syscall_src += arch-x86/syscalls/setuid.S
|
syscall_src += arch-x86/syscalls/setuid.S
|
||||||
syscall_src += arch-x86/syscalls/setxattr.S
|
syscall_src += arch-x86/syscalls/setxattr.S
|
||||||
syscall_src += arch-x86/syscalls/shutdown.S
|
syscall_src += arch-x86/syscalls/shutdown.S
|
||||||
syscall_src += arch-x86/syscalls/sigaction.S
|
|
||||||
syscall_src += arch-x86/syscalls/sigaltstack.S
|
syscall_src += arch-x86/syscalls/sigaltstack.S
|
||||||
syscall_src += arch-x86/syscalls/signalfd4.S
|
syscall_src += arch-x86/syscalls/signalfd4.S
|
||||||
syscall_src += arch-x86/syscalls/socket.S
|
syscall_src += arch-x86/syscalls/socket.S
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <machine/asm.h>
|
#include <machine/asm.h>
|
||||||
|
|
||||||
ENTRY(sigaction)
|
ENTRY(__sigaction)
|
||||||
pushl %ebx
|
pushl %ebx
|
||||||
pushl %ecx
|
pushl %ecx
|
||||||
pushl %edx
|
pushl %edx
|
||||||
|
@ -25,4 +25,4 @@ ENTRY(sigaction)
|
||||||
popl %ecx
|
popl %ecx
|
||||||
popl %ebx
|
popl %ebx
|
||||||
ret
|
ret
|
||||||
END(sigaction)
|
END(__sigaction)
|
|
@ -7,7 +7,6 @@ _LIBC_ARCH_COMMON_SRC_FILES := \
|
||||||
arch-x86_64/bionic/_setjmp.S \
|
arch-x86_64/bionic/_setjmp.S \
|
||||||
arch-x86_64/bionic/setjmp.S \
|
arch-x86_64/bionic/setjmp.S \
|
||||||
arch-x86_64/bionic/__set_tls.c \
|
arch-x86_64/bionic/__set_tls.c \
|
||||||
arch-x86_64/bionic/sigaction.c \
|
|
||||||
arch-x86_64/bionic/sigsetjmp.S \
|
arch-x86_64/bionic/sigsetjmp.S \
|
||||||
arch-x86_64/bionic/syscall.S \
|
arch-x86_64/bionic/syscall.S \
|
||||||
|
|
||||||
|
|
76
libc/bionic/sigaction.cpp
Normal file
76
libc/bionic/sigaction.cpp
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2013 The Android Open Source Project
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
#if __LP64__
|
||||||
|
extern "C" void __rt_sigreturn(void);
|
||||||
|
extern "C" int __rt_sigaction(int, const struct __kernel_sigaction*, struct __kernel_sigaction*, size_t);
|
||||||
|
#else
|
||||||
|
extern "C" int __sigaction(int, const struct sigaction*, struct sigaction*);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int sigaction(int signal, const struct sigaction* bionic_new_action, struct sigaction* bionic_old_action) {
|
||||||
|
#if __LP64__
|
||||||
|
__kernel_sigaction kernel_new_action;
|
||||||
|
if (bionic_new_action != NULL) {
|
||||||
|
kernel_new_action.sa_flags = bionic_new_action->sa_flags;
|
||||||
|
kernel_new_action.sa_handler = bionic_new_action->sa_handler;
|
||||||
|
kernel_new_action.sa_mask = bionic_new_action->sa_mask;
|
||||||
|
kernel_new_action.sa_restorer = bionic_new_action->sa_restorer;
|
||||||
|
|
||||||
|
if (!(kernel_new_action.sa_flags & SA_RESTORER)) {
|
||||||
|
kernel_new_action.sa_flags |= SA_RESTORER;
|
||||||
|
kernel_new_action.sa_restorer = &__rt_sigreturn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__kernel_sigaction kernel_old_action;
|
||||||
|
int result = __rt_sigaction(signal,
|
||||||
|
(bionic_new_action != NULL) ? &kernel_new_action : NULL,
|
||||||
|
(bionic_old_action != NULL) ? &kernel_old_action : NULL,
|
||||||
|
sizeof(sigset_t));
|
||||||
|
|
||||||
|
if (bionic_old_action != NULL) {
|
||||||
|
bionic_old_action->sa_flags = kernel_old_action.sa_flags;
|
||||||
|
bionic_old_action->sa_handler = kernel_old_action.sa_handler;
|
||||||
|
bionic_old_action->sa_mask = kernel_old_action.sa_mask;
|
||||||
|
bionic_old_action->sa_restorer = kernel_old_action.sa_restorer;
|
||||||
|
|
||||||
|
if (bionic_old_action->sa_restorer == &__rt_sigreturn) {
|
||||||
|
bionic_old_action->sa_flags &= ~SA_RESTORER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
#else
|
||||||
|
// The 32-bit ABI is broken. struct sigaction includes a too-small sigset_t.
|
||||||
|
// TODO: if we also had correct struct sigaction definitions available, we could copy in and out.
|
||||||
|
return __sigaction(signal, bionic_new_action, bionic_old_action);
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2013 The Android Open Source Project
|
* Copyright (C) 2008 The Android Open Source Project
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -28,25 +28,13 @@
|
||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
extern void __rt_sigreturn(void);
|
int sigaddset(sigset_t* set, int signum) {
|
||||||
extern int __rt_sigaction(int, const struct sigaction*, struct sigaction*, size_t);
|
int bit = signum - 1; // Signal numbers start at 1, but bit positions start at 0.
|
||||||
|
unsigned long* local_set = (unsigned long*) set;
|
||||||
int sigaction(int sig, const struct sigaction* act, struct sigaction* old_act) {
|
if (set == NULL || bit < 0 || bit >= (int) (8*sizeof(sigset_t))) {
|
||||||
struct sigaction sa;
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
if (act != NULL && !(act->sa_flags & SA_RESTORER)) {
|
|
||||||
sa = *act;
|
|
||||||
act = &sa;
|
|
||||||
sa.sa_flags |= SA_RESTORER;
|
|
||||||
sa.sa_restorer = &__rt_sigreturn;
|
|
||||||
}
|
}
|
||||||
|
local_set[bit / LONG_BIT] |= 1UL << (bit % LONG_BIT);
|
||||||
int result = __rt_sigaction(sig, act, old_act, sizeof(sigset_t));
|
return 0;
|
||||||
|
|
||||||
if (old_act != NULL && (old_act->sa_restorer == &__rt_sigreturn)) {
|
|
||||||
old_act->sa_flags &= ~SA_RESTORER;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
40
libc/bionic/sigdelset.cpp
Normal file
40
libc/bionic/sigdelset.cpp
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2008 The Android Open Source Project
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
int sigdelset(sigset_t* set, int signum) {
|
||||||
|
int bit = signum - 1; // Signal numbers start at 1, but bit positions start at 0.
|
||||||
|
unsigned long* local_set = (unsigned long*) set;
|
||||||
|
if (set == NULL || bit < 0 || bit >= (int) (8*sizeof(sigset_t))) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
local_set[bit / LONG_BIT] &= ~(1UL << (bit % LONG_BIT));
|
||||||
|
return 0;
|
||||||
|
}
|
38
libc/bionic/sigemptyset.cpp
Normal file
38
libc/bionic/sigemptyset.cpp
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2008 The Android Open Source Project
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
int sigemptyset(sigset_t* set) {
|
||||||
|
if (set == NULL) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memset(set, 0, sizeof(sigset_t));
|
||||||
|
return 0;
|
||||||
|
}
|
38
libc/bionic/sigfillset.cpp
Normal file
38
libc/bionic/sigfillset.cpp
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2008 The Android Open Source Project
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
int sigfillset(sigset_t* set) {
|
||||||
|
if (set == NULL) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memset(set, ~0, sizeof(sigset_t));
|
||||||
|
return 0;
|
||||||
|
}
|
39
libc/bionic/sigismember.cpp
Normal file
39
libc/bionic/sigismember.cpp
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2008 The Android Open Source Project
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
int sigismember(const sigset_t* set, int signum) {
|
||||||
|
int bit = signum - 1; // Signal numbers start at 1, but bit positions start at 0.
|
||||||
|
const unsigned long* local_set = (const unsigned long*) set;
|
||||||
|
if (set == NULL || bit < 0 || bit >= (int) (8*sizeof(sigset_t))) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return (int) ((local_set[bit / LONG_BIT] >> (bit % LONG_BIT)) & 1);
|
||||||
|
}
|
|
@ -25,33 +25,30 @@
|
||||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
|
static sighandler_t _signal(int signum, sighandler_t handler, int flags) {
|
||||||
|
struct sigaction sa;
|
||||||
|
sigemptyset(&sa.sa_mask);
|
||||||
|
sa.sa_handler = handler;
|
||||||
|
sa.sa_flags = flags;
|
||||||
|
|
||||||
static __sighandler_t
|
if (sigaction(signum, &sa, &sa) == -1) {
|
||||||
_signal(int signum, __sighandler_t handler, int flags)
|
return SIG_ERR;
|
||||||
{
|
}
|
||||||
struct sigaction sa;
|
|
||||||
__sighandler_t result = SIG_ERR;
|
|
||||||
|
|
||||||
sigemptyset( &sa.sa_mask );
|
return (sighandler_t) sa.sa_handler;
|
||||||
|
|
||||||
sa.sa_handler = handler;
|
|
||||||
sa.sa_flags = flags;
|
|
||||||
|
|
||||||
if ( !sigaction( signum, &sa, &sa ) )
|
|
||||||
result = (__sighandler_t) sa.sa_handler;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sighandler_t bsd_signal(int signum, sighandler_t handler) {
|
||||||
__sighandler_t bsd_signal(int signum, __sighandler_t handler)
|
|
||||||
{
|
|
||||||
return _signal(signum, handler, SA_RESTART);
|
return _signal(signum, handler, SA_RESTART);
|
||||||
}
|
}
|
||||||
|
|
||||||
__sighandler_t sysv_signal(int signum, __sighandler_t handler)
|
sighandler_t sysv_signal(int signum, sighandler_t handler) {
|
||||||
{
|
|
||||||
return _signal(signum, handler, SA_RESETHAND);
|
return _signal(signum, handler, SA_RESETHAND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sighandler_t signal(int signum, sighandler_t handler) {
|
||||||
|
return bsd_signal(signum, handler);
|
||||||
|
}
|
|
@ -25,6 +25,7 @@
|
||||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _SIGNAL_H_
|
#ifndef _SIGNAL_H_
|
||||||
#define _SIGNAL_H_
|
#define _SIGNAL_H_
|
||||||
|
|
||||||
|
@ -33,7 +34,18 @@
|
||||||
#include <limits.h> /* For LONG_BIT */
|
#include <limits.h> /* For LONG_BIT */
|
||||||
#include <string.h> /* For memset() */
|
#include <string.h> /* For memset() */
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <asm/signal.h>
|
|
||||||
|
#if defined(__LP64__)
|
||||||
|
/* For 64-bit, the kernel's struct sigaction doesn't match the POSIX one,
|
||||||
|
* so we need to expose our own and translate behind the scenes. */
|
||||||
|
# define sigaction __kernel_sigaction
|
||||||
|
# include <asm/signal.h>
|
||||||
|
# undef sigaction
|
||||||
|
#else
|
||||||
|
/* For 32-bit, we're stuck with the definitions we already shipped,
|
||||||
|
* even though they contain a sigset_t that's too small. */
|
||||||
|
# include <asm/signal.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define __ARCH_SI_UID_T __kernel_uid32_t
|
#define __ARCH_SI_UID_T __kernel_uid32_t
|
||||||
#include <asm/siginfo.h>
|
#include <asm/siginfo.h>
|
||||||
|
@ -57,73 +69,37 @@ typedef int sig_atomic_t;
|
||||||
extern const char* const sys_siglist[];
|
extern const char* const sys_siglist[];
|
||||||
extern const char* const sys_signame[];
|
extern const char* const sys_signame[];
|
||||||
|
|
||||||
static __inline__ int sigismember(const sigset_t* set, int signum) {
|
typedef __sighandler_t sig_t; /* BSD compatibility. */
|
||||||
int bit = signum - 1; // Signal numbers start at 1, but bit positions start at 0.
|
typedef __sighandler_t sighandler_t; /* glibc compatibility. */
|
||||||
const unsigned long* local_set = (const unsigned long*) set;
|
|
||||||
if (set == NULL || bit < 0 || bit >= (int) (8*sizeof(sigset_t))) {
|
|
||||||
errno = EINVAL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return (int) ((local_set[bit / LONG_BIT] >> (bit % LONG_BIT)) & 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline__ int sigaddset(sigset_t* set, int signum) {
|
#if __LP64__
|
||||||
int bit = signum - 1; // Signal numbers start at 1, but bit positions start at 0.
|
|
||||||
unsigned long* local_set = (unsigned long*) set;
|
|
||||||
if (set == NULL || bit < 0 || bit >= (int) (8*sizeof(sigset_t))) {
|
|
||||||
errno = EINVAL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
local_set[bit / LONG_BIT] |= 1UL << (bit % LONG_BIT);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline__ int sigdelset(sigset_t* set, int signum) {
|
struct sigaction {
|
||||||
int bit = signum - 1; // Signal numbers start at 1, but bit positions start at 0.
|
unsigned int sa_flags;
|
||||||
unsigned long* local_set = (unsigned long*) set;
|
union {
|
||||||
if (set == NULL || bit < 0 || bit >= (int) (8*sizeof(sigset_t))) {
|
sighandler_t sa_handler;
|
||||||
errno = EINVAL;
|
void (*sa_sigaction)(int, struct siginfo*, void*);
|
||||||
return -1;
|
};
|
||||||
}
|
sigset_t sa_mask;
|
||||||
local_set[bit / LONG_BIT] &= ~(1UL << (bit % LONG_BIT));
|
void (*sa_restorer)(void);
|
||||||
return 0;
|
};
|
||||||
}
|
|
||||||
|
|
||||||
static __inline__ int sigemptyset(sigset_t* set) {
|
#endif
|
||||||
if (set == NULL) {
|
|
||||||
errno = EINVAL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
memset(set, 0, sizeof *set);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline__ int sigfillset(sigset_t* set) {
|
|
||||||
if (set == NULL) {
|
|
||||||
errno = EINVAL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
memset(set, ~0, sizeof *set);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* compatibility types */
|
|
||||||
typedef void (*sig_t)(int);
|
|
||||||
typedef sig_t sighandler_t;
|
|
||||||
|
|
||||||
/* differentiater between sysv and bsd behaviour 8*/
|
|
||||||
extern __sighandler_t sysv_signal(int, __sighandler_t);
|
|
||||||
extern __sighandler_t bsd_signal(int, __sighandler_t);
|
|
||||||
|
|
||||||
/* the default is bsd */
|
|
||||||
static __inline__ __sighandler_t signal(int s, __sighandler_t f)
|
|
||||||
{
|
|
||||||
return bsd_signal(s,f);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern int sigaction(int, const struct sigaction*, struct sigaction*);
|
extern int sigaction(int, const struct sigaction*, struct sigaction*);
|
||||||
|
|
||||||
|
extern sighandler_t signal(int, sighandler_t);
|
||||||
|
extern sighandler_t bsd_signal(int, sighandler_t);
|
||||||
|
extern sighandler_t sysv_signal(int, sighandler_t);
|
||||||
|
|
||||||
extern int siginterrupt(int, int);
|
extern int siginterrupt(int, int);
|
||||||
|
|
||||||
|
extern int sigaddset(sigset_t*, int);
|
||||||
|
extern int sigdelset(sigset_t*, int);
|
||||||
|
extern int sigemptyset(sigset_t*);
|
||||||
|
extern int sigfillset(sigset_t*);
|
||||||
|
extern int sigismember(const sigset_t*, int);
|
||||||
|
|
||||||
extern int sigpending(sigset_t*) __nonnull((1));
|
extern int sigpending(sigset_t*) __nonnull((1));
|
||||||
extern int sigprocmask(int, const sigset_t*, sigset_t*);
|
extern int sigprocmask(int, const sigset_t*, sigset_t*);
|
||||||
extern int sigsuspend(const sigset_t*) __nonnull((1));
|
extern int sigsuspend(const sigset_t*) __nonnull((1));
|
||||||
|
@ -132,6 +108,7 @@ extern int sigwait(const sigset_t*, int*) __nonnull((1, 2));
|
||||||
extern int raise(int);
|
extern int raise(int);
|
||||||
extern int kill(pid_t, int);
|
extern int kill(pid_t, int);
|
||||||
extern int killpg(int, int);
|
extern int killpg(int, int);
|
||||||
|
|
||||||
extern int sigaltstack(const stack_t*, stack_t*);
|
extern int sigaltstack(const stack_t*, stack_t*);
|
||||||
|
|
||||||
extern void psiginfo(const siginfo_t*, const char*);
|
extern void psiginfo(const siginfo_t*, const char*);
|
||||||
|
|
|
@ -176,12 +176,7 @@ static bool have_siginfo(int signum) {
|
||||||
* Catches fatal signals so we can ask debuggerd to ptrace us before
|
* Catches fatal signals so we can ask debuggerd to ptrace us before
|
||||||
* we crash.
|
* we crash.
|
||||||
*/
|
*/
|
||||||
#if __LP64__ // TODO: implement 64-bit sigaction using rt_sigaction.
|
|
||||||
void debuggerd_signal_handler(int n) {
|
|
||||||
siginfo_t* info = NULL;
|
|
||||||
#else
|
|
||||||
void debuggerd_signal_handler(int n, siginfo_t* info, void*) {
|
void debuggerd_signal_handler(int n, siginfo_t* info, void*) {
|
||||||
#endif
|
|
||||||
/*
|
/*
|
||||||
* It's possible somebody cleared the SA_SIGINFO flag, which would mean
|
* It's possible somebody cleared the SA_SIGINFO flag, which would mean
|
||||||
* our "info" arg holds an undefined value.
|
* our "info" arg holds an undefined value.
|
||||||
|
@ -254,11 +249,7 @@ void debuggerd_init() {
|
||||||
struct sigaction action;
|
struct sigaction action;
|
||||||
memset(&action, 0, sizeof(action));
|
memset(&action, 0, sizeof(action));
|
||||||
sigemptyset(&action.sa_mask);
|
sigemptyset(&action.sa_mask);
|
||||||
#if __LP64__ // TODO: implement 64-bit sigaction using rt_sigaction.
|
|
||||||
action.sa_handler = debuggerd_signal_handler;
|
|
||||||
#else
|
|
||||||
action.sa_sigaction = debuggerd_signal_handler;
|
action.sa_sigaction = debuggerd_signal_handler;
|
||||||
#endif
|
|
||||||
action.sa_flags = SA_RESTART | SA_SIGINFO;
|
action.sa_flags = SA_RESTART | SA_SIGINFO;
|
||||||
|
|
||||||
// Use the alternate signal stack if available so we can catch stack overflows.
|
// Use the alternate signal stack if available so we can catch stack overflows.
|
||||||
|
|
|
@ -284,11 +284,13 @@ static void pthread_kill__in_signal_handler_helper(int signal_number) {
|
||||||
|
|
||||||
TEST(pthread, pthread_kill__in_signal_handler) {
|
TEST(pthread, pthread_kill__in_signal_handler) {
|
||||||
struct sigaction action;
|
struct sigaction action;
|
||||||
|
struct sigaction original_action;
|
||||||
sigemptyset(&action.sa_mask);
|
sigemptyset(&action.sa_mask);
|
||||||
action.sa_flags = 0;
|
action.sa_flags = 0;
|
||||||
action.sa_handler = pthread_kill__in_signal_handler_helper;
|
action.sa_handler = pthread_kill__in_signal_handler_helper;
|
||||||
sigaction(SIGALRM, &action, NULL);
|
ASSERT_EQ(0, sigaction(SIGALRM, &action, &original_action));
|
||||||
ASSERT_EQ(0, pthread_kill(pthread_self(), SIGALRM));
|
ASSERT_EQ(0, pthread_kill(pthread_self(), SIGALRM));
|
||||||
|
ASSERT_EQ(0, sigaction(SIGALRM, &original_action, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(pthread, pthread_detach__no_such_thread) {
|
TEST(pthread, pthread_detach__no_such_thread) {
|
||||||
|
|
|
@ -210,3 +210,44 @@ TEST(signal, sigsuspend_sigpending) {
|
||||||
// Restore the original set.
|
// Restore the original set.
|
||||||
assert(0 == sigprocmask(SIG_SETMASK, &original_set, NULL));
|
assert(0 == sigprocmask(SIG_SETMASK, &original_set, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void EmptySignalHandler(int) {}
|
||||||
|
static void EmptySignalAction(int, siginfo_t*, void*) {}
|
||||||
|
|
||||||
|
TEST(signal, sigaction) {
|
||||||
|
// See what's currently set for SIGALRM.
|
||||||
|
struct sigaction sa;
|
||||||
|
memset(&sa, 0, sizeof(sa));
|
||||||
|
ASSERT_EQ(0, sigaction(SIGALRM, NULL, &sa));
|
||||||
|
ASSERT_TRUE(sa.sa_handler == NULL);
|
||||||
|
ASSERT_TRUE(sa.sa_sigaction == NULL);
|
||||||
|
ASSERT_TRUE(sa.sa_flags == 0);
|
||||||
|
|
||||||
|
// Set a traditional sa_handler signal handler.
|
||||||
|
memset(&sa, 0, sizeof(sa));
|
||||||
|
sigaddset(&sa.sa_mask, SIGALRM);
|
||||||
|
sa.sa_flags = SA_ONSTACK;
|
||||||
|
sa.sa_handler = EmptySignalHandler;
|
||||||
|
ASSERT_EQ(0, sigaction(SIGALRM, &sa, NULL));
|
||||||
|
|
||||||
|
// Check that we can read it back.
|
||||||
|
memset(&sa, 0, sizeof(sa));
|
||||||
|
ASSERT_EQ(0, sigaction(SIGALRM, NULL, &sa));
|
||||||
|
ASSERT_TRUE(sa.sa_handler == EmptySignalHandler);
|
||||||
|
ASSERT_TRUE((void*) sa.sa_sigaction == (void*) sa.sa_handler);
|
||||||
|
ASSERT_TRUE(sa.sa_flags == SA_ONSTACK);
|
||||||
|
|
||||||
|
// Set a new-style sa_sigaction signal handler.
|
||||||
|
memset(&sa, 0, sizeof(sa));
|
||||||
|
sigaddset(&sa.sa_mask, SIGALRM);
|
||||||
|
sa.sa_flags = SA_ONSTACK | SA_SIGINFO;
|
||||||
|
sa.sa_sigaction = EmptySignalAction;
|
||||||
|
ASSERT_EQ(0, sigaction(SIGALRM, &sa, NULL));
|
||||||
|
|
||||||
|
// Check that we can read it back.
|
||||||
|
memset(&sa, 0, sizeof(sa));
|
||||||
|
ASSERT_EQ(0, sigaction(SIGALRM, NULL, &sa));
|
||||||
|
ASSERT_TRUE(sa.sa_sigaction == EmptySignalAction);
|
||||||
|
ASSERT_TRUE((void*) sa.sa_sigaction == (void*) sa.sa_handler);
|
||||||
|
ASSERT_TRUE(sa.sa_flags == (SA_ONSTACK | SA_SIGINFO));
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue