diff --git a/libc/Android.mk b/libc/Android.mk index 58d8a58ae..3b1677368 100644 --- a/libc/Android.mk +++ b/libc/Android.mk @@ -284,6 +284,7 @@ libc_bionic_src_files := \ bionic/raise.cpp \ bionic/__set_errno.cpp \ bionic/setlocale.cpp \ + bionic/signalfd.cpp \ bionic/__strcat_chk.cpp \ bionic/__strcpy_chk.cpp \ bionic/strerror.cpp \ diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT index 2973caaaa..dc139bd93 100644 --- a/libc/SYSCALLS.TXT +++ b/libc/SYSCALLS.TXT @@ -225,6 +225,7 @@ int __rt_sigaction:rt_sigaction (int sig, const struct sigaction *act, struc int __rt_sigprocmask:rt_sigprocmask (int how, const sigset_t *set, sigset_t *oset, size_t sigsetsize) 175,175,195 int __rt_sigtimedwait:rt_sigtimedwait(const sigset_t *set, struct siginfo_t *info, struct timespec_t *timeout, size_t sigset_size) 177,177,197 int sigpending(sigset_t *) 73 +int signalfd4(int fd, const sigset_t *mask, size_t sizemask, int flags) 355,327,324 # sockets int socket(int, int, int) 281,-1,183 diff --git a/libc/arch-arm/syscalls.mk b/libc/arch-arm/syscalls.mk index 62eda8700..5cb46b5e7 100644 --- a/libc/arch-arm/syscalls.mk +++ b/libc/arch-arm/syscalls.mk @@ -150,6 +150,7 @@ syscall_src += arch-arm/syscalls/__rt_sigaction.S syscall_src += arch-arm/syscalls/__rt_sigprocmask.S syscall_src += arch-arm/syscalls/__rt_sigtimedwait.S syscall_src += arch-arm/syscalls/sigpending.S +syscall_src += arch-arm/syscalls/signalfd4.S syscall_src += arch-arm/syscalls/socket.S syscall_src += arch-arm/syscalls/socketpair.S syscall_src += arch-arm/syscalls/bind.S diff --git a/libc/arch-arm/syscalls/signalfd4.S b/libc/arch-arm/syscalls/signalfd4.S new file mode 100644 index 000000000..1ec705510 --- /dev/null +++ b/libc/arch-arm/syscalls/signalfd4.S @@ -0,0 +1,14 @@ +/* autogenerated by gensyscalls.py */ +#include +#include + +ENTRY(signalfd4) + .save {r4, r7} + stmfd sp!, {r4, r7} + ldr r7, =__NR_signalfd4 + swi #0 + ldmfd sp!, {r4, r7} + movs r0, r0 + bxpl lr + b __set_syscall_errno +END(signalfd4) diff --git a/libc/arch-mips/syscalls.mk b/libc/arch-mips/syscalls.mk index 263f3078d..7e40c2eea 100644 --- a/libc/arch-mips/syscalls.mk +++ b/libc/arch-mips/syscalls.mk @@ -153,6 +153,7 @@ syscall_src += arch-mips/syscalls/__rt_sigaction.S syscall_src += arch-mips/syscalls/__rt_sigprocmask.S syscall_src += arch-mips/syscalls/__rt_sigtimedwait.S syscall_src += arch-mips/syscalls/sigpending.S +syscall_src += arch-mips/syscalls/signalfd4.S syscall_src += arch-mips/syscalls/socket.S syscall_src += arch-mips/syscalls/socketpair.S syscall_src += arch-mips/syscalls/bind.S diff --git a/libc/arch-mips/syscalls/signalfd4.S b/libc/arch-mips/syscalls/signalfd4.S new file mode 100644 index 000000000..7e4082c55 --- /dev/null +++ b/libc/arch-mips/syscalls/signalfd4.S @@ -0,0 +1,22 @@ +/* autogenerated by gensyscalls.py */ +#include + .text + .globl signalfd4 + .align 4 + .ent signalfd4 + +signalfd4: + .set noreorder + .cpload $t9 + li $v0, __NR_signalfd4 + syscall + bnez $a3, 1f + move $a0, $v0 + j $ra + nop +1: + la $t9,__set_errno + j $t9 + nop + .set reorder + .end signalfd4 diff --git a/libc/arch-x86/syscalls.mk b/libc/arch-x86/syscalls.mk index 2517ebfeb..e196c022b 100644 --- a/libc/arch-x86/syscalls.mk +++ b/libc/arch-x86/syscalls.mk @@ -154,6 +154,7 @@ syscall_src += arch-x86/syscalls/__rt_sigaction.S syscall_src += arch-x86/syscalls/__rt_sigprocmask.S syscall_src += arch-x86/syscalls/__rt_sigtimedwait.S syscall_src += arch-x86/syscalls/sigpending.S +syscall_src += arch-x86/syscalls/signalfd4.S syscall_src += arch-x86/syscalls/socket.S syscall_src += arch-x86/syscalls/bind.S syscall_src += arch-x86/syscalls/connect.S diff --git a/libc/arch-x86/syscalls/signalfd4.S b/libc/arch-x86/syscalls/signalfd4.S new file mode 100644 index 000000000..f1c2ea020 --- /dev/null +++ b/libc/arch-x86/syscalls/signalfd4.S @@ -0,0 +1,32 @@ +/* autogenerated by gensyscalls.py */ +#include + + .text + .type signalfd4, @function + .globl signalfd4 + .align 4 + +signalfd4: + pushl %ebx + pushl %ecx + pushl %edx + pushl %esi + mov 20(%esp), %ebx + mov 24(%esp), %ecx + mov 28(%esp), %edx + mov 32(%esp), %esi + movl $__NR_signalfd4, %eax + int $0x80 + cmpl $-129, %eax + jb 1f + negl %eax + pushl %eax + call __set_errno + addl $4, %esp + orl $-1, %eax +1: + popl %esi + popl %edx + popl %ecx + popl %ebx + ret diff --git a/libc/bionic/signalfd.cpp b/libc/bionic/signalfd.cpp new file mode 100644 index 000000000..51fae8361 --- /dev/null +++ b/libc/bionic/signalfd.cpp @@ -0,0 +1,54 @@ +/* + * 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 + +/* Despite the fact that our kernel headers define sigset_t explicitly + * as a 32-bit integer, the kernel system call really expects a 64-bit + * bitmap for the signal set, or more exactly an array of two-32-bit + * values (see $KERNEL/arch/$ARCH/include/asm/signal.h for details). + * + * Unfortunately, we cannot fix the sigset_t definition without breaking + * the C library ABI, so perform a little runtime translation here. + */ +typedef union { + sigset_t bionic; + uint32_t kernel[2]; +} kernel_sigset_t; + +extern "C" int signalfd4(int fd, kernel_sigset_t *mask, size_t sizemask, int flags); + +int signalfd(int fd, const sigset_t *mask, int flags) +{ + kernel_sigset_t in_set; + in_set.kernel[0] = in_set.kernel[1] = 0; + + in_set.bionic = *mask; + + return signalfd4(fd, &in_set, sizeof(in_set), flags); +} diff --git a/libc/include/sys/linux-syscalls.h b/libc/include/sys/linux-syscalls.h index ec48adad3..738d9e8a3 100644 --- a/libc/include/sys/linux-syscalls.h +++ b/libc/include/sys/linux-syscalls.h @@ -173,6 +173,7 @@ #define __NR_rt_sigaction (__NR_SYSCALL_BASE + 174) #define __NR_rt_sigprocmask (__NR_SYSCALL_BASE + 175) #define __NR_rt_sigtimedwait (__NR_SYSCALL_BASE + 177) +#define __NR_signalfd4 (__NR_SYSCALL_BASE + 355) #define __NR_socket (__NR_SYSCALL_BASE + 281) #define __NR_socketpair (__NR_SYSCALL_BASE + 288) #define __NR_bind (__NR_SYSCALL_BASE + 282) @@ -329,6 +330,7 @@ #define __NR_unshare (__NR_SYSCALL_BASE + 310) #define __NR_getcpu (__NR_SYSCALL_BASE + 318) #define __NR_utimensat (__NR_SYSCALL_BASE + 320) +#define __NR_signalfd4 (__NR_SYSCALL_BASE + 327) #define __NR_eventfd2 (__NR_SYSCALL_BASE + 328) #define __NR_pipe2 (__NR_SYSCALL_BASE + 331) #define __NR_perf_event_open (__NR_SYSCALL_BASE + 336) @@ -463,6 +465,7 @@ #define __NR_ioprio_set (__NR_SYSCALL_BASE + 314) #define __NR_ioprio_get (__NR_SYSCALL_BASE + 315) #define __NR_utimensat (__NR_SYSCALL_BASE + 316) +#define __NR_signalfd4 (__NR_SYSCALL_BASE + 324) #define __NR_eventfd2 (__NR_SYSCALL_BASE + 325) #define __NR_pipe2 (__NR_SYSCALL_BASE + 328) #define __NR_perf_event_open (__NR_SYSCALL_BASE + 333) diff --git a/libc/include/sys/signalfd.h b/libc/include/sys/signalfd.h new file mode 100644 index 000000000..af1f29051 --- /dev/null +++ b/libc/include/sys/signalfd.h @@ -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. + */ +#ifndef _SYS_SIGNALFD_H_ +#define _SYS_SIGNALFD_H_ + +#include +#include +#include + +__BEGIN_DECLS + +/* Compatibility with GLibc */ +extern int signalfd(int fd, const sigset_t *mask, int flags); + +__END_DECLS + +#endif /* _SYS_SIGNALFD_H */ diff --git a/libc/kernel/common/linux/signalfd.h b/libc/kernel/common/linux/signalfd.h new file mode 100644 index 000000000..a06419295 --- /dev/null +++ b/libc/kernel/common/linux/signalfd.h @@ -0,0 +1,51 @@ +/**************************************************************************** + **************************************************************************** + *** + *** This header was automatically generated from a Linux kernel header + *** of the same name, to make information necessary for userspace to + *** call into the kernel available to libc. It contains only constants, + *** structures, and macros generated from the original header, and thus, + *** contains no copyrightable information. + *** + *** To edit the content of this header, modify the corresponding + *** source file (e.g. under external/kernel-headers/original/) then + *** run bionic/libc/kernel/tools/update_all.py + *** + *** Any manual change here will be lost the next time this script will + *** be run. You've been warned! + *** + **************************************************************************** + ****************************************************************************/ +#ifndef _LINUX_SIGNALFD_H +#define _LINUX_SIGNALFD_H +#include +#include +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#define SFD_CLOEXEC O_CLOEXEC +#define SFD_NONBLOCK O_NONBLOCK +struct signalfd_siginfo { + __u32 ssi_signo; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __s32 ssi_errno; + __s32 ssi_code; + __u32 ssi_pid; + __u32 ssi_uid; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __s32 ssi_fd; + __u32 ssi_tid; + __u32 ssi_band; + __u32 ssi_overrun; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __u32 ssi_trapno; + __s32 ssi_status; + __s32 ssi_int; + __u64 ssi_ptr; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __u64 ssi_utime; + __u64 ssi_stime; + __u64 ssi_addr; + __u16 ssi_addr_lsb; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __u8 __pad[46]; +}; +#endif