diff options
Diffstat (limited to 'libc')
28 files changed, 471 insertions, 365 deletions
diff --git a/libc/Android.bp b/libc/Android.bp index 2ea851466..0f5820459 100644 --- a/libc/Android.bp +++ b/libc/Android.bp @@ -1248,9 +1248,6 @@ cc_library_static { "bionic/dirent.cpp", "bionic/dup2.cpp", "bionic/environ.cpp", - "bionic/epoll_create.cpp", - "bionic/epoll_pwait.cpp", - "bionic/epoll_wait.cpp", "bionic/error.cpp", "bionic/eventfd_read.cpp", "bionic/eventfd_write.cpp", @@ -1350,6 +1347,7 @@ cc_library_static { "bionic/swab.cpp", "bionic/symlink.cpp", "bionic/sync_file_range.cpp", + "bionic/sys_epoll.cpp", "bionic/sys_msg.cpp", "bionic/sys_sem.cpp", "bionic/sys_shm.cpp", @@ -1431,7 +1429,6 @@ cc_library_static { "bionic/pthread_self.cpp", "bionic/pthread_setname_np.cpp", "bionic/pthread_setschedparam.cpp", - "bionic/pthread_sigmask.cpp", "bionic/pthread_spinlock.cpp", // The following implementations depend on pthread data or implementation, diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT index 5c9a284fe..5c63c0f17 100644 --- a/libc/SYSCALLS.TXT +++ b/libc/SYSCALLS.TXT @@ -229,12 +229,12 @@ int clock_adjtime(clockid_t, struct timex*) all # signals 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_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*, siginfo_t*, const timespec*, size_t) all +int __rt_sigpending:rt_sigpending(sigset64_t*, size_t) all +int __rt_sigprocmask:rt_sigprocmask(int, const sigset64_t*, sigset64_t*, size_t) all +int __rt_sigsuspend:rt_sigsuspend(const sigset64_t*, size_t) all +int __rt_sigtimedwait:rt_sigtimedwait(const sigset64_t*, siginfo_t*, const timespec*, size_t) all int ___rt_sigqueueinfo:rt_sigqueueinfo(pid_t, int, siginfo_t*) all -int __signalfd4:signalfd4(int, const sigset_t*, size_t, int) all +int __signalfd4:signalfd4(int, const sigset64_t*, size_t, int) all # sockets int __socket:socket(int, int, int) arm,arm64,mips,mips64,x86_64 @@ -305,7 +305,7 @@ ssize_t vmsplice(int, const struct iovec*, size_t, unsigned int) all int epoll_create1(int) all int epoll_ctl(int, int op, int, struct epoll_event*) all -int __epoll_pwait:epoll_pwait(int, struct epoll_event*, int, int, const sigset_t*, size_t) all +int __epoll_pwait:epoll_pwait(int, struct epoll_event*, int, int, const sigset64_t*, size_t) all int eventfd:eventfd2(unsigned int, int) all @@ -317,7 +317,7 @@ int inotify_add_watch(int, const char*, unsigned int) all int inotify_rm_watch(int, unsigned int) all int __pselect6:pselect6(int, fd_set*, fd_set*, fd_set*, timespec*, void*) all -int __ppoll:ppoll(pollfd*, unsigned int, timespec*, const sigset_t*, size_t) all +int __ppoll:ppoll(pollfd*, unsigned int, timespec*, const sigset64_t*, size_t) all ssize_t process_vm_readv(pid_t, const struct iovec*, unsigned long, const struct iovec*, unsigned long, unsigned long) all ssize_t process_vm_writev(pid_t, const struct iovec*, unsigned long, const struct iovec*, unsigned long, unsigned long) all diff --git a/libc/bionic/abort.cpp b/libc/bionic/abort.cpp index 9f1c31f3d..ec26a50c4 100644 --- a/libc/bionic/abort.cpp +++ b/libc/bionic/abort.cpp @@ -32,8 +32,6 @@ #include <sys/syscall.h> #include <unistd.h> -#include "private/kernel_sigset_t.h" - // We call tgkill(2) directly instead of raise (or even the libc tgkill wrapper), to reduce the // number of uninteresting stack frames at the top of a crash. static inline __always_inline void inline_tgkill(pid_t pid, pid_t tid, int sig) { @@ -62,11 +60,11 @@ void abort() { // Don't block SIGABRT to give any signal handler a chance; we ignore // any errors -- X311J doesn't allow abort to return anyway. - kernel_sigset_t mask; - mask.fill(); - mask.clear(SIGABRT); - __rt_sigprocmask(SIG_SETMASK, &mask, nullptr, sizeof(mask)); + sigset64_t mask; + sigfillset64(&mask); + sigdelset64(&mask, SIGABRT); + sigprocmask64(SIG_SETMASK, &mask, nullptr); inline_tgkill(pid, tid, SIGABRT); // If SIGABRT ignored, or caught and the handler returns, @@ -76,8 +74,8 @@ void abort() { sa.sa_flags = SA_RESTART; sigemptyset(&sa.sa_mask); sigaction(SIGABRT, &sa, &sa); - __rt_sigprocmask(SIG_SETMASK, &mask, nullptr, sizeof(mask)); + sigprocmask64(SIG_SETMASK, &mask, nullptr); inline_tgkill(pid, tid, SIGABRT); // If we get this far, just exit. diff --git a/libc/bionic/epoll_wait.cpp b/libc/bionic/epoll_wait.cpp deleted file mode 100644 index deb19daf2..000000000 --- a/libc/bionic/epoll_wait.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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 <sys/epoll.h> - -int epoll_wait(int fd, struct epoll_event* events, int max_events, int timeout) { - return epoll_pwait(fd, events, max_events, timeout, NULL); -} diff --git a/libc/bionic/pause.cpp b/libc/bionic/pause.cpp index 2a0779a5c..534a80430 100644 --- a/libc/bionic/pause.cpp +++ b/libc/bionic/pause.cpp @@ -26,12 +26,10 @@ * SUCH DAMAGE. */ +#include <signal.h> #include <unistd.h> -#include "private/kernel_sigset_t.h" - int pause() { - kernel_sigset_t mask; - if (__rt_sigprocmask(SIG_SETMASK, nullptr, &mask, sizeof(mask)) == -1) return -1; - return __rt_sigsuspend(&mask, sizeof(mask)); + sigset64_t mask = {}; + return sigsuspend64(&mask); } diff --git a/libc/bionic/poll.cpp b/libc/bionic/poll.cpp index dbc9584e9..1d72fe5b4 100644 --- a/libc/bionic/poll.cpp +++ b/libc/bionic/poll.cpp @@ -31,51 +31,56 @@ #include <sys/select.h> #include "private/bionic_time_conversions.h" -#include "private/kernel_sigset_t.h" +#include "private/SigSetConverter.h" -extern "C" int __ppoll(pollfd*, unsigned int, timespec*, const kernel_sigset_t*, size_t); +extern "C" int __ppoll(pollfd*, unsigned int, timespec*, const sigset64_t*, size_t); extern "C" int __pselect6(int, fd_set*, fd_set*, fd_set*, timespec*, void*); int poll(pollfd* fds, nfds_t fd_count, int ms) __overloadable { timespec ts; - timespec* ts_ptr = NULL; + timespec* ts_ptr = nullptr; if (ms >= 0) { timespec_from_ms(ts, ms); ts_ptr = &ts; } - return __ppoll(fds, fd_count, ts_ptr, NULL, 0); + return __ppoll(fds, fd_count, ts_ptr, nullptr, 0); } int ppoll(pollfd* fds, nfds_t fd_count, const timespec* ts, const sigset_t* ss) __overloadable { + // The underlying `__ppoll` system call only takes `sigset64_t`. + SigSetConverter set; + sigset64_t* ss_ptr = nullptr; + if (ss != nullptr) { + set = {}; + set.sigset = *ss; + ss_ptr = &set.sigset64; + } + return ppoll64(fds, fd_count, ts, ss_ptr); +} + +int ppoll64(pollfd* fds, nfds_t fd_count, const timespec* ts, const sigset64_t* ss) { + // The underlying __ppoll system call modifies its `struct timespec` argument. timespec mutable_ts; - timespec* mutable_ts_ptr = NULL; - if (ts != NULL) { + timespec* mutable_ts_ptr = nullptr; + if (ts != nullptr) { mutable_ts = *ts; mutable_ts_ptr = &mutable_ts; } - - kernel_sigset_t kernel_ss; - kernel_sigset_t* kernel_ss_ptr = NULL; - if (ss != NULL) { - kernel_ss.set(ss); - kernel_ss_ptr = &kernel_ss; - } - - return __ppoll(fds, fd_count, mutable_ts_ptr, kernel_ss_ptr, sizeof(kernel_ss)); + return __ppoll(fds, fd_count, mutable_ts_ptr, ss, sizeof(*ss)); } int select(int fd_count, fd_set* read_fds, fd_set* write_fds, fd_set* error_fds, timeval* tv) { timespec ts; - timespec* ts_ptr = NULL; - if (tv != NULL) { + timespec* ts_ptr = nullptr; + if (tv != nullptr) { if (!timespec_from_timeval(ts, *tv)) { errno = EINVAL; return -1; } ts_ptr = &ts; } - int result = __pselect6(fd_count, read_fds, write_fds, error_fds, ts_ptr, NULL); - if (tv != NULL) { + int result = __pselect6(fd_count, read_fds, write_fds, error_fds, ts_ptr, nullptr); + if (tv != nullptr) { timeval_from_timespec(*tv, ts); } return result; @@ -83,20 +88,27 @@ int select(int fd_count, fd_set* read_fds, fd_set* write_fds, fd_set* error_fds, int pselect(int fd_count, fd_set* read_fds, fd_set* write_fds, fd_set* error_fds, const timespec* ts, const sigset_t* ss) { + // The underlying `__pselect6` system call only takes `sigset64_t`. + SigSetConverter set; + sigset64_t* ss_ptr = nullptr; + if (ss != nullptr) { + set = {}; + set.sigset = *ss; + ss_ptr = &set.sigset64; + } + return pselect64(fd_count, read_fds, write_fds, error_fds, ts, ss_ptr); +} + +int pselect64(int fd_count, fd_set* read_fds, fd_set* write_fds, fd_set* error_fds, + const timespec* ts, const sigset64_t* ss) { + // The underlying __pselect6 system call modifies its `struct timespec` argument. timespec mutable_ts; - timespec* mutable_ts_ptr = NULL; - if (ts != NULL) { + timespec* mutable_ts_ptr = nullptr; + if (ts != nullptr) { mutable_ts = *ts; mutable_ts_ptr = &mutable_ts; } - kernel_sigset_t kernel_ss; - kernel_sigset_t* kernel_ss_ptr = NULL; - if (ss != NULL) { - kernel_ss.set(ss); - kernel_ss_ptr = &kernel_ss; - } - // The Linux kernel only handles 6 arguments and this system call really needs 7, // so the last argument is a void* pointing to: struct pselect6_extra_data_t { @@ -104,8 +116,8 @@ int pselect(int fd_count, fd_set* read_fds, fd_set* write_fds, fd_set* error_fds size_t ss_len; }; pselect6_extra_data_t extra_data; - extra_data.ss_addr = reinterpret_cast<uintptr_t>(kernel_ss_ptr); - extra_data.ss_len = sizeof(kernel_ss); + extra_data.ss_addr = reinterpret_cast<uintptr_t>(ss); + extra_data.ss_len = sizeof(*ss); return __pselect6(fd_count, read_fds, write_fds, error_fds, mutable_ts_ptr, &extra_data); } diff --git a/libc/bionic/posix_timers.cpp b/libc/bionic/posix_timers.cpp index e3bb112fb..2edfe9701 100644 --- a/libc/bionic/posix_timers.cpp +++ b/libc/bionic/posix_timers.cpp @@ -26,8 +26,6 @@ * SUCH DAMAGE. */ -#include "private/kernel_sigset_t.h" - #include <errno.h> #include <malloc.h> #include <pthread.h> @@ -37,7 +35,6 @@ #include <time.h> // System calls. -extern "C" int __rt_sigtimedwait(const sigset_t*, siginfo_t*, const timespec*, size_t); extern "C" int __timer_create(clockid_t, sigevent*, __kernel_timer_t*); extern "C" int __timer_delete(__kernel_timer_t); extern "C" int __timer_getoverrun(__kernel_timer_t); @@ -74,16 +71,13 @@ static __kernel_timer_t to_kernel_timer_id(timer_t timer) { static void* __timer_thread_start(void* arg) { PosixTimer* timer = reinterpret_cast<PosixTimer*>(arg); - kernel_sigset_t sigset{TIMER_SIGNAL}; + sigset64_t sigset = {}; + sigaddset64(&sigset, TIMER_SIGNAL); while (true) { // Wait for a signal... - siginfo_t si; - memset(&si, 0, sizeof(si)); - int rc = __rt_sigtimedwait(sigset.get(), &si, NULL, sizeof(sigset)); - if (rc == -1) { - continue; - } + siginfo_t si = {}; + if (sigtimedwait64(&sigset, &si, nullptr) == -1) continue; if (si.si_code == SI_TIMER) { // This signal was sent because a timer fired, so call the callback. @@ -149,13 +143,14 @@ int timer_create(clockid_t clock_id, sigevent* evp, timer_t* timer_id) { // We start the thread with TIMER_SIGNAL blocked by blocking the signal here and letting it // inherit. If it tried to block the signal itself, there would be a race. - kernel_sigset_t sigset{TIMER_SIGNAL}; - kernel_sigset_t old_sigset; - __rt_sigprocmask(SIG_BLOCK, &sigset, &old_sigset, sizeof(sigset)); + sigset64_t sigset = {}; + sigaddset64(&sigset, TIMER_SIGNAL); + sigset64_t old_sigset; + sigprocmask64(SIG_BLOCK, &sigset, &old_sigset); int rc = pthread_create(&timer->callback_thread, &thread_attributes, __timer_thread_start, timer); - __rt_sigprocmask(SIG_SETMASK, &old_sigset, nullptr, sizeof(sigset)); + sigprocmask64(SIG_SETMASK, &old_sigset, nullptr); if (rc != 0) { free(timer); diff --git a/libc/bionic/pthread_sigmask.cpp b/libc/bionic/pthread_sigmask.cpp deleted file mode 100644 index 79f31a145..000000000 --- a/libc/bionic/pthread_sigmask.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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 <errno.h> -#include <pthread.h> -#include <signal.h> - -#include "private/ErrnoRestorer.h" - -int pthread_sigmask(int how, const sigset_t* new_set, sigset_t* old_set) { - ErrnoRestorer errno_restorer; - int result = sigprocmask(how, new_set, old_set); - return (result == -1) ? errno : 0; -} diff --git a/libc/bionic/signal.cpp b/libc/bionic/signal.cpp index 9a2341604..099944ad8 100644 --- a/libc/bionic/signal.cpp +++ b/libc/bionic/signal.cpp @@ -30,19 +30,36 @@ #include <pthread.h> #include <signal.h> #include <string.h> +#include <sys/epoll.h> +#include <sys/signalfd.h> #include <sys/types.h> #include <time.h> #include <unistd.h> -#include "private/kernel_sigset_t.h" +#include "private/ErrnoRestorer.h" +#include "private/SigSetConverter.h" +extern "C" int __rt_sigpending(const sigset64_t*, size_t); +extern "C" int __rt_sigprocmask(int, const sigset64_t*, sigset64_t*, size_t); extern "C" int ___rt_sigqueueinfo(pid_t, int, siginfo_t*); -extern "C" int __rt_sigtimedwait(const sigset_t*, siginfo_t*, const timespec*, size_t); +extern "C" int __rt_sigsuspend(const sigset64_t*, size_t); +extern "C" int __rt_sigtimedwait(const sigset64_t*, siginfo_t*, const timespec*, size_t); -int sigaddset(sigset_t* set, int signum) { - int bit = signum - 1; // Signal numbers start at 1, but bit positions start at 0. +int pthread_sigmask(int how, const sigset_t* new_set, sigset_t* old_set) { + ErrnoRestorer errno_restorer; + return (sigprocmask(how, new_set, old_set) == -1) ? errno : 0; +} + +int pthread_sigmask64(int how, const sigset64_t* new_set, sigset64_t* old_set) { + ErrnoRestorer errno_restorer; + return (sigprocmask64(how, new_set, old_set) == -1) ? errno : 0; +} + +template <typename SigSetT> +int SigAddSet(SigSetT* set, int sig) { + int bit = sig - 1; // Signal numbers start at 1, but bit positions start at 0. unsigned long* local_set = reinterpret_cast<unsigned long*>(set); - if (set == NULL || bit < 0 || bit >= static_cast<int>(8*sizeof(sigset_t))) { + if (set == nullptr || bit < 0 || bit >= static_cast<int>(8*sizeof(*set))) { errno = EINVAL; return -1; } @@ -50,24 +67,28 @@ int sigaddset(sigset_t* set, int signum) { return 0; } -// This isn't in our header files, but is exposed on all architectures. -extern "C" int sigblock(int mask) { - union { - int mask; - sigset_t set; - } in, out; +int sigaddset(sigset_t* set, int sig) { + return SigAddSet(set, sig); +} - sigemptyset(&in.set); - in.mask = mask; +int sigaddset64(sigset64_t* set, int sig) { + return SigAddSet(set, sig); +} - if (sigprocmask(SIG_BLOCK, &in.set, &out.set) == -1) return -1; - return out.mask; +// This isn't in our header files, but is exposed on all architectures. +extern "C" int sigblock(int mask) { + SigSetConverter in, out; + sigemptyset(&in.sigset); + in.bsd = mask; + if (sigprocmask(SIG_BLOCK, &in.sigset, &out.sigset) == -1) return -1; + return out.bsd; } -int sigdelset(sigset_t* set, int signum) { - int bit = signum - 1; // Signal numbers start at 1, but bit positions start at 0. +template <typename SigSetT> +int SigDelSet(SigSetT* set, int sig) { + int bit = sig - 1; // Signal numbers start at 1, but bit positions start at 0. unsigned long* local_set = reinterpret_cast<unsigned long*>(set); - if (set == NULL || bit < 0 || bit >= static_cast<int>(8*sizeof(sigset_t))) { + if (set == nullptr || bit < 0 || bit >= static_cast<int>(8*sizeof(*set))) { errno = EINVAL; return -1; } @@ -75,29 +96,54 @@ int sigdelset(sigset_t* set, int signum) { return 0; } -int sigemptyset(sigset_t* set) { - if (set == NULL) { +int sigdelset(sigset_t* set, int sig) { + return SigDelSet(set, sig); +} + +int sigdelset64(sigset64_t* set, int sig) { + return SigDelSet(set, sig); +} + +template <typename SigSetT> +int SigEmptySet(SigSetT* set) { + if (set == nullptr) { errno = EINVAL; return -1; } - memset(set, 0, sizeof(sigset_t)); + memset(set, 0, sizeof(*set)); return 0; } -int sigfillset(sigset_t* set) { - if (set == NULL) { +int sigemptyset(sigset_t* set) { + return SigEmptySet(set); +} + +int sigemptyset64(sigset64_t* set) { + return SigEmptySet(set); +} + +template <typename SigSetT> +int SigFillSet(SigSetT* set) { + if (set == nullptr) { errno = EINVAL; return -1; } - memset(set, ~0, sizeof(sigset_t)); + memset(set, 0xff, sizeof(*set)); return 0; } +int sigfillset(sigset_t* set) { + return SigFillSet(set); +} + +int sigfillset64(sigset64_t* set) { + return SigFillSet(set); +} + int sighold(int sig) { - kernel_sigset_t set; - set.clear(); - if (!set.set(sig)) return -1; - return __rt_sigprocmask(SIG_BLOCK, &set, nullptr, sizeof(set)); + sigset64_t set = {}; + if (sigaddset64(&set, sig) == -1) return -1; + return sigprocmask64(SIG_BLOCK, &set, nullptr); } int sigignore(int sig) { @@ -119,87 +165,100 @@ int siginterrupt(int sig, int flag) { return sigaction(sig, &act, nullptr); } -int sigismember(const sigset_t* set, int signum) { - int bit = signum - 1; // Signal numbers start at 1, but bit positions start at 0. +template <typename SigSetT> +int SigIsMember(const SigSetT* set, int sig) { + int bit = sig - 1; // Signal numbers start at 1, but bit positions start at 0. const unsigned long* local_set = reinterpret_cast<const unsigned long*>(set); - if (set == NULL || bit < 0 || bit >= static_cast<int>(8*sizeof(sigset_t))) { + if (set == nullptr || bit < 0 || bit >= static_cast<int>(8*sizeof(*set))) { errno = EINVAL; return -1; } return static_cast<int>((local_set[bit / LONG_BIT] >> (bit % LONG_BIT)) & 1); } -__LIBC_HIDDEN__ sighandler_t _signal(int signum, sighandler_t handler, int flags) { +int sigismember(const sigset_t* set, int sig) { + return SigIsMember(set, sig); +} + +int sigismember64(const sigset64_t* set, int sig) { + return SigIsMember(set, sig); +} + +__LIBC_HIDDEN__ sighandler_t _signal(int sig, sighandler_t handler, int flags) { struct sigaction sa; sigemptyset(&sa.sa_mask); sa.sa_handler = handler; sa.sa_flags = flags; - if (sigaction(signum, &sa, &sa) == -1) { + if (sigaction(sig, &sa, &sa) == -1) { return SIG_ERR; } return sa.sa_handler; } -sighandler_t signal(int signum, sighandler_t handler) { - return _signal(signum, handler, SA_RESTART); +sighandler_t signal(int sig, sighandler_t handler) { + return _signal(sig, handler, SA_RESTART); } int sigpause(int sig) { - kernel_sigset_t set; - set.clear(); - if (__rt_sigprocmask(SIG_SETMASK, nullptr, &set, sizeof(set)) == -1) return -1; - if (!set.clear(sig)) return -1; - return __rt_sigsuspend(&set, sizeof(set)); + sigset64_t set = {}; + if (sigprocmask64(SIG_SETMASK, nullptr, &set) == -1 || sigdelset64(&set, sig) == -1) return -1; + return sigsuspend64(&set); } 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; + SigSetConverter set = {}; + set.sigset = *bionic_set; + if (__rt_sigpending(&set.sigset64, sizeof(set.sigset64)) == -1) return -1; + *bionic_set = set.sigset; + return 0; +} + +int sigpending64(sigset64_t* set) { + return __rt_sigpending(set, sizeof(*set)); } 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; + SigSetConverter new_set; + sigset64_t* new_set_ptr = nullptr; + if (bionic_new_set != nullptr) { + sigemptyset64(&new_set.sigset64); + new_set.sigset = *bionic_new_set; + new_set_ptr = &new_set.sigset64; } - kernel_sigset_t old_set; - if (__rt_sigprocmask(how, new_set_ptr, &old_set, sizeof(old_set)) == -1) { + SigSetConverter old_set; + if (sigprocmask64(how, new_set_ptr, &old_set.sigset64) == -1) { return -1; } - if (bionic_old_set != NULL) { - *bionic_old_set = old_set.bionic; + if (bionic_old_set != nullptr) { + *bionic_old_set = old_set.sigset; } return 0; } -int sigqueue(pid_t pid, int signo, const sigval value) { +int sigprocmask64(int how, const sigset64_t* new_set, sigset64_t* old_set) { + return __rt_sigprocmask(how, new_set, old_set, sizeof(*new_set)); +} + +int sigqueue(pid_t pid, int sig, const sigval value) { siginfo_t info; memset(&info, 0, sizeof(siginfo_t)); - info.si_signo = signo; + info.si_signo = sig; info.si_code = SI_QUEUE; info.si_pid = getpid(); info.si_uid = getuid(); info.si_value = value; - - return ___rt_sigqueueinfo(pid, signo, &info); + return ___rt_sigqueueinfo(pid, sig, &info); } int sigrelse(int sig) { - kernel_sigset_t set; - set.clear(); - if (!set.set(sig)) return -1; - return __rt_sigprocmask(SIG_UNBLOCK, &set, nullptr, sizeof(set)); + sigset64_t set = {}; + if (sigaddset64(&set, sig) == -1) return -1; + return sigprocmask64(SIG_UNBLOCK, &set, nullptr); } sighandler_t sigset(int sig, sighandler_t disp) { @@ -215,57 +274,68 @@ sighandler_t sigset(int sig, sighandler_t disp) { return SIG_ERR; } - kernel_sigset_t new_mask{sig}; - kernel_sigset_t old_mask; - if (__rt_sigprocmask(disp == SIG_HOLD ? SIG_BLOCK : SIG_UNBLOCK, &new_mask, &old_mask, - sizeof(new_mask)) == -1) { + sigset64_t new_mask = {}; + sigaddset64(&new_mask, sig); + sigset64_t old_mask; + if (sigprocmask64(disp == SIG_HOLD ? SIG_BLOCK : SIG_UNBLOCK, &new_mask, &old_mask) == -1) { return SIG_ERR; } - return old_mask.is_set(sig) ? SIG_HOLD : old_sa.sa_handler; + return sigismember64(&old_mask, sig) ? SIG_HOLD : old_sa.sa_handler; } // This isn't in our header files, but is exposed on all architectures. extern "C" int sigsetmask(int mask) { - union { - int mask; - sigset_t set; - } in, out; + SigSetConverter in, out; + sigemptyset(&in.sigset); + in.bsd = mask; + if (sigprocmask(SIG_SETMASK, &in.sigset, &out.sigset) == -1) return -1; + return out.bsd; +} - sigemptyset(&in.set); - in.mask = mask; +int sigsuspend(const sigset_t* bionic_set) { + SigSetConverter set = {}; + set.sigset = *bionic_set; + return __rt_sigsuspend(&set.sigset64, sizeof(set.sigset64)); +} - if (sigprocmask(SIG_SETMASK, &in.set, &out.set) == -1) return -1; - return out.mask; +int sigsuspend64(const sigset64_t* set) { + return __rt_sigsuspend(set, sizeof(*set)); } -int sigsuspend(const sigset_t* bionic_set) { - kernel_sigset_t set(bionic_set); - return __rt_sigsuspend(&set, sizeof(set)); +int sigtimedwait(const sigset_t* bionic_set, siginfo_t* info, const timespec* timeout) { + SigSetConverter set = {}; + set.sigset = *bionic_set; + return __rt_sigtimedwait(&set.sigset64, info, timeout, sizeof(set.sigset64)); } -int sigtimedwait(const sigset_t* set, siginfo_t* info, const timespec* timeout) { - kernel_sigset_t sigset(set); - return __rt_sigtimedwait(sigset.get(), info, timeout, sizeof(sigset)); +int sigtimedwait64(const sigset64_t* set, siginfo_t* info, const timespec* timeout) { + return __rt_sigtimedwait(set, info, timeout, sizeof(*set)); } -int sigwait(const sigset_t* set, int* sig) { - kernel_sigset_t sigset(set); +int sigwait(const sigset_t* bionic_set, int* sig) { + SigSetConverter set = {}; + set.sigset = *bionic_set; + return sigwait64(&set.sigset64, sig); +} + +int sigwait64(const sigset64_t* set, int* sig) { while (true) { // __rt_sigtimedwait can return EAGAIN or EINTR, we need to loop // around them since sigwait is only allowed to return EINVAL. - int result = __rt_sigtimedwait(sigset.get(), NULL, NULL, sizeof(sigset)); + int result = sigtimedwait64(set, nullptr, nullptr); if (result >= 0) { *sig = result; return 0; } - - if (errno != EAGAIN && errno != EINTR) { - return errno; - } + if (errno != EAGAIN && errno != EINTR) return errno; } } int sigwaitinfo(const sigset_t* set, siginfo_t* info) { - return sigtimedwait(set, info, NULL); + return sigtimedwait(set, info, nullptr); +} + +int sigwaitinfo64(const sigset64_t* set, siginfo_t* info) { + return sigtimedwait64(set, info, nullptr); } diff --git a/libc/bionic/spawn.cpp b/libc/bionic/spawn.cpp index e5075f54e..7422a0bb4 100644 --- a/libc/bionic/spawn.cpp +++ b/libc/bionic/spawn.cpp @@ -36,6 +36,7 @@ #include <unistd.h> #include "private/ScopedSignalBlocker.h" +#include "private/SigSetConverter.h" enum Action { kOpen, @@ -87,8 +88,8 @@ struct __posix_spawnattr { pid_t pgroup; sched_param schedparam; int schedpolicy; - sigset_t sigmask; - sigset_t sigdefault; + SigSetConverter sigmask; + SigSetConverter sigdefault; }; static void ApplyAttrs(short flags, const posix_spawnattr_t* attr) { @@ -100,7 +101,7 @@ static void ApplyAttrs(short flags, const posix_spawnattr_t* attr) { const struct sigaction default_sa = { .sa_handler = SIG_DFL }; for (int s = 1; s < _NSIG; ++s) { bool reset = false; - if (use_sigdefault && sigismember(&(*attr)->sigdefault, s)) { + if (use_sigdefault && sigismember64(&(*attr)->sigdefault.sigset64, s)) { reset = true; } else { struct sigaction current; @@ -126,7 +127,7 @@ static void ApplyAttrs(short flags, const posix_spawnattr_t* attr) { } if ((flags & POSIX_SPAWN_SETSIGMASK) != 0) { - if (sigprocmask(SIG_SETMASK, &(*attr)->sigmask, nullptr)) _exit(127); + if (sigprocmask64(SIG_SETMASK, &(*attr)->sigmask.sigset64, nullptr)) _exit(127); } } @@ -209,22 +210,42 @@ int posix_spawnattr_getpgroup(const posix_spawnattr_t* attr, pid_t* pgroup) { } int posix_spawnattr_setsigmask(posix_spawnattr_t* attr, const sigset_t* mask) { - (*attr)->sigmask = *mask; + (*attr)->sigmask.sigset = *mask; + return 0; +} + +int posix_spawnattr_setsigmask64(posix_spawnattr_t* attr, const sigset64_t* mask) { + (*attr)->sigmask.sigset64 = *mask; return 0; } int posix_spawnattr_getsigmask(const posix_spawnattr_t* attr, sigset_t* mask) { - *mask = (*attr)->sigmask; + *mask = (*attr)->sigmask.sigset; + return 0; +} + +int posix_spawnattr_getsigmask64(const posix_spawnattr_t* attr, sigset64_t* mask) { + *mask = (*attr)->sigmask.sigset64; return 0; } int posix_spawnattr_setsigdefault(posix_spawnattr_t* attr, const sigset_t* mask) { - (*attr)->sigdefault = *mask; + (*attr)->sigdefault.sigset = *mask; + return 0; +} + +int posix_spawnattr_setsigdefault64(posix_spawnattr_t* attr, const sigset64_t* mask) { + (*attr)->sigdefault.sigset64 = *mask; return 0; } int posix_spawnattr_getsigdefault(const posix_spawnattr_t* attr, sigset_t* mask) { - *mask = (*attr)->sigdefault; + *mask = (*attr)->sigdefault.sigset; + return 0; +} + +int posix_spawnattr_getsigdefault64(const posix_spawnattr_t* attr, sigset64_t* mask) { + *mask = (*attr)->sigdefault.sigset64; return 0; } diff --git a/libc/bionic/epoll_pwait.cpp b/libc/bionic/sys_epoll.cpp index f3af93ef2..9f829127f 100644 --- a/libc/bionic/epoll_pwait.cpp +++ b/libc/bionic/sys_epoll.cpp @@ -26,18 +26,36 @@ * SUCH DAMAGE. */ +#include <errno.h> #include <sys/epoll.h> -#include "private/kernel_sigset_t.h" +#include "private/SigSetConverter.h" -extern "C" int __epoll_pwait(int, epoll_event*, int, int, const kernel_sigset_t*, size_t); +extern "C" int __epoll_pwait(int, epoll_event*, int, int, const sigset64_t*, size_t); + +int epoll_create(int size) { + if (size <= 0) { + errno = EINVAL; + return -1; + } + return epoll_create1(0); +} int epoll_pwait(int fd, epoll_event* events, int max_events, int timeout, const sigset_t* ss) { - kernel_sigset_t kernel_ss; - kernel_sigset_t* kernel_ss_ptr = NULL; - if (ss != NULL) { - kernel_ss.set(ss); - kernel_ss_ptr = &kernel_ss; + SigSetConverter set; + sigset64_t* ss_ptr = nullptr; + if (ss != nullptr) { + set = {}; + set.sigset = *ss; + ss_ptr = &set.sigset64; } - return __epoll_pwait(fd, events, max_events, timeout, kernel_ss_ptr, sizeof(kernel_ss)); + return epoll_pwait64(fd, events, max_events, timeout, ss_ptr); +} + +int epoll_pwait64(int fd, epoll_event* events, int max_events, int timeout, const sigset64_t* ss) { + return __epoll_pwait(fd, events, max_events, timeout, ss, sizeof(*ss)); +} + +int epoll_wait(int fd, struct epoll_event* events, int max_events, int timeout) { + return epoll_pwait64(fd, events, max_events, timeout, nullptr); } diff --git a/libc/bionic/sys_signalfd.cpp b/libc/bionic/sys_signalfd.cpp index 63e1db431..53d1f25c9 100644 --- a/libc/bionic/sys_signalfd.cpp +++ b/libc/bionic/sys_signalfd.cpp @@ -28,11 +28,16 @@ #include <sys/signalfd.h> -#include "private/kernel_sigset_t.h" +#include "private/SigSetConverter.h" -extern "C" int __signalfd4(int fd, kernel_sigset_t* mask, size_t sizemask, int flags); +extern "C" int __signalfd4(int, const sigset64_t*, size_t, int); int signalfd(int fd, const sigset_t* mask, int flags) { - kernel_sigset_t in_set(mask); - return __signalfd4(fd, &in_set, sizeof(in_set), flags); + SigSetConverter set = {}; + set.sigset = *mask; + return signalfd64(fd, &set.sigset64, flags); +} + +int signalfd64(int fd, const sigset64_t* mask, int flags) { + return __signalfd4(fd, mask, sizeof(*mask), flags); } diff --git a/libc/include/poll.h b/libc/include/poll.h index 8517dc623..9ca1cf8e4 100644 --- a/libc/include/poll.h +++ b/libc/include/poll.h @@ -40,6 +40,7 @@ typedef unsigned int nfds_t; int poll(struct pollfd* __fds, nfds_t __count, int __timeout_ms) __overloadable __RENAME_CLANG(poll); int ppoll(struct pollfd* __fds, nfds_t __count, const struct timespec* __timeout, const sigset_t* __mask) __overloadable __RENAME_CLANG(ppoll) __INTRODUCED_IN(21); +int ppoll64(struct pollfd* __fds, nfds_t __count, const struct timespec* __timeout, const sigset64_t* __mask) __INTRODUCED_IN(28); #if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS) #include <bits/fortify/poll.h> diff --git a/libc/include/signal.h b/libc/include/signal.h index d9c9ee246..61bb395fa 100644 --- a/libc/include/signal.h +++ b/libc/include/signal.h @@ -80,6 +80,13 @@ typedef __sighandler_t sighandler_t; /* glibc compatibility. */ #define si_timerid si_tid /* glibc compatibility. */ +/* sigset_t is already large enough on LP64, but LP32's sigset_t is just `unsigned long`. */ +#if defined(__LP64__) +typedef sigset_t sigset64_t; +#else +typedef struct { unsigned long __bits[_KERNEL__NSIG/LONG_BIT]; } sigset64_t; +#endif + #if defined(__LP64__) struct sigaction { @@ -117,6 +124,7 @@ struct sigaction { #endif +// TODO: sigaction contains a sigset_t that's too small on LP32. int sigaction(int __signal, const struct sigaction* __new_action, struct sigaction* __old_action); int siginterrupt(int __signal, int __flag); @@ -124,18 +132,27 @@ int siginterrupt(int __signal, int __flag); #if __ANDROID_API__ >= __ANDROID_API_L__ sighandler_t signal(int __signal, sighandler_t __handler) __INTRODUCED_IN(21); int sigaddset(sigset_t* __set, int __signal) __INTRODUCED_IN(21); +int sigaddset64(sigset64_t* __set, int __signal) __INTRODUCED_IN(28); int sigdelset(sigset_t* __set, int __signal) __INTRODUCED_IN(21); +int sigdelset64(sigset64_t* __set, int __signal) __INTRODUCED_IN(28); int sigemptyset(sigset_t* __set) __INTRODUCED_IN(21); +int sigemptyset64(sigset64_t* __set) __INTRODUCED_IN(28); int sigfillset(sigset_t* __set) __INTRODUCED_IN(21); +int sigfillset64(sigset64_t* __set) __INTRODUCED_IN(28); int sigismember(const sigset_t* __set, int __signal) __INTRODUCED_IN(21); +int sigismember64(const sigset64_t* __set, int __signal) __INTRODUCED_IN(28); #else // Implemented as static inlines before 21. #endif int sigpending(sigset_t* __set); +int sigpending64(sigset64_t* __set) __INTRODUCED_IN(28); int sigprocmask(int __how, const sigset_t* __new_set, sigset_t* __old_set); +int sigprocmask64(int __how, const sigset64_t* __new_set, sigset64_t* __old_set) __INTRODUCED_IN(28); int sigsuspend(const sigset_t* __mask); +int sigsuspend64(const sigset64_t* __mask) __INTRODUCED_IN(28); int sigwait(const sigset_t* __set, int* __signal); +int sigwait64(const sigset64_t* __set, int* __signal) __INTRODUCED_IN(28); int sighold(int __signal) __attribute__((deprecated("use sigprocmask() or pthread_sigmask() instead"))) @@ -162,10 +179,13 @@ void psignal(int __signal, const char* __msg) __INTRODUCED_IN(17); int pthread_kill(pthread_t __pthread, int __signal); int pthread_sigmask(int __how, const sigset_t* __new_set, sigset_t* __old_set); +int pthread_sigmask64(int __how, const sigset64_t* __new_set, sigset64_t* __old_set) __INTRODUCED_IN(28); int sigqueue(pid_t __pid, int __signal, const union sigval __value) __INTRODUCED_IN(23); int sigtimedwait(const sigset_t* __set, siginfo_t* __info, const struct timespec* __timeout) __INTRODUCED_IN(23); +int sigtimedwait64(const sigset64_t* __set, siginfo_t* __info, const struct timespec* __timeout) __INTRODUCED_IN(28); int sigwaitinfo(const sigset_t* __set, siginfo_t* __info) __INTRODUCED_IN(23); +int sigwaitinfo64(const sigset64_t* __set, siginfo_t* __info) __INTRODUCED_IN(28); __END_DECLS diff --git a/libc/include/spawn.h b/libc/include/spawn.h index b5ac58652..2e239bfc2 100644 --- a/libc/include/spawn.h +++ b/libc/include/spawn.h @@ -63,10 +63,14 @@ int posix_spawnattr_setpgroup(posix_spawnattr_t* __attr, pid_t __pgroup) __INTRO int posix_spawnattr_getpgroup(const posix_spawnattr_t* __attr, pid_t* __pgroup) __INTRODUCED_IN(28); int posix_spawnattr_setsigmask(posix_spawnattr_t* __attr, const sigset_t* __mask) __INTRODUCED_IN(28); +int posix_spawnattr_setsigmask64(posix_spawnattr_t* __attr, const sigset64_t* __mask) __INTRODUCED_IN(28); int posix_spawnattr_getsigmask(const posix_spawnattr_t* __attr, sigset_t* __mask) __INTRODUCED_IN(28); +int posix_spawnattr_getsigmask64(const posix_spawnattr_t* __attr, sigset64_t* __mask) __INTRODUCED_IN(28); int posix_spawnattr_setsigdefault(posix_spawnattr_t* __attr, const sigset_t* __mask) __INTRODUCED_IN(28); +int posix_spawnattr_setsigdefault64(posix_spawnattr_t* __attr, const sigset64_t* __mask) __INTRODUCED_IN(28); int posix_spawnattr_getsigdefault(const posix_spawnattr_t* __attr, sigset_t* __mask) __INTRODUCED_IN(28); +int posix_spawnattr_getsigdefault64(const posix_spawnattr_t* __attr, sigset64_t* __mask) __INTRODUCED_IN(28); int posix_spawnattr_setschedparam(posix_spawnattr_t* __attr, const struct sched_param* __param) __INTRODUCED_IN(28); int posix_spawnattr_getschedparam(const posix_spawnattr_t* __attr, struct sched_param* __param) __INTRODUCED_IN(28); diff --git a/libc/include/sys/epoll.h b/libc/include/sys/epoll.h index 2bc16f5b8..a213a90fb 100644 --- a/libc/include/sys/epoll.h +++ b/libc/include/sys/epoll.h @@ -58,6 +58,7 @@ int epoll_create1(int __flags) __INTRODUCED_IN(21); int epoll_ctl(int __epoll_fd, int __op, int __fd, struct epoll_event* __event); int epoll_wait(int __epoll_fd, struct epoll_event* __events, int __event_count, int __timeout_ms); int epoll_pwait(int __epoll_fd, struct epoll_event* __events, int __event_count, int __timeout_ms, const sigset_t* __mask) __INTRODUCED_IN(21); +int epoll_pwait64(int __epoll_fd, struct epoll_event* __events, int __event_count, int __timeout_ms, const sigset64_t* __mask) __INTRODUCED_IN(28); __END_DECLS diff --git a/libc/include/sys/select.h b/libc/include/sys/select.h index ac51d3fc8..603a5a676 100644 --- a/libc/include/sys/select.h +++ b/libc/include/sys/select.h @@ -75,6 +75,7 @@ int __FD_ISSET_chk(int, const fd_set*, size_t) __INTRODUCED_IN(21); int select(int __fd_count, fd_set* __read_fds, fd_set* __write_fds, fd_set* __exception_fds, struct timeval* __timeout); int pselect(int __fd_count, fd_set* __read_fds, fd_set* __write_fds, fd_set* __exception_fds, const struct timespec* __timeout, const sigset_t* __mask); +int pselect64(int __fd_count, fd_set* __read_fds, fd_set* __write_fds, fd_set* __exception_fds, const struct timespec* __timeout, const sigset64_t* __mask); __END_DECLS diff --git a/libc/include/sys/signalfd.h b/libc/include/sys/signalfd.h index 315622c7f..2337cd773 100644 --- a/libc/include/sys/signalfd.h +++ b/libc/include/sys/signalfd.h @@ -37,6 +37,7 @@ __BEGIN_DECLS int signalfd(int __fd, const sigset_t* __mask, int __flags) __INTRODUCED_IN(18); +int signalfd64(int __fd, const sigset64_t* __mask, int __flags) __INTRODUCED_IN(28); __END_DECLS diff --git a/libc/libc.arm.map b/libc/libc.arm.map index 1ed4ec6e8..c345ba636 100644 --- a/libc/libc.arm.map +++ b/libc/libc.arm.map @@ -1325,6 +1325,7 @@ LIBC_P { # introduced=P endhostent; endnetent; endprotoent; + epoll_pwait64; fexecve; fflush_unlocked; fgetc_unlocked; @@ -1356,28 +1357,47 @@ LIBC_P { # introduced=P posix_spawnattr_getschedparam; posix_spawnattr_getschedpolicy; posix_spawnattr_getsigdefault; + posix_spawnattr_getsigdefault64; posix_spawnattr_getsigmask; + posix_spawnattr_getsigmask64; posix_spawnattr_init; posix_spawnattr_setflags; posix_spawnattr_setpgroup; posix_spawnattr_setschedparam; posix_spawnattr_setschedpolicy; posix_spawnattr_setsigdefault; + posix_spawnattr_setsigdefault64; posix_spawnattr_setsigmask; + posix_spawnattr_setsigmask64; posix_spawn_file_actions_addclose; posix_spawn_file_actions_adddup2; posix_spawn_file_actions_addopen; posix_spawn_file_actions_destroy; posix_spawn_file_actions_init; posix_spawnp; + ppoll64; + pselect64; pthread_attr_getinheritsched; pthread_attr_setinheritsched; pthread_mutexattr_getprotocol; pthread_mutexattr_setprotocol; pthread_setschedprio; + pthread_sigmask64; sethostent; setnetent; setprotoent; + sigaddset64; + sigdelset64; + sigemptyset64; + sigfillset64; + sigismember64; + signalfd64; + sigpending64; + sigprocmask64; + sigsuspend64; + sigtimedwait64; + sigwait64; + sigwaitinfo64; swab; syncfs; } LIBC_O; diff --git a/libc/libc.arm64.map b/libc/libc.arm64.map index f5117077b..3af0d423b 100644 --- a/libc/libc.arm64.map +++ b/libc/libc.arm64.map @@ -1245,6 +1245,7 @@ LIBC_P { # introduced=P endhostent; endnetent; endprotoent; + epoll_pwait64; fexecve; fflush_unlocked; fgetc_unlocked; @@ -1276,28 +1277,47 @@ LIBC_P { # introduced=P posix_spawnattr_getschedparam; posix_spawnattr_getschedpolicy; posix_spawnattr_getsigdefault; + posix_spawnattr_getsigdefault64; posix_spawnattr_getsigmask; + posix_spawnattr_getsigmask64; posix_spawnattr_init; posix_spawnattr_setflags; posix_spawnattr_setpgroup; posix_spawnattr_setschedparam; posix_spawnattr_setschedpolicy; posix_spawnattr_setsigdefault; + posix_spawnattr_setsigdefault64; posix_spawnattr_setsigmask; + posix_spawnattr_setsigmask64; posix_spawn_file_actions_addclose; posix_spawn_file_actions_adddup2; posix_spawn_file_actions_addopen; posix_spawn_file_actions_destroy; posix_spawn_file_actions_init; posix_spawnp; + ppoll64; + pselect64; pthread_attr_getinheritsched; pthread_attr_setinheritsched; pthread_mutexattr_getprotocol; pthread_mutexattr_setprotocol; pthread_setschedprio; + pthread_sigmask64; sethostent; setnetent; setprotoent; + sigaddset64; + sigdelset64; + sigemptyset64; + sigfillset64; + sigismember64; + signalfd64; + sigpending64; + sigprocmask64; + sigsuspend64; + sigtimedwait64; + sigwait64; + sigwaitinfo64; swab; syncfs; } LIBC_O; diff --git a/libc/libc.map.txt b/libc/libc.map.txt index 09605607a..5c54ba105 100644 --- a/libc/libc.map.txt +++ b/libc/libc.map.txt @@ -1350,6 +1350,7 @@ LIBC_P { # introduced=P endhostent; endnetent; endprotoent; + epoll_pwait64; fexecve; fflush_unlocked; fgetc_unlocked; @@ -1381,28 +1382,47 @@ LIBC_P { # introduced=P posix_spawnattr_getschedparam; posix_spawnattr_getschedpolicy; posix_spawnattr_getsigdefault; + posix_spawnattr_getsigdefault64; posix_spawnattr_getsigmask; + posix_spawnattr_getsigmask64; posix_spawnattr_init; posix_spawnattr_setflags; posix_spawnattr_setpgroup; posix_spawnattr_setschedparam; posix_spawnattr_setschedpolicy; posix_spawnattr_setsigdefault; + posix_spawnattr_setsigdefault64; posix_spawnattr_setsigmask; + posix_spawnattr_setsigmask64; posix_spawn_file_actions_addclose; posix_spawn_file_actions_adddup2; posix_spawn_file_actions_addopen; posix_spawn_file_actions_destroy; posix_spawn_file_actions_init; posix_spawnp; + ppoll64; + pselect64; pthread_attr_getinheritsched; pthread_attr_setinheritsched; pthread_mutexattr_getprotocol; pthread_mutexattr_setprotocol; pthread_setschedprio; + pthread_sigmask64; sethostent; setnetent; setprotoent; + sigaddset64; + sigdelset64; + sigemptyset64; + sigfillset64; + sigismember64; + signalfd64; + sigpending64; + sigprocmask64; + sigsuspend64; + sigtimedwait64; + sigwait64; + sigwaitinfo64; swab; syncfs; } LIBC_O; diff --git a/libc/libc.mips.map b/libc/libc.mips.map index 1160f8783..c3646085d 100644 --- a/libc/libc.mips.map +++ b/libc/libc.mips.map @@ -1309,6 +1309,7 @@ LIBC_P { # introduced=P endhostent; endnetent; endprotoent; + epoll_pwait64; fexecve; fflush_unlocked; fgetc_unlocked; @@ -1340,28 +1341,47 @@ LIBC_P { # introduced=P posix_spawnattr_getschedparam; posix_spawnattr_getschedpolicy; posix_spawnattr_getsigdefault; + posix_spawnattr_getsigdefault64; posix_spawnattr_getsigmask; + posix_spawnattr_getsigmask64; posix_spawnattr_init; posix_spawnattr_setflags; posix_spawnattr_setpgroup; posix_spawnattr_setschedparam; posix_spawnattr_setschedpolicy; posix_spawnattr_setsigdefault; + posix_spawnattr_setsigdefault64; posix_spawnattr_setsigmask; + posix_spawnattr_setsigmask64; posix_spawn_file_actions_addclose; posix_spawn_file_actions_adddup2; posix_spawn_file_actions_addopen; posix_spawn_file_actions_destroy; posix_spawn_file_actions_init; posix_spawnp; + ppoll64; + pselect64; pthread_attr_getinheritsched; pthread_attr_setinheritsched; pthread_mutexattr_getprotocol; pthread_mutexattr_setprotocol; pthread_setschedprio; + pthread_sigmask64; sethostent; setnetent; setprotoent; + sigaddset64; + sigdelset64; + sigemptyset64; + sigfillset64; + sigismember64; + signalfd64; + sigpending64; + sigprocmask64; + sigsuspend64; + sigtimedwait64; + sigwait64; + sigwaitinfo64; swab; syncfs; } LIBC_O; diff --git a/libc/libc.mips64.map b/libc/libc.mips64.map index f5117077b..3af0d423b 100644 --- a/libc/libc.mips64.map +++ b/libc/libc.mips64.map @@ -1245,6 +1245,7 @@ LIBC_P { # introduced=P endhostent; endnetent; endprotoent; + epoll_pwait64; fexecve; fflush_unlocked; fgetc_unlocked; @@ -1276,28 +1277,47 @@ LIBC_P { # introduced=P posix_spawnattr_getschedparam; posix_spawnattr_getschedpolicy; posix_spawnattr_getsigdefault; + posix_spawnattr_getsigdefault64; posix_spawnattr_getsigmask; + posix_spawnattr_getsigmask64; posix_spawnattr_init; posix_spawnattr_setflags; posix_spawnattr_setpgroup; posix_spawnattr_setschedparam; posix_spawnattr_setschedpolicy; posix_spawnattr_setsigdefault; + posix_spawnattr_setsigdefault64; posix_spawnattr_setsigmask; + posix_spawnattr_setsigmask64; posix_spawn_file_actions_addclose; posix_spawn_file_actions_adddup2; posix_spawn_file_actions_addopen; posix_spawn_file_actions_destroy; posix_spawn_file_actions_init; posix_spawnp; + ppoll64; + pselect64; pthread_attr_getinheritsched; pthread_attr_setinheritsched; pthread_mutexattr_getprotocol; pthread_mutexattr_setprotocol; pthread_setschedprio; + pthread_sigmask64; sethostent; setnetent; setprotoent; + sigaddset64; + sigdelset64; + sigemptyset64; + sigfillset64; + sigismember64; + signalfd64; + sigpending64; + sigprocmask64; + sigsuspend64; + sigtimedwait64; + sigwait64; + sigwaitinfo64; swab; syncfs; } LIBC_O; diff --git a/libc/libc.x86.map b/libc/libc.x86.map index b0b4b162b..eec2c19cb 100644 --- a/libc/libc.x86.map +++ b/libc/libc.x86.map @@ -1307,6 +1307,7 @@ LIBC_P { # introduced=P endhostent; endnetent; endprotoent; + epoll_pwait64; fexecve; fflush_unlocked; fgetc_unlocked; @@ -1338,28 +1339,47 @@ LIBC_P { # introduced=P posix_spawnattr_getschedparam; posix_spawnattr_getschedpolicy; posix_spawnattr_getsigdefault; + posix_spawnattr_getsigdefault64; posix_spawnattr_getsigmask; + posix_spawnattr_getsigmask64; posix_spawnattr_init; posix_spawnattr_setflags; posix_spawnattr_setpgroup; posix_spawnattr_setschedparam; posix_spawnattr_setschedpolicy; posix_spawnattr_setsigdefault; + posix_spawnattr_setsigdefault64; posix_spawnattr_setsigmask; + posix_spawnattr_setsigmask64; posix_spawn_file_actions_addclose; posix_spawn_file_actions_adddup2; posix_spawn_file_actions_addopen; posix_spawn_file_actions_destroy; posix_spawn_file_actions_init; posix_spawnp; + ppoll64; + pselect64; pthread_attr_getinheritsched; pthread_attr_setinheritsched; pthread_mutexattr_getprotocol; pthread_mutexattr_setprotocol; pthread_setschedprio; + pthread_sigmask64; sethostent; setnetent; setprotoent; + sigaddset64; + sigdelset64; + sigemptyset64; + sigfillset64; + sigismember64; + signalfd64; + sigpending64; + sigprocmask64; + sigsuspend64; + sigtimedwait64; + sigwait64; + sigwaitinfo64; swab; syncfs; } LIBC_O; diff --git a/libc/libc.x86_64.map b/libc/libc.x86_64.map index f5117077b..3af0d423b 100644 --- a/libc/libc.x86_64.map +++ b/libc/libc.x86_64.map @@ -1245,6 +1245,7 @@ LIBC_P { # introduced=P endhostent; endnetent; endprotoent; + epoll_pwait64; fexecve; fflush_unlocked; fgetc_unlocked; @@ -1276,28 +1277,47 @@ LIBC_P { # introduced=P posix_spawnattr_getschedparam; posix_spawnattr_getschedpolicy; posix_spawnattr_getsigdefault; + posix_spawnattr_getsigdefault64; posix_spawnattr_getsigmask; + posix_spawnattr_getsigmask64; posix_spawnattr_init; posix_spawnattr_setflags; posix_spawnattr_setpgroup; posix_spawnattr_setschedparam; posix_spawnattr_setschedpolicy; posix_spawnattr_setsigdefault; + posix_spawnattr_setsigdefault64; posix_spawnattr_setsigmask; + posix_spawnattr_setsigmask64; posix_spawn_file_actions_addclose; posix_spawn_file_actions_adddup2; posix_spawn_file_actions_addopen; posix_spawn_file_actions_destroy; posix_spawn_file_actions_init; posix_spawnp; + ppoll64; + pselect64; pthread_attr_getinheritsched; pthread_attr_setinheritsched; pthread_mutexattr_getprotocol; pthread_mutexattr_setprotocol; pthread_setschedprio; + pthread_sigmask64; sethostent; setnetent; setprotoent; + sigaddset64; + sigdelset64; + sigemptyset64; + sigfillset64; + sigismember64; + signalfd64; + sigpending64; + sigprocmask64; + sigsuspend64; + sigtimedwait64; + sigwait64; + sigwaitinfo64; swab; syncfs; } LIBC_O; diff --git a/libc/private/ScopedSignalBlocker.h b/libc/private/ScopedSignalBlocker.h index c3ab30759..7582068ac 100644 --- a/libc/private/ScopedSignalBlocker.h +++ b/libc/private/ScopedSignalBlocker.h @@ -20,14 +20,13 @@ #include <signal.h> #include "bionic_macros.h" -#include "kernel_sigset_t.h" class ScopedSignalBlocker { public: explicit ScopedSignalBlocker() { - kernel_sigset_t set; - set.fill(); - __rt_sigprocmask(SIG_SETMASK, &set, &old_set_, sizeof(set)); + sigset64_t set; + sigfillset64(&set); + sigprocmask64(SIG_SETMASK, &set, &old_set_); } ~ScopedSignalBlocker() { @@ -35,11 +34,11 @@ class ScopedSignalBlocker { } void reset() { - __rt_sigprocmask(SIG_SETMASK, &old_set_, nullptr, sizeof(old_set_)); + sigprocmask64(SIG_SETMASK, &old_set_, nullptr); } private: - kernel_sigset_t old_set_; + sigset64_t old_set_; DISALLOW_COPY_AND_ASSIGN(ScopedSignalBlocker); }; diff --git a/libc/bionic/epoll_create.cpp b/libc/private/SigSetConverter.h index 74f664f86..7d0b21573 100644 --- a/libc/bionic/epoll_create.cpp +++ b/libc/private/SigSetConverter.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 The Android Open Source Project + * Copyright (C) 2018 The Android Open Source Project * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,13 +26,10 @@ * SUCH DAMAGE. */ -#include <errno.h> -#include <sys/epoll.h> +#pragma once -int epoll_create(int size) { - if (size <= 0) { - errno = EINVAL; - return -1; - } - return epoll_create1(0); -} +union SigSetConverter { + int bsd; + sigset_t sigset; + sigset64_t sigset64; +}; diff --git a/libc/private/kernel_sigset_t.h b/libc/private/kernel_sigset_t.h deleted file mode 100644 index bdfb729c6..000000000 --- a/libc/private/kernel_sigset_t.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef LIBC_PRIVATE_KERNEL_SIGSET_T_H_ -#define LIBC_PRIVATE_KERNEL_SIGSET_T_H_ - -#include <errno.h> -#include <signal.h> - -#include <async_safe/log.h> - -// Our sigset_t is wrong for ARM and x86. It's 32-bit but the kernel expects 64 bits. -// This means we can't support real-time signals correctly without breaking the ABI. -// In the meantime, we can use this union to pass an appropriately-sized block of memory -// to the kernel, at the cost of not being able to refer to real-time signals when -// initializing from a sigset_t on LP32. -union kernel_sigset_t { - public: - kernel_sigset_t() { - } - - explicit kernel_sigset_t(int signal_number) { - clear(); - if (!set(signal_number)) async_safe_fatal("kernel_sigset_t(%d)", signal_number); - } - - explicit kernel_sigset_t(const sigset_t* value) { - clear(); - set(value); - } - - void clear() { - __builtin_memset(this, 0, sizeof(*this)); - } - - bool clear(int signal_number) { - int bit = bit_of(signal_number); - if (bit == -1) return false; - bits[bit / LONG_BIT] &= ~(1UL << (bit % LONG_BIT)); - return true; - } - - void fill() { - __builtin_memset(this, 0xff, sizeof(*this)); - } - - bool is_set(int signal_number) { - int bit = bit_of(signal_number); - if (bit == -1) return false; - return ((bits[bit / LONG_BIT] >> (bit % LONG_BIT)) & 1) == 1; - } - - bool set(int signal_number) { - int bit = bit_of(signal_number); - if (bit == -1) return false; - bits[bit / LONG_BIT] |= 1UL << (bit % LONG_BIT); - return true; - } - - void set(const sigset_t* value) { - clear(); - bionic = *value; - } - - sigset_t* get() { - return &bionic; - } - - sigset_t bionic; - unsigned long bits[_KERNEL__NSIG/LONG_BIT]; - - private: - int bit_of(int signal_number) { - int bit = signal_number - 1; // Signal numbers start at 1, but bit positions start at 0. - if (bit < 0 || bit >= static_cast<int>(8*sizeof(*this))) { - errno = EINVAL; - return -1; - } - return bit; - } -}; - -extern "C" int __rt_sigpending(const kernel_sigset_t*, size_t); -extern "C" int __rt_sigprocmask(int, const kernel_sigset_t*, kernel_sigset_t*, size_t); -extern "C" int __rt_sigsuspend(const kernel_sigset_t*, size_t); - -#endif |