From 40d105ccb3e6283566ce54b693b3088f31aa4f26 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Wed, 16 Oct 2013 12:53:58 -0700 Subject: [PATCH] Switch sigpending over to rt_sigpending. Change-Id: I7b28984796b5fb343cfbcc47e0afc3a84293d417 --- libc/Android.mk | 1 + libc/SYSCALLS.TXT | 9 ++- libc/arch-arm/syscalls.mk | 4 +- .../{sigpending.S => __rt_sigpending.S} | 6 +- libc/arch-mips/syscalls.mk | 6 +- .../{sigpending.S => __rt_sigpending.S} | 10 ++-- libc/arch-x86/syscalls.mk | 6 +- .../{sigpending.S => __rt_sigpending.S} | 11 ++-- libc/arch-x86_64/syscalls.mk | 3 +- libc/arch-x86_64/syscalls/__rt_sigpending.S | 17 ++++++ libc/bionic/sigpending.cpp | 42 ++++++++++++++ libc/include/signal.h | 24 ++++---- tests/signal_test.cpp | 58 +++++++++++++------ 13 files changed, 140 insertions(+), 57 deletions(-) rename libc/arch-arm/syscalls/{sigpending.S => __rt_sigpending.S} (76%) rename libc/arch-mips/syscalls/{sigpending.S => __rt_sigpending.S} (66%) rename libc/arch-x86/syscalls/{sigpending.S => __rt_sigpending.S} (65%) create mode 100644 libc/arch-x86_64/syscalls/__rt_sigpending.S create mode 100644 libc/bionic/sigpending.cpp diff --git a/libc/Android.mk b/libc/Android.mk index 88be78dc2..417d0ab33 100644 --- a/libc/Android.mk +++ b/libc/Android.mk @@ -246,6 +246,7 @@ libc_bionic_src_files := \ bionic/seteuid.cpp \ bionic/setlocale.cpp \ bionic/signalfd.cpp \ + bionic/sigpending.cpp \ bionic/sigprocmask.cpp \ bionic/sigsuspend.cpp \ bionic/sigwait.cpp \ diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT index 1d6c75f8d..f5712e1bf 100644 --- a/libc/SYSCALLS.TXT +++ b/libc/SYSCALLS.TXT @@ -28,13 +28,12 @@ void _exit:exit_group(int) all void _exit_thread:exit(int) all pid_t __fork:fork(void) all -pid_t _waitpid:waitpid(pid_t, int*, int, struct rusage*) mips,x86 -int __waitid:waitid(int, pid_t, struct siginfo_t*, int, void*) all pid_t wait4(pid_t pid, int* status, int options, struct rusage* rusage) all -# NOTE: this system call is never called directly, but we list it there -# to have __NR_clone properly defined. +# NOTE: these stubs are unused. pid_t __sys_clone:clone(int, void*, int*, void*, int*) all +pid_t _waitpid:waitpid(pid_t, int*, int, struct rusage*) mips,x86 +int __waitid:waitid(int, pid_t, struct siginfo_t*, int, void*) all int execve(const char*, char* const*, char* const*) all @@ -226,8 +225,8 @@ int timerfd_gettime(int, struct itimerspec*) all # signals int sigaction(int, const struct sigaction*, struct sigaction*) arm,x86,mips -int sigpending(sigset_t*) arm,x86,mips 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_sigprocmask:rt_sigprocmask(int, const sigset_t*, sigset_t*, size_t) all int __rt_sigsuspend:rt_sigsuspend(const sigset_t*, size_t) all int __rt_sigtimedwait:rt_sigtimedwait(const sigset_t*, struct siginfo_t*, struct timespec_t*, size_t) all diff --git a/libc/arch-arm/syscalls.mk b/libc/arch-arm/syscalls.mk index dc7e3dfdb..5e5e56bfd 100644 --- a/libc/arch-arm/syscalls.mk +++ b/libc/arch-arm/syscalls.mk @@ -3,9 +3,9 @@ syscall_src := syscall_src += arch-arm/syscalls/_exit.S syscall_src += arch-arm/syscalls/_exit_thread.S syscall_src += arch-arm/syscalls/__fork.S -syscall_src += arch-arm/syscalls/__waitid.S syscall_src += arch-arm/syscalls/wait4.S syscall_src += arch-arm/syscalls/__sys_clone.S +syscall_src += arch-arm/syscalls/__waitid.S syscall_src += arch-arm/syscalls/execve.S syscall_src += arch-arm/syscalls/getuid.S syscall_src += arch-arm/syscalls/getgid.S @@ -152,8 +152,8 @@ 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/sigpending.S syscall_src += arch-arm/syscalls/__rt_sigaction.S +syscall_src += arch-arm/syscalls/__rt_sigpending.S syscall_src += arch-arm/syscalls/__rt_sigprocmask.S syscall_src += arch-arm/syscalls/__rt_sigsuspend.S syscall_src += arch-arm/syscalls/__rt_sigtimedwait.S diff --git a/libc/arch-arm/syscalls/sigpending.S b/libc/arch-arm/syscalls/__rt_sigpending.S similarity index 76% rename from libc/arch-arm/syscalls/sigpending.S rename to libc/arch-arm/syscalls/__rt_sigpending.S index ba667a027..0e0be3a3d 100644 --- a/libc/arch-arm/syscalls/sigpending.S +++ b/libc/arch-arm/syscalls/__rt_sigpending.S @@ -3,13 +3,13 @@ #include #include -ENTRY(sigpending) +ENTRY(__rt_sigpending) mov ip, r7 - ldr r7, =__NR_sigpending + ldr r7, =__NR_rt_sigpending swi #0 mov r7, ip cmn r0, #(MAX_ERRNO + 1) bxls lr neg r0, r0 b __set_errno -END(sigpending) +END(__rt_sigpending) diff --git a/libc/arch-mips/syscalls.mk b/libc/arch-mips/syscalls.mk index 2704200ea..7d99dad7b 100644 --- a/libc/arch-mips/syscalls.mk +++ b/libc/arch-mips/syscalls.mk @@ -3,10 +3,10 @@ syscall_src := syscall_src += arch-mips/syscalls/_exit.S syscall_src += arch-mips/syscalls/_exit_thread.S syscall_src += arch-mips/syscalls/__fork.S -syscall_src += arch-mips/syscalls/_waitpid.S -syscall_src += arch-mips/syscalls/__waitid.S syscall_src += arch-mips/syscalls/wait4.S syscall_src += arch-mips/syscalls/__sys_clone.S +syscall_src += arch-mips/syscalls/_waitpid.S +syscall_src += arch-mips/syscalls/__waitid.S syscall_src += arch-mips/syscalls/execve.S syscall_src += arch-mips/syscalls/getuid.S syscall_src += arch-mips/syscalls/getgid.S @@ -155,8 +155,8 @@ 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/sigpending.S syscall_src += arch-mips/syscalls/__rt_sigaction.S +syscall_src += arch-mips/syscalls/__rt_sigpending.S syscall_src += arch-mips/syscalls/__rt_sigprocmask.S syscall_src += arch-mips/syscalls/__rt_sigsuspend.S syscall_src += arch-mips/syscalls/__rt_sigtimedwait.S diff --git a/libc/arch-mips/syscalls/sigpending.S b/libc/arch-mips/syscalls/__rt_sigpending.S similarity index 66% rename from libc/arch-mips/syscalls/sigpending.S rename to libc/arch-mips/syscalls/__rt_sigpending.S index 45baa4f64..bd4a96e60 100644 --- a/libc/arch-mips/syscalls/sigpending.S +++ b/libc/arch-mips/syscalls/__rt_sigpending.S @@ -1,14 +1,14 @@ /* autogenerated by gensyscalls.py */ #include .text - .globl sigpending + .globl __rt_sigpending .align 4 - .ent sigpending + .ent __rt_sigpending -sigpending: +__rt_sigpending: .set noreorder .cpload $t9 - li $v0, __NR_sigpending + li $v0, __NR_rt_sigpending syscall bnez $a3, 1f move $a0, $v0 @@ -19,4 +19,4 @@ sigpending: j $t9 nop .set reorder - .end sigpending + .end __rt_sigpending diff --git a/libc/arch-x86/syscalls.mk b/libc/arch-x86/syscalls.mk index 10970a6f5..698f6f5a6 100644 --- a/libc/arch-x86/syscalls.mk +++ b/libc/arch-x86/syscalls.mk @@ -3,10 +3,10 @@ syscall_src := syscall_src += arch-x86/syscalls/_exit.S syscall_src += arch-x86/syscalls/_exit_thread.S syscall_src += arch-x86/syscalls/__fork.S -syscall_src += arch-x86/syscalls/_waitpid.S -syscall_src += arch-x86/syscalls/__waitid.S syscall_src += arch-x86/syscalls/wait4.S syscall_src += arch-x86/syscalls/__sys_clone.S +syscall_src += arch-x86/syscalls/_waitpid.S +syscall_src += arch-x86/syscalls/__waitid.S syscall_src += arch-x86/syscalls/execve.S syscall_src += arch-x86/syscalls/getuid.S syscall_src += arch-x86/syscalls/getgid.S @@ -156,8 +156,8 @@ 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/sigpending.S syscall_src += arch-x86/syscalls/__rt_sigaction.S +syscall_src += arch-x86/syscalls/__rt_sigpending.S syscall_src += arch-x86/syscalls/__rt_sigprocmask.S syscall_src += arch-x86/syscalls/__rt_sigsuspend.S syscall_src += arch-x86/syscalls/__rt_sigtimedwait.S diff --git a/libc/arch-x86/syscalls/sigpending.S b/libc/arch-x86/syscalls/__rt_sigpending.S similarity index 65% rename from libc/arch-x86/syscalls/sigpending.S rename to libc/arch-x86/syscalls/__rt_sigpending.S index 70c3ec4e3..84634b495 100644 --- a/libc/arch-x86/syscalls/sigpending.S +++ b/libc/arch-x86/syscalls/__rt_sigpending.S @@ -3,10 +3,12 @@ #include #include -ENTRY(sigpending) +ENTRY(__rt_sigpending) pushl %ebx - mov 8(%esp), %ebx - movl $__NR_sigpending, %eax + pushl %ecx + mov 12(%esp), %ebx + mov 16(%esp), %ecx + movl $__NR_rt_sigpending, %eax int $0x80 cmpl $-MAX_ERRNO, %eax jb 1f @@ -16,6 +18,7 @@ ENTRY(sigpending) addl $4, %esp orl $-1, %eax 1: + popl %ecx popl %ebx ret -END(sigpending) +END(__rt_sigpending) diff --git a/libc/arch-x86_64/syscalls.mk b/libc/arch-x86_64/syscalls.mk index 6b72ca0b1..611bb35dd 100644 --- a/libc/arch-x86_64/syscalls.mk +++ b/libc/arch-x86_64/syscalls.mk @@ -3,9 +3,9 @@ syscall_src := syscall_src += arch-x86_64/syscalls/_exit.S syscall_src += arch-x86_64/syscalls/_exit_thread.S syscall_src += arch-x86_64/syscalls/__fork.S -syscall_src += arch-x86_64/syscalls/__waitid.S syscall_src += arch-x86_64/syscalls/wait4.S syscall_src += arch-x86_64/syscalls/__sys_clone.S +syscall_src += arch-x86_64/syscalls/__waitid.S syscall_src += arch-x86_64/syscalls/execve.S syscall_src += arch-x86_64/syscalls/getuid.S syscall_src += arch-x86_64/syscalls/getgid.S @@ -150,6 +150,7 @@ syscall_src += arch-x86_64/syscalls/timerfd_create.S syscall_src += arch-x86_64/syscalls/timerfd_settime.S syscall_src += arch-x86_64/syscalls/timerfd_gettime.S syscall_src += arch-x86_64/syscalls/__rt_sigaction.S +syscall_src += arch-x86_64/syscalls/__rt_sigpending.S syscall_src += arch-x86_64/syscalls/__rt_sigprocmask.S syscall_src += arch-x86_64/syscalls/__rt_sigsuspend.S syscall_src += arch-x86_64/syscalls/__rt_sigtimedwait.S diff --git a/libc/arch-x86_64/syscalls/__rt_sigpending.S b/libc/arch-x86_64/syscalls/__rt_sigpending.S new file mode 100644 index 000000000..ecf197162 --- /dev/null +++ b/libc/arch-x86_64/syscalls/__rt_sigpending.S @@ -0,0 +1,17 @@ +/* autogenerated by gensyscalls.py */ +#include +#include +#include + +ENTRY(__rt_sigpending) + movl $__NR_rt_sigpending, %eax + syscall + cmpq $-MAX_ERRNO, %rax + jb 1f + negl %eax + movl %eax, %edi + call __set_errno + orq $-1, %rax +1: + ret +END(__rt_sigpending) diff --git a/libc/bionic/sigpending.cpp b/libc/bionic/sigpending.cpp new file mode 100644 index 000000000..b6e503c56 --- /dev/null +++ b/libc/bionic/sigpending.cpp @@ -0,0 +1,42 @@ +/* + * 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 + +#include "private/kernel_sigset_t.h" + +extern "C" int __rt_sigpending(const kernel_sigset_t*, size_t); + +int sigpending(sigset_t* bionic_set) { + kernel_sigset_t set; + int result = __rt_sigpending(&set, sizeof(set)); + if (result != -1) { + *bionic_set = set.bionic; + } + return result; +} diff --git a/libc/include/signal.h b/libc/include/signal.h index 15d2d3a68..e211ef758 100644 --- a/libc/include/signal.h +++ b/libc/include/signal.h @@ -122,24 +122,20 @@ static __inline__ __sighandler_t signal(int s, __sighandler_t f) return bsd_signal(s,f); } -/* the syscall itself */ -extern __sighandler_t __signal(int, __sighandler_t, int); - -extern int sigprocmask(int, const sigset_t *, sigset_t *); -extern int sigaction(int, const struct sigaction *, struct sigaction *); - -extern int sigpending(sigset_t *); -extern int sigsuspend(const sigset_t *); -extern int sigwait(const sigset_t *set, int *sig); -extern int siginterrupt(int sig, int flag); +extern int sigaction(int, const struct sigaction*, struct sigaction*); +extern int siginterrupt(int, int); +extern int sigpending(sigset_t*) __nonnull((1)); +extern int sigprocmask(int, const sigset_t*, sigset_t*); +extern int sigsuspend(const sigset_t*) __nonnull((1)); +extern int sigwait(const sigset_t*, int*) __nonnull((1, 2)); extern int raise(int); extern int kill(pid_t, int); -extern int killpg(int pgrp, int sig); -extern int sigaltstack(const stack_t *ss, stack_t *oss); +extern int killpg(int, int); +extern int sigaltstack(const stack_t*, stack_t*); -extern void psiginfo(const siginfo_t* si, const char* message); -extern void psignal(int signal_number, const char* message); +extern void psiginfo(const siginfo_t*, const char*); +extern void psignal(int, const char*); __END_DECLS diff --git a/tests/signal_test.cpp b/tests/signal_test.cpp index 70e9017cd..a719fe786 100644 --- a/tests/signal_test.cpp +++ b/tests/signal_test.cpp @@ -19,6 +19,28 @@ #include #include +static size_t SIGNAL_MIN() { + return 1; // Signals start at 1 (SIGHUP), not 0. +} + +static size_t SIGNAL_MAX() { + size_t result = SIGRTMAX; + +#if defined(__BIONIC__) && !defined(__mips__) && !defined(__LP64__) + // 32-bit bionic's sigset_t is too small for ARM and x86: 32 bits instead of 64. + // This means you can't refer to any of the real-time signals. + // See http://b/3038348 and http://b/5828899. + result = 32; +#else + // Otherwise, C libraries should be perfectly capable of using their largest signal. + if (sizeof(sigset_t) * 8 < static_cast(SIGRTMAX)) { + abort(); + } +#endif + + return result; +} + template static void TestSigSet1(Fn fn) { // NULL sigset_t*. @@ -45,19 +67,6 @@ static void TestSigSet2(Fn fn) { sigset_t set; sigemptyset(&set); - int min_signal = SIGHUP; - int max_signal = SIGRTMAX; - -#if defined(__BIONIC__) && !defined(__mips__) - // bionic's sigset_t is too small for ARM and x86: 32 bits instead of 64. - // This means you can't refer to any of the real-time signals. - // See http://b/3038348 and http://b/5828899. - max_signal = 32; -#else - // Other C libraries (or bionic for MIPS) are perfectly capable of using their largest signal. - ASSERT_GE(sizeof(sigset_t) * 8, static_cast(SIGRTMAX)); -#endif - // Bad signal number: too small. errno = 0; ASSERT_EQ(-1, fn(&set, 0)); @@ -65,14 +74,14 @@ static void TestSigSet2(Fn fn) { // Bad signal number: too high. errno = 0; - ASSERT_EQ(-1, fn(&set, max_signal + 1)); + ASSERT_EQ(-1, fn(&set, SIGNAL_MAX() + 1)); ASSERT_EQ(EINVAL, errno); // Good signal numbers, low and high ends of range. errno = 0; - ASSERT_EQ(0, fn(&set, min_signal)); + ASSERT_EQ(0, fn(&set, SIGNAL_MIN())); ASSERT_EQ(0, errno); - ASSERT_EQ(0, fn(&set, max_signal)); + ASSERT_EQ(0, fn(&set, SIGNAL_MAX())); ASSERT_EQ(0, errno); } @@ -160,7 +169,7 @@ static void SigSuspendTestHelper(int) { ++gSigSuspendTestHelperCallCount; } -TEST(signal, sigsuspend) { +TEST(signal, sigsuspend_sigpending) { ScopedSignalHandler ssh(SIGALRM, SigSuspendTestHelper); // Block SIGALRM. @@ -170,10 +179,25 @@ TEST(signal, sigsuspend) { sigset_t original_set; ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGALRM, &original_set)); + // There should be no pending signals. + sigset_t pending; + sigemptyset(&pending); + ASSERT_EQ(0, sigpending(&pending)); + for (size_t i = SIGNAL_MIN(); i <= SIGNAL_MAX(); ++i) { + EXPECT_FALSE(sigismember(&pending, i)) << i; + } + // Raise SIGALRM and check our signal handler wasn't called. raise(SIGALRM); ASSERT_EQ(0, gSigSuspendTestHelperCallCount); + // We should now have a pending SIGALRM but nothing else. + sigemptyset(&pending); + ASSERT_EQ(0, sigpending(&pending)); + for (size_t i = SIGNAL_MIN(); i <= SIGNAL_MAX(); ++i) { + EXPECT_EQ((i == SIGALRM), sigismember(&pending, i)); + } + // Use sigsuspend to block everything except SIGALRM... sigset_t not_SIGALRM; sigfillset(¬_SIGALRM);