Merge "Move static variable out of should_trace()."
diff --git a/docs/status.md b/docs/status.md
index d4ca913..8cef5b7 100644
--- a/docs/status.md
+++ b/docs/status.md
@@ -48,10 +48,12 @@
* `hcreate`/`hcreate_r`/`hdestroy`/`hdestroy_r`/`hsearch`/`hsearch_r` (completing <search.h>)
* `iconv`/`iconv_close`/`iconv_open` (adding <iconv.h>)
* `pthread_attr_getinheritsched`/`pthread_attr_setinheritsched`/`pthread_setschedprio`
+ * `pthread_mutexattr_getprotocol`/`pthread_mutexattr_setprotocol` (mutex priority inheritance)
* <spawn.h>
* `swab`
* `syncfs`
- * %C and %S support in the printf family (previously only the wprintf family supported these).
+ * `%C` and `%S` support in the printf family (previously only the wprintf family supported these).
+ * `%mc`/`%ms`/`%m[` support in the scanf family.
New libc functions in O:
* `sendto` FORTIFY support
diff --git a/libc/Android.bp b/libc/Android.bp
index a8c518d..2ea8514 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -10,9 +10,6 @@
"bionic/pututline.c",
"bionic/sched_cpualloc.c",
"bionic/sched_cpucount.c",
- "bionic/sigblock.c",
- "bionic/siginterrupt.c",
- "bionic/sigsetmask.c",
"stdio/fmemopen.cpp",
"stdio/parsefloat.c",
"stdio/refill.c",
@@ -1336,25 +1333,7 @@
"bionic/seteuid.cpp",
"bionic/setpgrp.cpp",
"bionic/sigaction.cpp",
- "bionic/sigaddset.cpp",
- "bionic/sigdelset.cpp",
- "bionic/sigemptyset.cpp",
- "bionic/sigfillset.cpp",
- "bionic/sighold.cpp",
- "bionic/sigignore.cpp",
- "bionic/sigismember.cpp",
"bionic/signal.cpp",
- "bionic/signalfd.cpp",
- "bionic/sigpause.cpp",
- "bionic/sigpending.cpp",
- "bionic/sigprocmask.cpp",
- "bionic/sigqueue.cpp",
- "bionic/sigrelse.cpp",
- "bionic/sigset.cpp",
- "bionic/sigsuspend.cpp",
- "bionic/sigtimedwait.cpp",
- "bionic/sigwait.cpp",
- "bionic/sigwaitinfo.cpp",
"bionic/socket.cpp",
"bionic/spawn.cpp",
"bionic/stat.cpp",
@@ -1375,6 +1354,7 @@
"bionic/sys_sem.cpp",
"bionic/sys_shm.cpp",
"bionic/sys_siglist.c",
+ "bionic/sys_signalfd.cpp",
"bionic/sys_signame.c",
"bionic/sys_time.cpp",
"bionic/sysinfo.cpp",
diff --git a/libc/arch-arm/bionic/setjmp.S b/libc/arch-arm/bionic/setjmp.S
index b814124..c10bd3e 100644
--- a/libc/arch-arm/bionic/setjmp.S
+++ b/libc/arch-arm/bionic/setjmp.S
@@ -218,8 +218,10 @@
beq 1f
// Restore the signal mask.
- ldr r0, [r0, #(_JB_SIGMASK * 4)]
- bl sigsetmask
+ mov r2, #0
+ add r1, r0, #(_JB_SIGMASK * 4)
+ mov r0, #2 // SIG_SETMASK
+ bl sigprocmask
1:
ldmfd sp!, {r0, r1, lr}
diff --git a/libc/arch-x86/bionic/setjmp.S b/libc/arch-x86/bionic/setjmp.S
index 6e6c365..f9f7cd7 100644
--- a/libc/arch-x86/bionic/setjmp.S
+++ b/libc/arch-x86/bionic/setjmp.S
@@ -110,16 +110,17 @@
testl $1,%eax
jz 1f
- // Get the current signal mask.
+ // Save the current signal mask.
+ pushl %ecx
PIC_PROLOGUE
- pushl $0
- call PIC_PLT(sigblock)
- addl $4,%esp
+ leal (_JB_SIGMASK * 4)(%ecx),%eax
+ pushl %eax
+ pushl $0 // NULL
+ pushl $2 // SIG_SETMASK
+ call PIC_PLT(sigprocmask)
+ addl $12,%esp
PIC_EPILOGUE
-
- // Save the signal mask.
- movl 4(%esp),%ecx
- movl %eax,(_JB_SIGMASK * 4)(%ecx)
+ popl %ecx
1:
// Fetch the setjmp cookie and clear the signal flag bit.
@@ -159,10 +160,13 @@
jz 1f
// Restore the signal mask.
+ leal (_JB_SIGMASK * 4)(%edx),%eax
PIC_PROLOGUE
- pushl (_JB_SIGMASK * 4)(%edx)
- call PIC_PLT(sigsetmask)
- addl $4,%esp
+ pushl $0 // NULL
+ pushl %eax
+ pushl $2 // SIG_SETMASK
+ call PIC_PLT(sigprocmask)
+ addl $12,%esp
PIC_EPILOGUE
1:
diff --git a/libc/bionic/abort.cpp b/libc/bionic/abort.cpp
index f401cab..9f1c31f 100644
--- a/libc/bionic/abort.cpp
+++ b/libc/bionic/abort.cpp
@@ -32,6 +32,8 @@
#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) {
@@ -60,10 +62,10 @@
// Don't block SIGABRT to give any signal handler a chance; we ignore
// any errors -- X311J doesn't allow abort to return anyway.
- sigset_t mask;
- sigfillset(&mask);
- sigdelset(&mask, SIGABRT);
- sigprocmask(SIG_SETMASK, &mask, NULL);
+ kernel_sigset_t mask;
+ mask.fill();
+ mask.clear(SIGABRT);
+ __rt_sigprocmask(SIG_SETMASK, &mask, nullptr, sizeof(mask));
inline_tgkill(pid, tid, SIGABRT);
@@ -74,7 +76,7 @@
sa.sa_flags = SA_RESTART;
sigemptyset(&sa.sa_mask);
sigaction(SIGABRT, &sa, &sa);
- sigprocmask(SIG_SETMASK, &mask, NULL);
+ __rt_sigprocmask(SIG_SETMASK, &mask, nullptr, sizeof(mask));
inline_tgkill(pid, tid, SIGABRT);
diff --git a/libc/bionic/pause.cpp b/libc/bionic/pause.cpp
index 94a16fb..2a0779a 100644
--- a/libc/bionic/pause.cpp
+++ b/libc/bionic/pause.cpp
@@ -30,13 +30,8 @@
#include "private/kernel_sigset_t.h"
-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);
-
int pause() {
kernel_sigset_t mask;
- if (__rt_sigprocmask(SIG_SETMASK, NULL, &mask, sizeof(mask)) == -1) {
- return -1;
- }
+ if (__rt_sigprocmask(SIG_SETMASK, nullptr, &mask, sizeof(mask)) == -1) return -1;
return __rt_sigsuspend(&mask, sizeof(mask));
}
diff --git a/libc/bionic/posix_timers.cpp b/libc/bionic/posix_timers.cpp
index c46965f..e3bb112 100644
--- a/libc/bionic/posix_timers.cpp
+++ b/libc/bionic/posix_timers.cpp
@@ -74,8 +74,7 @@
static void* __timer_thread_start(void* arg) {
PosixTimer* timer = reinterpret_cast<PosixTimer*>(arg);
- kernel_sigset_t sigset;
- sigaddset(sigset.get(), TIMER_SIGNAL);
+ kernel_sigset_t sigset{TIMER_SIGNAL};
while (true) {
// Wait for a signal...
@@ -150,14 +149,13 @@
// 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;
- sigaddset(sigset.get(), TIMER_SIGNAL);
+ kernel_sigset_t sigset{TIMER_SIGNAL};
kernel_sigset_t old_sigset;
- pthread_sigmask(SIG_BLOCK, sigset.get(), old_sigset.get());
+ __rt_sigprocmask(SIG_BLOCK, &sigset, &old_sigset, sizeof(sigset));
int rc = pthread_create(&timer->callback_thread, &thread_attributes, __timer_thread_start, timer);
- pthread_sigmask(SIG_SETMASK, old_sigset.get(), NULL);
+ __rt_sigprocmask(SIG_SETMASK, &old_sigset, nullptr, sizeof(sigset));
if (rc != 0) {
free(timer);
diff --git a/libc/bionic/pthread_exit.cpp b/libc/bionic/pthread_exit.cpp
index 8b4c44e..f1b65fd 100644
--- a/libc/bionic/pthread_exit.cpp
+++ b/libc/bionic/pthread_exit.cpp
@@ -34,6 +34,7 @@
#include <sys/mman.h>
#include "private/bionic_defs.h"
+#include "private/ScopedSignalBlocker.h"
#include "pthread_internal.h"
extern "C" __noreturn void _exit_with_stack_teardown(void*, size_t);
@@ -63,6 +64,12 @@
}
}
+static void __pthread_unmap_tls(pthread_internal_t* thread) {
+ // Unmap the bionic TLS, including guard pages.
+ void* allocation = reinterpret_cast<char*>(thread->bionic_tls) - PTHREAD_GUARD_SIZE;
+ munmap(allocation, BIONIC_TLS_SIZE + 2 * PTHREAD_GUARD_SIZE);
+}
+
__BIONIC_WEAK_FOR_NATIVE_BRIDGE
void pthread_exit(void* return_value) {
// Call dtors for thread_local objects first.
@@ -96,10 +103,6 @@
thread->alternate_signal_stack = NULL;
}
- // Unmap the bionic TLS, including guard pages.
- void* allocation = reinterpret_cast<char*>(thread->bionic_tls) - PTHREAD_GUARD_SIZE;
- munmap(allocation, BIONIC_TLS_SIZE + 2 * PTHREAD_GUARD_SIZE);
-
ThreadJoinState old_state = THREAD_NOT_JOINED;
while (old_state == THREAD_NOT_JOINED &&
!atomic_compare_exchange_weak(&thread->join_state, &old_state, THREAD_EXITED_NOT_JOINED)) {
@@ -120,16 +123,15 @@
// That's not something we can do in C.
// We don't want to take a signal after we've unmapped the stack.
- // That's one last thing we can handle in C.
- sigset_t mask;
- sigfillset(&mask);
- sigprocmask(SIG_SETMASK, &mask, NULL);
-
+ // That's one last thing we can do before dropping to assembler.
+ ScopedSignalBlocker ssb;
+ __pthread_unmap_tls(thread);
_exit_with_stack_teardown(thread->attr.stack_base, thread->mmap_size);
}
}
// No need to free mapped space. Either there was no space mapped, or it is left for
// the pthread_join caller to clean up.
+ __pthread_unmap_tls(thread);
__exit(0);
}
diff --git a/libc/bionic/sigaddset.cpp b/libc/bionic/sigaddset.cpp
deleted file mode 100644
index ca6b982..0000000
--- a/libc/bionic/sigaddset.cpp
+++ /dev/null
@@ -1,41 +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 <signal.h>
-
-int sigaddset(sigset_t* set, int signum) {
- int bit = signum - 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))) {
- errno = EINVAL;
- return -1;
- }
- local_set[bit / LONG_BIT] |= 1UL << (bit % LONG_BIT);
- return 0;
-}
diff --git a/libc/bionic/sigblock.c b/libc/bionic/sigblock.c
deleted file mode 100644
index 176bc13..0000000
--- a/libc/bionic/sigblock.c
+++ /dev/null
@@ -1,50 +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 <signal.h>
-
-/* this function is called from the ARM assembly setjmp fragments */
-int
-sigblock(int mask)
-{
- int n;
- union {
- int the_mask;
- sigset_t the_sigset;
- } in, out;
-
- sigemptyset(&in.the_sigset);
- in.the_mask = mask;
-
- n = sigprocmask(SIG_BLOCK, &in.the_sigset, &out.the_sigset);
- if (n)
- return n;
-
- return out.the_mask;
-}
-
-
diff --git a/libc/bionic/sigdelset.cpp b/libc/bionic/sigdelset.cpp
deleted file mode 100644
index 48363d3..0000000
--- a/libc/bionic/sigdelset.cpp
+++ /dev/null
@@ -1,41 +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 <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 = reinterpret_cast<unsigned long*>(set);
- if (set == NULL || bit < 0 || bit >= static_cast<int>(8*sizeof(sigset_t))) {
- errno = EINVAL;
- return -1;
- }
- local_set[bit / LONG_BIT] &= ~(1UL << (bit % LONG_BIT));
- return 0;
-}
diff --git a/libc/bionic/sigemptyset.cpp b/libc/bionic/sigemptyset.cpp
deleted file mode 100644
index 58166a1..0000000
--- a/libc/bionic/sigemptyset.cpp
+++ /dev/null
@@ -1,40 +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 <signal.h>
-#include <string.h>
-
-int sigemptyset(sigset_t* set) {
- if (set == NULL) {
- errno = EINVAL;
- return -1;
- }
- memset(set, 0, sizeof(sigset_t));
- return 0;
-}
diff --git a/libc/bionic/sigfillset.cpp b/libc/bionic/sigfillset.cpp
deleted file mode 100644
index cb67394..0000000
--- a/libc/bionic/sigfillset.cpp
+++ /dev/null
@@ -1,40 +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 <signal.h>
-#include <string.h>
-
-int sigfillset(sigset_t* set) {
- if (set == NULL) {
- errno = EINVAL;
- return -1;
- }
- memset(set, ~0, sizeof(sigset_t));
- return 0;
-}
diff --git a/libc/bionic/sighold.cpp b/libc/bionic/sighold.cpp
deleted file mode 100644
index e9c8ca1..0000000
--- a/libc/bionic/sighold.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2016 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 sighold(int sig) {
- sigset_t set;
- if (sigemptyset(&set) == -1) return -1;
- if (sigaddset(&set, sig) == -1) return -1;
- return sigprocmask(SIG_BLOCK, &set, nullptr);
-}
diff --git a/libc/bionic/sigignore.cpp b/libc/bionic/sigignore.cpp
deleted file mode 100644
index 06f458e..0000000
--- a/libc/bionic/sigignore.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2016 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>
-#include <string.h>
-
-int sigignore(int sig) {
- struct sigaction sa;
- memset(&sa, 0, sizeof(sa));
- if (sigemptyset(&sa.sa_mask) == -1) return -1;
- sa.sa_handler = SIG_IGN;
- return sigaction(sig, &sa, nullptr);
-}
diff --git a/libc/bionic/siginterrupt.c b/libc/bionic/siginterrupt.c
deleted file mode 100644
index 4e91edb..0000000
--- a/libc/bionic/siginterrupt.c
+++ /dev/null
@@ -1,45 +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 <signal.h>
-
-/* this is only useful for legacy programs */
-int siginterrupt(int sig, int flag)
-{
- struct sigaction act;
-
- (void) sigaction(sig, NULL, &act);
-
- if (flag)
- act.sa_flags &= ~SA_RESTART;
- else
- act.sa_flags |= SA_RESTART;
-
- return sigaction(sig, &act, NULL);
-}
-
diff --git a/libc/bionic/sigismember.cpp b/libc/bionic/sigismember.cpp
deleted file mode 100644
index 9d1fc3c..0000000
--- a/libc/bionic/sigismember.cpp
+++ /dev/null
@@ -1,40 +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 <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 = reinterpret_cast<const unsigned long*>(set);
- if (set == NULL || bit < 0 || bit >= static_cast<int>(8*sizeof(sigset_t))) {
- errno = EINVAL;
- return -1;
- }
- return static_cast<int>((local_set[bit / LONG_BIT] >> (bit % LONG_BIT)) & 1);
-}
diff --git a/libc/bionic/signal.cpp b/libc/bionic/signal.cpp
index 13d1882..9a23416 100644
--- a/libc/bionic/signal.cpp
+++ b/libc/bionic/signal.cpp
@@ -26,7 +26,108 @@
* SUCH DAMAGE.
*/
+#include <errno.h>
+#include <pthread.h>
#include <signal.h>
+#include <string.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "private/kernel_sigset_t.h"
+
+extern "C" int ___rt_sigqueueinfo(pid_t, int, siginfo_t*);
+extern "C" int __rt_sigtimedwait(const sigset_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.
+ unsigned long* local_set = reinterpret_cast<unsigned long*>(set);
+ if (set == NULL || bit < 0 || bit >= static_cast<int>(8*sizeof(sigset_t))) {
+ errno = EINVAL;
+ return -1;
+ }
+ local_set[bit / LONG_BIT] |= 1UL << (bit % LONG_BIT);
+ 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;
+
+ sigemptyset(&in.set);
+ in.mask = mask;
+
+ if (sigprocmask(SIG_BLOCK, &in.set, &out.set) == -1) return -1;
+ return out.mask;
+}
+
+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 = reinterpret_cast<unsigned long*>(set);
+ if (set == NULL || bit < 0 || bit >= static_cast<int>(8*sizeof(sigset_t))) {
+ errno = EINVAL;
+ return -1;
+ }
+ local_set[bit / LONG_BIT] &= ~(1UL << (bit % LONG_BIT));
+ return 0;
+}
+
+int sigemptyset(sigset_t* set) {
+ if (set == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+ memset(set, 0, sizeof(sigset_t));
+ return 0;
+}
+
+int sigfillset(sigset_t* set) {
+ if (set == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+ memset(set, ~0, sizeof(sigset_t));
+ return 0;
+}
+
+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));
+}
+
+int sigignore(int sig) {
+ struct sigaction sa;
+ memset(&sa, 0, sizeof(sa));
+ if (sigemptyset(&sa.sa_mask) == -1) return -1;
+ sa.sa_handler = SIG_IGN;
+ return sigaction(sig, &sa, nullptr);
+}
+
+int siginterrupt(int sig, int flag) {
+ struct sigaction act;
+ sigaction(sig, nullptr, &act);
+ if (flag) {
+ act.sa_flags &= ~SA_RESTART;
+ } else {
+ act.sa_flags |= SA_RESTART;
+ }
+ 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.
+ const unsigned long* local_set = reinterpret_cast<const unsigned long*>(set);
+ if (set == NULL || bit < 0 || bit >= static_cast<int>(8*sizeof(sigset_t))) {
+ 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) {
struct sigaction sa;
@@ -44,3 +145,127 @@
sighandler_t signal(int signum, sighandler_t handler) {
return _signal(signum, 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));
+}
+
+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;
+}
+
+int sigprocmask(int how, const sigset_t* bionic_new_set, sigset_t* bionic_old_set) {
+ kernel_sigset_t new_set;
+ kernel_sigset_t* new_set_ptr = NULL;
+ if (bionic_new_set != NULL) {
+ new_set.set(bionic_new_set);
+ new_set_ptr = &new_set;
+ }
+
+ kernel_sigset_t old_set;
+ if (__rt_sigprocmask(how, new_set_ptr, &old_set, sizeof(old_set)) == -1) {
+ return -1;
+ }
+
+ if (bionic_old_set != NULL) {
+ *bionic_old_set = old_set.bionic;
+ }
+
+ return 0;
+}
+
+int sigqueue(pid_t pid, int signo, const sigval value) {
+ siginfo_t info;
+ memset(&info, 0, sizeof(siginfo_t));
+ info.si_signo = signo;
+ info.si_code = SI_QUEUE;
+ info.si_pid = getpid();
+ info.si_uid = getuid();
+ info.si_value = value;
+
+ return ___rt_sigqueueinfo(pid, signo, &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));
+}
+
+sighandler_t sigset(int sig, sighandler_t disp) {
+ struct sigaction new_sa;
+ if (disp != SIG_HOLD) {
+ memset(&new_sa, 0, sizeof(new_sa));
+ new_sa.sa_handler = disp;
+ sigemptyset(&new_sa.sa_mask);
+ }
+
+ struct sigaction old_sa;
+ if (sigaction(sig, (disp == SIG_HOLD) ? nullptr : &new_sa, &old_sa) == -1) {
+ 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) {
+ return SIG_ERR;
+ }
+
+ return old_mask.is_set(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;
+
+ sigemptyset(&in.set);
+ in.mask = mask;
+
+ if (sigprocmask(SIG_SETMASK, &in.set, &out.set) == -1) return -1;
+ return out.mask;
+}
+
+int sigsuspend(const sigset_t* bionic_set) {
+ kernel_sigset_t set(bionic_set);
+ return __rt_sigsuspend(&set, sizeof(set));
+}
+
+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 sigwait(const sigset_t* set, int* sig) {
+ kernel_sigset_t sigset(set);
+ 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));
+ if (result >= 0) {
+ *sig = result;
+ return 0;
+ }
+
+ if (errno != EAGAIN && errno != EINTR) {
+ return errno;
+ }
+ }
+}
+
+int sigwaitinfo(const sigset_t* set, siginfo_t* info) {
+ return sigtimedwait(set, info, NULL);
+}
diff --git a/libc/bionic/sigpause.cpp b/libc/bionic/sigpause.cpp
deleted file mode 100644
index 8ba42d4..0000000
--- a/libc/bionic/sigpause.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2016 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 sigpause(int sig) {
- sigset_t set;
- if (sigprocmask(SIG_SETMASK, nullptr, &set) == -1) return -1;
- if (sigdelset(&set, sig) == -1) return -1;
- return sigsuspend(&set);
-}
diff --git a/libc/bionic/sigpending.cpp b/libc/bionic/sigpending.cpp
deleted file mode 100644
index b6e503c..0000000
--- a/libc/bionic/sigpending.cpp
+++ /dev/null
@@ -1,42 +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 <signal.h>
-
-#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/bionic/sigprocmask.cpp b/libc/bionic/sigprocmask.cpp
deleted file mode 100644
index 61e2c63..0000000
--- a/libc/bionic/sigprocmask.cpp
+++ /dev/null
@@ -1,55 +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 <errno.h>
-#include <pthread.h>
-#include <signal.h>
-
-#include "private/kernel_sigset_t.h"
-
-extern "C" int __rt_sigprocmask(int, const kernel_sigset_t*, kernel_sigset_t*, size_t);
-
-int sigprocmask(int how, const sigset_t* bionic_new_set, sigset_t* bionic_old_set) {
- kernel_sigset_t new_set;
- kernel_sigset_t* new_set_ptr = NULL;
- if (bionic_new_set != NULL) {
- new_set.set(bionic_new_set);
- new_set_ptr = &new_set;
- }
-
- kernel_sigset_t old_set;
- if (__rt_sigprocmask(how, new_set_ptr, &old_set, sizeof(old_set)) == -1) {
- return -1;
- }
-
- if (bionic_old_set != NULL) {
- *bionic_old_set = old_set.bionic;
- }
-
- return 0;
-}
diff --git a/libc/bionic/sigqueue.cpp b/libc/bionic/sigqueue.cpp
deleted file mode 100644
index 8741460..0000000
--- a/libc/bionic/sigqueue.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2014 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>
-#include <string.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-extern "C" int ___rt_sigqueueinfo(pid_t, int, siginfo_t*);
-
-int sigqueue(pid_t pid, int signo, const sigval value) {
- siginfo_t info;
- memset(&info, 0, sizeof(siginfo_t));
- info.si_signo = signo;
- info.si_code = SI_QUEUE;
- info.si_pid = getpid();
- info.si_uid = getuid();
- info.si_value = value;
-
- return ___rt_sigqueueinfo(pid, signo, &info);
-}
diff --git a/libc/bionic/sigrelse.cpp b/libc/bionic/sigrelse.cpp
deleted file mode 100644
index ab5554e..0000000
--- a/libc/bionic/sigrelse.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2016 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 sigrelse(int sig) {
- sigset_t set;
- if (sigemptyset(&set) == -1) return -1;
- if (sigaddset(&set, sig) == -1) return -1;
- return sigprocmask(SIG_UNBLOCK, &set, nullptr);
-}
diff --git a/libc/bionic/sigset.cpp b/libc/bionic/sigset.cpp
deleted file mode 100644
index e3f3e72..0000000
--- a/libc/bionic/sigset.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2016 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>
-#include <string.h>
-
-sighandler_t sigset(int sig, sighandler_t disp) {
- struct sigaction new_sa;
- if (disp != SIG_HOLD) {
- memset(&new_sa, 0, sizeof(new_sa));
- new_sa.sa_handler = disp;
- sigemptyset(&new_sa.sa_mask);
- }
-
- struct sigaction old_sa;
- if (sigaction(sig, disp == SIG_HOLD ? nullptr : &new_sa, &old_sa) == -1) {
- return SIG_ERR;
- }
-
- sigset_t new_proc_mask;
- sigemptyset(&new_proc_mask);
- sigaddset(&new_proc_mask, sig);
-
- sigset_t old_proc_mask;
- if (sigprocmask(disp == SIG_HOLD ? SIG_BLOCK : SIG_UNBLOCK,
- &new_proc_mask, &old_proc_mask) == -1) {
- return SIG_ERR;
- }
-
- return sigismember(&old_proc_mask, sig) ? SIG_HOLD : old_sa.sa_handler;
-}
diff --git a/libc/bionic/sigsetmask.c b/libc/bionic/sigsetmask.c
deleted file mode 100644
index 7842bf1..0000000
--- a/libc/bionic/sigsetmask.c
+++ /dev/null
@@ -1,50 +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 <signal.h>
-
-/* called from setjmp assembly fragment */
-int
-sigsetmask(int mask)
-{
- int n;
-
- union {
- int the_mask;
- sigset_t the_sigset;
- } in, out;
-
- sigemptyset(&in.the_sigset);
- in.the_mask = mask;
-
- n = sigprocmask(SIG_SETMASK, &in.the_sigset, &out.the_sigset);
- if (n)
- return n;
-
- return out.the_mask;
-}
-
diff --git a/libc/bionic/sigsuspend.cpp b/libc/bionic/sigsuspend.cpp
deleted file mode 100644
index fb846b8..0000000
--- a/libc/bionic/sigsuspend.cpp
+++ /dev/null
@@ -1,38 +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 <signal.h>
-
-#include "private/kernel_sigset_t.h"
-
-extern "C" int __rt_sigsuspend(const kernel_sigset_t*, size_t);
-
-int sigsuspend(const sigset_t* bionic_set) {
- kernel_sigset_t set(bionic_set);
- return __rt_sigsuspend(&set, sizeof(set));
-}
diff --git a/libc/bionic/sigtimedwait.cpp b/libc/bionic/sigtimedwait.cpp
deleted file mode 100644
index c29f806..0000000
--- a/libc/bionic/sigtimedwait.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2014 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>
-
-#include "private/kernel_sigset_t.h"
-
-extern "C" int __rt_sigtimedwait(const sigset_t*, siginfo_t*, const timespec*, size_t);
-
-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));
-}
diff --git a/libc/bionic/sigwait.cpp b/libc/bionic/sigwait.cpp
deleted file mode 100644
index 2534b89..0000000
--- a/libc/bionic/sigwait.cpp
+++ /dev/null
@@ -1,53 +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 <signal.h>
-#include <string.h>
-#include <time.h>
-
-#include "private/kernel_sigset_t.h"
-
-extern "C" int __rt_sigtimedwait(const sigset_t*, siginfo_t*, const timespec*, size_t);
-
-int sigwait(const sigset_t* set, int* sig) {
- kernel_sigset_t sigset(set);
- 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));
- if (result >= 0) {
- *sig = result;
- return 0;
- }
-
- if (errno != EAGAIN && errno != EINTR) {
- return errno;
- }
- }
-}
diff --git a/libc/bionic/sigwaitinfo.cpp b/libc/bionic/sigwaitinfo.cpp
deleted file mode 100644
index 43e2395..0000000
--- a/libc/bionic/sigwaitinfo.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2014 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 sigwaitinfo(const sigset_t* set, siginfo_t* info) {
- return sigtimedwait(set, info, NULL);
-}
diff --git a/libc/bionic/signalfd.cpp b/libc/bionic/sys_signalfd.cpp
similarity index 100%
rename from libc/bionic/signalfd.cpp
rename to libc/bionic/sys_signalfd.cpp
diff --git a/libc/include/android/dlext.h b/libc/include/android/dlext.h
index c824544..2b4169e 100644
--- a/libc/include/android/dlext.h
+++ b/libc/include/android/dlext.h
@@ -23,88 +23,116 @@
#include <sys/cdefs.h>
#include <sys/types.h> /* for off64_t */
+/**
+ * \file
+ * Advanced dynamic library opening support. Most users will want to use
+ * the standard [dlopen(3)](http://man7.org/linux/man-pages/man3/dlopen.3.html)
+ * functionality in `<dlfcn.h>` instead.
+ */
+
__BEGIN_DECLS
-/* bitfield definitions for android_dlextinfo.flags */
+/** Bitfield definitions for `android_dlextinfo::flags`. */
enum {
- /* When set, the reserved_addr and reserved_size fields must point to an
+ /**
+ * When set, the `reserved_addr` and `reserved_size` fields must point to an
* already-reserved region of address space which will be used to load the
- * library if it fits. If the reserved region is not large enough, the load
- * will fail.
+ * library if it fits.
+ *
+ * If the reserved region is not large enough, loading will fail.
*/
ANDROID_DLEXT_RESERVED_ADDRESS = 0x1,
- /* As DLEXT_RESERVED_ADDRESS, but if the reserved region is not large enough,
+ /**
+ * Like `ANDROID_DLEXT_RESERVED_ADDRESS`, but if the reserved region is not large enough,
* the linker will choose an available address instead.
*/
ANDROID_DLEXT_RESERVED_ADDRESS_HINT = 0x2,
- /* When set, write the GNU RELRO section of the mapped library to relro_fd
+ /**
+ * When set, write the GNU RELRO section of the mapped library to `relro_fd`
* after relocation has been performed, to allow it to be reused by another
* process loading the same library at the same address. This implies
- * ANDROID_DLEXT_USE_RELRO.
+ * `ANDROID_DLEXT_USE_RELRO`.
+ *
+ * This is mainly useful for the system WebView implementation.
*/
ANDROID_DLEXT_WRITE_RELRO = 0x4,
- /* When set, compare the GNU RELRO section of the mapped library to relro_fd
+ /**
+ * When set, compare the GNU RELRO section of the mapped library to `relro_fd`
* after relocation has been performed, and replace any relocated pages that
* are identical with a version mapped from the file.
+ *
+ * This is mainly useful for the system WebView implementation.
*/
ANDROID_DLEXT_USE_RELRO = 0x8,
- /* Instruct dlopen to use library_fd instead of opening file by name.
+ /**
+ * Use `library_fd` instead of opening the file by name.
* The filename parameter is still used to identify the library.
*/
ANDROID_DLEXT_USE_LIBRARY_FD = 0x10,
- /* If opening a library using library_fd read it starting at library_fd_offset.
- * This flag is only valid when ANDROID_DLEXT_USE_LIBRARY_FD is set.
+ /**
+ * If opening a library using `library_fd` read it starting at `library_fd_offset`.
+ * This is mainly useful for loading a library stored within another file (such as uncompressed
+ * inside a ZIP archive).
+ * This flag is only valid when `ANDROID_DLEXT_USE_LIBRARY_FD` is set.
*/
ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET = 0x20,
- /* When set, do not check if the library has already been loaded by file stat(2)s.
+ /**
+ * When set, do not use `stat(2)` to check if the library has already been loaded.
*
* This flag allows forced loading of the library in the case when for some
* reason multiple ELF files share the same filename (because the already-loaded
* library has been removed and overwritten, for example).
*
- * Note that if the library has the same dt_soname as an old one and some other
- * library has the soname in DT_NEEDED list, the first one will be used to resolve any
+ * Note that if the library has the same `DT_SONAME` as an old one and some other
+ * library has the soname in its `DT_NEEDED` list, the first one will be used to resolve any
* dependencies.
*/
ANDROID_DLEXT_FORCE_LOAD = 0x40,
- /* When set, if the minimum p_vaddr of the ELF file's PT_LOAD segments is non-zero,
+ /**
+ * When set, if the minimum `p_vaddr` of the ELF file's `PT_LOAD` segments is non-zero,
* the dynamic linker will load it at that address.
*
* This flag is for ART internal use only.
*/
ANDROID_DLEXT_FORCE_FIXED_VADDR = 0x80,
- /* Instructs dlopen to load the library at the address specified by reserved_addr.
+ /**
+ * Instructs dlopen to load the library at the address specified by reserved_addr.
*
- * The difference between ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS and ANDROID_DLEXT_RESERVED_ADDRESS
- * is that for ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS the linker reserves memory at reserved_addr
- * whereas for ANDROID_DLEXT_RESERVED_ADDRESS the linker relies on the caller to reserve the memory.
+ * The difference between `ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS` and
+ * `ANDROID_DLEXT_RESERVED_ADDRESS` is that for `ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS` the linker
+ * reserves memory at `reserved_addr` whereas for `ANDROID_DLEXT_RESERVED_ADDRESS` the linker
+ * relies on the caller to reserve the memory.
*
- * This flag can be used with ANDROID_DLEXT_FORCE_FIXED_VADDR; when ANDROID_DLEXT_FORCE_FIXED_VADDR
- * is set and load_bias is not 0 (load_bias is min(p_vaddr) of PT_LOAD segments) this flag is ignored.
- * This is implemented this way because the linker has to pick one address over the other and this
- * way is more convenient for art. Note that ANDROID_DLEXT_FORCE_FIXED_VADDR does not generate
- * an error when min(p_vaddr) is 0.
+ * This flag can be used with `ANDROID_DLEXT_FORCE_FIXED_VADDR`. When
+ * `ANDROID_DLEXT_FORCE_FIXED_VADDR` is set and `load_bias` is not 0 (`load_bias` is the
+ * minimum `p_vaddr` of all `PT_LOAD` segments) this flag is ignored because the linker has to
+ * pick one address over the other and this way is more convenient for ART.
+ * Note that `ANDROID_DLEXT_FORCE_FIXED_VADDR` does not generate an error when the minimum
+ * `p_vaddr` is 0.
*
- * Cannot be used with ANDROID_DLEXT_RESERVED_ADDRESS or ANDROID_DLEXT_RESERVED_ADDRESS_HINT.
+ * Cannot be used with `ANDROID_DLEXT_RESERVED_ADDRESS` or `ANDROID_DLEXT_RESERVED_ADDRESS_HINT`.
*
* This flag is for ART internal use only.
*/
ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS = 0x100,
- /* This flag used to load library in a different namespace. The namespace is
- * specified in library_namespace.
+ /**
+ * This flag used to load library in a different namespace. The namespace is
+ * specified in `library_namespace`.
+ *
+ * This flag is for internal use only (since there is no NDK API for namespaces).
*/
ANDROID_DLEXT_USE_NAMESPACE = 0x200,
- /* Mask of valid bits */
+ /** Mask of valid bits. */
ANDROID_DLEXT_VALID_FLAG_BITS = ANDROID_DLEXT_RESERVED_ADDRESS |
ANDROID_DLEXT_RESERVED_ADDRESS_HINT |
ANDROID_DLEXT_WRITE_RELRO |
@@ -119,19 +147,36 @@
struct android_namespace_t;
+/** Used to pass Android-specific arguments to `android_dlopen_ext`. */
typedef struct {
+ /** A bitmask of `ANDROID_DLEXT_` enum values. */
uint64_t flags;
+
+ /** Used by `ANDROID_DLEXT_RESERVED_ADDRESS` and `ANDROID_DLEXT_RESERVED_ADDRESS_HINT`. */
void* reserved_addr;
+ /** Used by `ANDROID_DLEXT_RESERVED_ADDRESS` and `ANDROID_DLEXT_RESERVED_ADDRESS_HINT`. */
size_t reserved_size;
+
+ /** Used by `ANDROID_DLEXT_WRITE_RELRO` and `ANDROID_DLEXT_USE_RELRO`. */
int relro_fd;
+
+ /** Used by `ANDROID_DLEXT_USE_LIBRARY_FD`. */
int library_fd;
+ /** Used by `ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET` */
off64_t library_fd_offset;
+
+ /** Used by `ANDROID_DLEXT_USE_NAMESPACE`. */
struct android_namespace_t* library_namespace;
} android_dlextinfo;
+/**
+ * Opens the given library. The `__filename` and `__flags` arguments are
+ * the same as for [dlopen(3)](http://man7.org/linux/man-pages/man3/dlopen.3.html),
+ * with the Android-specific flags supplied via the `flags` member of `__info`.
+ */
void* android_dlopen_ext(const char* __filename, int __flags, const android_dlextinfo* __info)
__INTRODUCED_IN(21);
__END_DECLS
-#endif /* __ANDROID_DLEXT_H__ */
+#endif
diff --git a/libc/include/bits/fortify/fcntl.h b/libc/include/bits/fortify/fcntl.h
index 6d90341..75cd4f2 100644
--- a/libc/include/bits/fortify/fcntl.h
+++ b/libc/include/bits/fortify/fcntl.h
@@ -98,7 +98,7 @@
__errordecl(__creat_too_many_args, __open_too_many_args_error);
#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
-__BIONIC_FORTIFY_INLINE
+__BIONIC_FORTIFY_VARIADIC
int open(const char* pathname, int flags, ...) {
if (__builtin_constant_p(flags)) {
if (__open_modes_useful(flags) && __builtin_va_arg_pack_len() == 0) {
@@ -117,7 +117,7 @@
return __open_real(pathname, flags, __builtin_va_arg_pack());
}
-__BIONIC_FORTIFY_INLINE
+__BIONIC_FORTIFY_VARIADIC
int openat(int dirfd, const char* pathname, int flags, ...) {
if (__builtin_constant_p(flags)) {
if (__open_modes_useful(flags) && __builtin_va_arg_pack_len() == 0) {
diff --git a/libc/include/bits/fortify/stdio.h b/libc/include/bits/fortify/stdio.h
index cfc78d7..6a6b433 100644
--- a/libc/include/bits/fortify/stdio.h
+++ b/libc/include/bits/fortify/stdio.h
@@ -63,8 +63,7 @@
"format string will always overflow destination buffer")
__errorattr("format string will always overflow destination buffer");
-__BIONIC_FORTIFY_INLINE
-__printflike(3, 4)
+__BIONIC_FORTIFY_VARIADIC __printflike(3, 4)
int snprintf(char* const __pass_object_size dest, size_t size, const char* format, ...)
__overloadable {
va_list va;
@@ -82,8 +81,7 @@
"format string will always overflow destination buffer")
__errorattr("format string will always overflow destination buffer");
-__BIONIC_FORTIFY_INLINE
-__printflike(2, 3)
+__BIONIC_FORTIFY_VARIADIC __printflike(2, 3)
int sprintf(char* const __pass_object_size dest, const char* format, ...) __overloadable {
va_list va;
va_start(va, format);
@@ -159,12 +157,12 @@
#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
-__BIONIC_FORTIFY_INLINE __printflike(3, 4)
+__BIONIC_FORTIFY_VARIADIC __printflike(3, 4)
int snprintf(char* dest, size_t size, const char* format, ...) {
return __builtin___snprintf_chk(dest, size, 0, __bos(dest), format, __builtin_va_arg_pack());
}
-__BIONIC_FORTIFY_INLINE __printflike(2, 3)
+__BIONIC_FORTIFY_VARIADIC __printflike(2, 3)
int sprintf(char* dest, const char* format, ...) {
return __builtin___sprintf_chk(dest, 0, __bos(dest), format, __builtin_va_arg_pack());
}
diff --git a/libc/include/elf.h b/libc/include/elf.h
index bda11f5..a8d62db 100644
--- a/libc/include/elf.h
+++ b/libc/include/elf.h
@@ -194,13 +194,9 @@
Elf64_Word vna_next;
} Elf64_Vernaux;
-/* Relocation table entry for relative (in section of type SHT_RELR). */
+/* Relocation table entry for relative (in section of type SHT_RELR). */
typedef Elf32_Word Elf32_Relr;
typedef Elf64_Xword Elf64_Relr;
-#define ELF32_R_JUMP(val) ((val) >> 24)
-#define ELF32_R_BITS(val) ((val) & 0xffffff)
-#define ELF64_R_JUMP(val) ((val) >> 56)
-#define ELF64_R_BITS(val) ((val) & 0xffffffffffffff)
/* http://www.sco.com/developers/gabi/latest/ch5.dynamic.html */
#define DF_ORIGIN 0x00000001
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index 3cf6723..be07007 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -300,6 +300,13 @@
* inline` without making them available externally.
*/
# define __BIONIC_FORTIFY_INLINE static __inline__ __always_inline
+/*
+ * We should use __BIONIC_FORTIFY_VARIADIC instead of __BIONIC_FORTIFY_INLINE
+ * for variadic functions because compilers cannot inline them.
+ * The __always_inline attribute is useless, misleading, and could trigger
+ * clang compiler bug to incorrectly inline variadic functions.
+ */
+# define __BIONIC_FORTIFY_VARIADIC static __inline__
/* Error functions don't have bodies, so they can just be static. */
# define __BIONIC_ERROR_FUNCTION_VISIBILITY static
# else
@@ -311,6 +318,8 @@
# define __call_bypassing_fortify(fn) (fn)
/* __BIONIC_FORTIFY_NONSTATIC_INLINE is pointless in GCC's FORTIFY */
# define __BIONIC_FORTIFY_INLINE extern __inline__ __always_inline __attribute__((gnu_inline)) __attribute__((__artificial__))
+/* __always_inline is probably okay and ignored by gcc in __BIONIC_FORTIFY_VARIADIC */
+# define __BIONIC_FORTIFY_VARIADIC __BIONIC_FORTIFY_INLINE
# endif
#else
/* Further increase sharing for some inline functions */
diff --git a/libc/include/sys/ioctl.h b/libc/include/sys/ioctl.h
index 76dc1ff..b48b7f9 100644
--- a/libc/include/sys/ioctl.h
+++ b/libc/include/sys/ioctl.h
@@ -36,8 +36,6 @@
* terminal-related ioctl data structures such as struct winsize.
*/
#include <linux/termios.h>
-#include <asm/ioctls.h>
-#include <asm/termbits.h>
#include <linux/tty.h>
#include <bits/ioctl.h>
diff --git a/libc/private/ScopedSignalBlocker.h b/libc/private/ScopedSignalBlocker.h
index 35d1c58..c3ab307 100644
--- a/libc/private/ScopedSignalBlocker.h
+++ b/libc/private/ScopedSignalBlocker.h
@@ -20,13 +20,14 @@
#include <signal.h>
#include "bionic_macros.h"
+#include "kernel_sigset_t.h"
class ScopedSignalBlocker {
public:
explicit ScopedSignalBlocker() {
- sigset_t set;
- sigfillset(&set);
- sigprocmask(SIG_BLOCK, &set, &old_set_);
+ kernel_sigset_t set;
+ set.fill();
+ __rt_sigprocmask(SIG_SETMASK, &set, &old_set_, sizeof(set));
}
~ScopedSignalBlocker() {
@@ -34,11 +35,11 @@
}
void reset() {
- sigprocmask(SIG_SETMASK, &old_set_, nullptr);
+ __rt_sigprocmask(SIG_SETMASK, &old_set_, nullptr, sizeof(old_set_));
}
private:
- sigset_t old_set_;
+ kernel_sigset_t old_set_;
DISALLOW_COPY_AND_ASSIGN(ScopedSignalBlocker);
};
diff --git a/libc/private/kernel_sigset_t.h b/libc/private/kernel_sigset_t.h
index 9415fcf..bdfb729 100644
--- a/libc/private/kernel_sigset_t.h
+++ b/libc/private/kernel_sigset_t.h
@@ -17,18 +17,27 @@
#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 until we can change the ABI.
+// 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.
+// 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() {
- clear();
}
- kernel_sigset_t(const sigset_t* value) {
+ 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);
}
@@ -37,7 +46,32 @@
__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;
}
@@ -46,9 +80,21 @@
}
sigset_t bionic;
-#ifndef __mips__
- uint32_t kernel[2];
-#endif
+ 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
diff --git a/libdl/libdl.arm.map b/libdl/libdl.arm.map
index 7ed9503..1fcfc58 100644
--- a/libdl/libdl.arm.map
+++ b/libdl/libdl.arm.map
@@ -41,11 +41,6 @@
__cfi_slowpath_diag;
} LIBC_N;
-LIBC_PRIVATE {
- global:
- android_link_namespaces_all_libs;
-} LIBC_OMR1;
-
LIBC_PLATFORM {
global:
__cfi_init;
diff --git a/libdl/libdl.arm64.map b/libdl/libdl.arm64.map
index 199f2e3..8d4019c 100644
--- a/libdl/libdl.arm64.map
+++ b/libdl/libdl.arm64.map
@@ -40,11 +40,6 @@
__cfi_slowpath_diag;
} LIBC_N;
-LIBC_PRIVATE {
- global:
- android_link_namespaces_all_libs;
-} LIBC_OMR1;
-
LIBC_PLATFORM {
global:
__cfi_init;
diff --git a/libdl/libdl.cpp b/libdl/libdl.cpp
index 4c2415f..c834088 100644
--- a/libdl/libdl.cpp
+++ b/libdl/libdl.cpp
@@ -93,11 +93,6 @@
const char* shared_libs_sonames);
__attribute__((__weak__, visibility("default")))
-bool __loader_android_link_namespaces_all_libs(
- struct android_namespace_t* namespace_from,
- struct android_namespace_t* namespace_to);
-
-__attribute__((__weak__, visibility("default")))
void __loader_android_dlwarning(void* obj, void (*f)(void*, const char*));
__attribute__((__weak__, visibility("default")))
@@ -210,12 +205,6 @@
}
__attribute__((__weak__))
-bool android_link_namespaces_all_libs(struct android_namespace_t* namespace_from,
- struct android_namespace_t* namespace_to) {
- return __loader_android_link_namespaces_all_libs(namespace_from, namespace_to);
-}
-
-__attribute__((__weak__))
void android_dlwarning(void* obj, void (*f)(void*, const char*)) {
__loader_android_dlwarning(obj, f);
}
diff --git a/libdl/libdl.map.txt b/libdl/libdl.map.txt
index 579ffa7..002e9f8 100644
--- a/libdl/libdl.map.txt
+++ b/libdl/libdl.map.txt
@@ -40,11 +40,6 @@
__cfi_slowpath_diag;
} LIBC_N;
-LIBC_PRIVATE {
- global:
- android_link_namespaces_all_libs;
-} LIBC_OMR1;
-
LIBC_PLATFORM {
global:
__cfi_init;
diff --git a/libdl/libdl.mips.map b/libdl/libdl.mips.map
index 199f2e3..8d4019c 100644
--- a/libdl/libdl.mips.map
+++ b/libdl/libdl.mips.map
@@ -40,11 +40,6 @@
__cfi_slowpath_diag;
} LIBC_N;
-LIBC_PRIVATE {
- global:
- android_link_namespaces_all_libs;
-} LIBC_OMR1;
-
LIBC_PLATFORM {
global:
__cfi_init;
diff --git a/libdl/libdl.mips64.map b/libdl/libdl.mips64.map
index 199f2e3..8d4019c 100644
--- a/libdl/libdl.mips64.map
+++ b/libdl/libdl.mips64.map
@@ -40,11 +40,6 @@
__cfi_slowpath_diag;
} LIBC_N;
-LIBC_PRIVATE {
- global:
- android_link_namespaces_all_libs;
-} LIBC_OMR1;
-
LIBC_PLATFORM {
global:
__cfi_init;
diff --git a/libdl/libdl.x86.map b/libdl/libdl.x86.map
index 199f2e3..8d4019c 100644
--- a/libdl/libdl.x86.map
+++ b/libdl/libdl.x86.map
@@ -40,11 +40,6 @@
__cfi_slowpath_diag;
} LIBC_N;
-LIBC_PRIVATE {
- global:
- android_link_namespaces_all_libs;
-} LIBC_OMR1;
-
LIBC_PLATFORM {
global:
__cfi_init;
diff --git a/libdl/libdl.x86_64.map b/libdl/libdl.x86_64.map
index 199f2e3..8d4019c 100644
--- a/libdl/libdl.x86_64.map
+++ b/libdl/libdl.x86_64.map
@@ -40,11 +40,6 @@
__cfi_slowpath_diag;
} LIBC_N;
-LIBC_PRIVATE {
- global:
- android_link_namespaces_all_libs;
-} LIBC_OMR1;
-
LIBC_PLATFORM {
global:
__cfi_init;
diff --git a/linker/ld_android.cpp b/linker/ld_android.cpp
index 4a05772..e2499b3 100644
--- a/linker/ld_android.cpp
+++ b/linker/ld_android.cpp
@@ -29,14 +29,6 @@
#include <stdlib.h>
#include <sys/cdefs.h>
-extern "C" void __somehow_you_managed_to_not_get_the_actual_symbols_from_the_linker();
-
-extern "C" void __ld_android_init() __attribute__((constructor));
-
-void __ld_android_init() {
- __somehow_you_managed_to_not_get_the_actual_symbols_from_the_linker();
-}
-
extern "C" void __internal_linker_error() {
abort();
}
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 0b8d5ee..3f898ba 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -2614,31 +2614,46 @@
return true;
}
+void soinfo::apply_relr_reloc(ElfW(Addr) offset) {
+ ElfW(Addr) address = offset + load_bias;
+ *reinterpret_cast<ElfW(Addr)*>(address) += load_bias;
+}
+
// Process relocations in SHT_RELR section (experimental).
-// See the original proposal for details of the encoding:
-// - https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg
+// Details of the encoding are described in this post:
+// https://groups.google.com/d/msg/generic-abi/bX460iggiKg/Pi9aSwwABgAJ
bool soinfo::relocate_relr() {
ElfW(Relr)* begin = relr_;
ElfW(Relr)* end = relr_ + relr_count_;
+ constexpr size_t wordsize = sizeof(ElfW(Addr));
- ElfW(Addr) offset = 0;
+ ElfW(Addr) base = 0;
for (ElfW(Relr)* current = begin; current < end; ++current) {
- ElfW(Addr) jump = ELFW(R_JUMP)(*current);
- ElfW(Addr) bits = ELFW(R_BITS)(*current);
- offset += jump * sizeof(ElfW(Addr));
- if (jump == 0) {
- ++current;
- offset = *current;
+ ElfW(Relr) entry = *current;
+ ElfW(Addr) offset;
+
+ if ((entry&1) == 0) {
+ // Even entry: encodes the offset for next relocation.
+ offset = static_cast<ElfW(Addr)>(entry);
+ apply_relr_reloc(offset);
+ // Set base offset for subsequent bitmap entries.
+ base = offset + wordsize;
+ continue;
}
- ElfW(Addr) r_offset = offset;
- for (; bits != 0; bits >>= 1) {
- if ((bits&1) != 0) {
- ElfW(Addr) reloc = static_cast<ElfW(Addr)>(r_offset + load_bias);
- ElfW(Addr) addend = *reinterpret_cast<ElfW(Addr)*>(reloc);
- *reinterpret_cast<ElfW(Addr)*>(reloc) = (load_bias + addend);
+
+ // Odd entry: encodes bitmap for relocations starting at base.
+ offset = base;
+ while (entry != 0) {
+ entry >>= 1;
+ if ((entry&1) != 0) {
+ apply_relr_reloc(offset);
}
- r_offset += sizeof(ElfW(Addr));
+ offset += wordsize;
}
+
+ // Advance base offset by 63 words for 64-bit platforms,
+ // or 31 words for 32-bit platforms.
+ base += (8*wordsize - 1) * wordsize;
}
return true;
}
diff --git a/linker/linker_soinfo.h b/linker/linker_soinfo.h
index cb607a9..447c7c3 100644
--- a/linker/linker_soinfo.h
+++ b/linker/linker_soinfo.h
@@ -310,6 +310,7 @@
bool relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& rel_iterator,
const soinfo_list_t& global_group, const soinfo_list_t& local_group);
bool relocate_relr();
+ void apply_relr_reloc(ElfW(Addr) offset);
private:
// This part of the structure is only available
diff --git a/tests/Android.bp b/tests/Android.bp
index 1521b73..25377df 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -413,6 +413,7 @@
target: {
android: {
shared_libs: [
+ "ld-android",
"libdl",
"libdl_preempt_test_1",
"libdl_preempt_test_2",
diff --git a/tests/ScopedSignalHandler.h b/tests/ScopedSignalHandler.h
index 8998d0d..71f22dc 100644
--- a/tests/ScopedSignalHandler.h
+++ b/tests/ScopedSignalHandler.h
@@ -53,13 +53,13 @@
const int signal_number_;
};
-class ScopedSignalMask {
+class SignalMaskRestorer {
public:
- ScopedSignalMask() {
+ SignalMaskRestorer() {
sigprocmask(SIG_SETMASK, nullptr, &old_mask_);
}
- ~ScopedSignalMask() {
+ ~SignalMaskRestorer() {
sigprocmask(SIG_SETMASK, &old_mask_, nullptr);
}
diff --git a/tests/dlext_test.cpp b/tests/dlext_test.cpp
index bb2d8a3..9ed1a56 100644
--- a/tests/dlext_test.cpp
+++ b/tests/dlext_test.cpp
@@ -1737,6 +1737,9 @@
ASSERT_EQ(expected_dlerror, dlerror());
}
+extern "C" bool __loader_android_link_namespaces_all_libs(android_namespace_t* namespace_from,
+ android_namespace_t* namespace_to);
+
TEST(dlext, ns_link_namespaces_invalid_arguments) {
ASSERT_TRUE(android_init_anonymous_namespace(g_core_shared_libs.c_str(), nullptr));
@@ -1764,16 +1767,16 @@
"error linking namespaces \"private\"->\"(default)\": "
"the list of shared libraries is empty.", dlerror());
- // Test android_link_namespaces_all_libs()
- ASSERT_FALSE(android_link_namespaces_all_libs(nullptr, nullptr));
+ // Test __loader_android_link_namespaces_all_libs()
+ ASSERT_FALSE(__loader_android_link_namespaces_all_libs(nullptr, nullptr));
ASSERT_STREQ("android_link_namespaces_all_libs failed: "
"error linking namespaces: namespace_from is null.", dlerror());
- ASSERT_FALSE(android_link_namespaces_all_libs(nullptr, ns));
+ ASSERT_FALSE(__loader_android_link_namespaces_all_libs(nullptr, ns));
ASSERT_STREQ("android_link_namespaces_all_libs failed: "
"error linking namespaces: namespace_from is null.", dlerror());
- ASSERT_FALSE(android_link_namespaces_all_libs(ns, nullptr));
+ ASSERT_FALSE(__loader_android_link_namespaces_all_libs(ns, nullptr));
ASSERT_STREQ("android_link_namespaces_all_libs failed: "
"error linking namespaces: namespace_to is null.", dlerror());
}
@@ -1802,7 +1805,7 @@
ASSERT_TRUE(android_link_namespaces(ns_b, nullptr, g_core_shared_libs.c_str())) << dlerror();
ASSERT_TRUE(android_link_namespaces(ns_b, ns_a, "libnstest_ns_a_public1.so")) << dlerror();
- ASSERT_TRUE(android_link_namespaces_all_libs(ns_a, ns_b)) << dlerror();
+ ASSERT_TRUE(__loader_android_link_namespaces_all_libs(ns_a, ns_b)) << dlerror();
// Load libs with android_dlopen_ext() from namespace b
android_dlextinfo extinfo;
diff --git a/tests/headers/posix/pthread_h.c b/tests/headers/posix/pthread_h.c
index 4fa5b9d..4be822c 100644
--- a/tests/headers/posix/pthread_h.c
+++ b/tests/headers/posix/pthread_h.c
@@ -57,9 +57,9 @@
MACRO(PTHREAD_ONCE_INIT);
-#if !defined(__BIONIC__) // No robust mutexes on Android.
MACRO(PTHREAD_PRIO_INHERIT);
MACRO(PTHREAD_PRIO_NONE);
+#if !defined(__BIONIC__)
MACRO(PTHREAD_PRIO_PROTECT);
#endif
@@ -158,8 +158,8 @@
FUNCTION(pthread_mutexattr_destroy, int (*f)(pthread_mutexattr_t*));
#if !defined(__BIONIC__) // No robust mutexes on Android.
FUNCTION(pthread_mutexattr_getprioceiling, int (*f)(const pthread_mutexattr_t*, int*));
- FUNCTION(pthread_mutexattr_getprotocol, int (*f)(const pthread_mutexattr_t*, int*));
#endif
+ FUNCTION(pthread_mutexattr_getprotocol, int (*f)(const pthread_mutexattr_t*, int*));
FUNCTION(pthread_mutexattr_getpshared, int (*f)(const pthread_mutexattr_t*, int*));
#if !defined(__BIONIC__) // No robust mutexes on Android.
FUNCTION(pthread_mutexattr_getrobust, int (*f)(const pthread_mutexattr_t*, int*));
@@ -168,8 +168,8 @@
FUNCTION(pthread_mutexattr_init, int (*f)(pthread_mutexattr_t*));
#if !defined(__BIONIC__) // No robust mutexes on Android.
FUNCTION(pthread_mutexattr_setprioceiling, int (*f)(pthread_mutexattr_t*, int));
- FUNCTION(pthread_mutexattr_setprotocol, int (*f)(pthread_mutexattr_t*, int));
#endif
+ FUNCTION(pthread_mutexattr_setprotocol, int (*f)(pthread_mutexattr_t*, int));
FUNCTION(pthread_mutexattr_setpshared, int (*f)(pthread_mutexattr_t*, int));
#if !defined(__BIONIC__) // No robust mutexes on Android.
FUNCTION(pthread_mutexattr_setrobust, int (*f)(pthread_mutexattr_t*, int));
diff --git a/tests/signal_test.cpp b/tests/signal_test.cpp
index 207c156..5cbec88 100644
--- a/tests/signal_test.cpp
+++ b/tests/signal_test.cpp
@@ -464,33 +464,45 @@
ASSERT_EQ(EINVAL, errno);
}
-TEST(signal, sighold_sigpause_sigrelse) {
- static int sigalrm_handler_call_count;
- auto sigalrm_handler = [](int) { sigalrm_handler_call_count++; };
- ScopedSignalHandler sigalrm{SIGALRM, sigalrm_handler};
- ScopedSignalMask mask;
+static void TestSigholdSigpauseSigrelse(int sig) {
+ static int signal_handler_call_count = 0;
+ ScopedSignalHandler ssh{sig, [](int) { signal_handler_call_count++; }};
+ SignalMaskRestorer mask_restorer;
sigset_t set;
- // sighold(SIGALRM) should add SIGALRM to the signal mask ...
- ASSERT_EQ(0, sighold(SIGALRM));
+ // sighold(SIGALRM/SIGRTMIN) should add SIGALRM/SIGRTMIN to the signal mask ...
+ ASSERT_EQ(0, sighold(sig));
ASSERT_EQ(0, sigprocmask(SIG_SETMASK, 0, &set));
- EXPECT_TRUE(sigismember(&set, SIGALRM));
+ EXPECT_TRUE(sigismember(&set, sig));
- // ... preventing our SIGALRM handler from running ...
- raise(SIGALRM);
- ASSERT_EQ(0, sigalrm_handler_call_count);
- // ... until sigpause(SIGALRM) temporarily unblocks it.
- ASSERT_EQ(-1, sigpause(SIGALRM));
+ // ... preventing our SIGALRM/SIGRTMIN handler from running ...
+ raise(sig);
+ ASSERT_EQ(0, signal_handler_call_count);
+ // ... until sigpause(SIGALRM/SIGRTMIN) temporarily unblocks it.
+ ASSERT_EQ(-1, sigpause(sig));
ASSERT_EQ(EINTR, errno);
- ASSERT_EQ(1, sigalrm_handler_call_count);
+ ASSERT_EQ(1, signal_handler_call_count);
- // But sigpause(SIGALRM) shouldn't permanently unblock SIGALRM.
- ASSERT_EQ(0, sigprocmask(SIG_SETMASK, 0, &set));
- EXPECT_TRUE(sigismember(&set, SIGALRM));
+ if (sig >= SIGRTMIN && sizeof(void*) == 8) {
+ // But sigpause(SIGALRM/SIGRTMIN) shouldn't permanently unblock SIGALRM/SIGRTMIN.
+ ASSERT_EQ(0, sigprocmask(SIG_SETMASK, 0, &set));
+ EXPECT_TRUE(sigismember(&set, sig));
- ASSERT_EQ(0, sigrelse(SIGALRM));
- ASSERT_EQ(0, sigprocmask(SIG_SETMASK, 0, &set));
- EXPECT_FALSE(sigismember(&set, SIGALRM));
+ // Whereas sigrelse(SIGALRM/SIGRTMIN) should.
+ ASSERT_EQ(0, sigrelse(sig));
+ ASSERT_EQ(0, sigprocmask(SIG_SETMASK, 0, &set));
+ EXPECT_FALSE(sigismember(&set, sig));
+ } else {
+ // sigismember won't work for SIGRTMIN on LP32.
+ }
+}
+
+TEST(signal, sighold_sigpause_sigrelse) {
+ TestSigholdSigpauseSigrelse(SIGALRM);
+}
+
+TEST(signal, sighold_sigpause_sigrelse_RT) {
+ TestSigholdSigpauseSigrelse(SIGRTMIN);
}
TEST(signal, sigset_EINVAL) {
@@ -499,23 +511,48 @@
ASSERT_EQ(EINVAL, errno);
}
-TEST(signal, sigset) {
- auto sigalrm_handler = [](int) { };
- ScopedSignalHandler sigalrm{SIGALRM, sigalrm_handler};
- ScopedSignalMask mask;
+TEST(signal, sigset_RT) {
+ static int signal_handler_call_count = 0;
+ auto signal_handler = [](int) { signal_handler_call_count++; };
+ ScopedSignalHandler ssh{SIGRTMIN, signal_handler};
+ SignalMaskRestorer mask_restorer;
- // block SIGALRM so the next sigset(SIGARLM) call will return SIG_HOLD
- sigset_t sigalrm_set;
- sigemptyset(&sigalrm_set);
- sigaddset(&sigalrm_set, SIGALRM);
- ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &sigalrm_set, nullptr));
-
+ ASSERT_EQ(signal_handler, sigset(SIGRTMIN, SIG_HOLD));
+#if defined(__LP64__)
sigset_t set;
- ASSERT_EQ(SIG_HOLD, sigset(SIGALRM, sigalrm_handler));
+ ASSERT_EQ(0, sigprocmask(SIG_BLOCK, nullptr, &set));
+ ASSERT_TRUE(sigismember(&set, SIGRTMIN));
+#endif
+
+ ASSERT_EQ(SIG_HOLD, sigset(SIGRTMIN, signal_handler));
+ ASSERT_EQ(signal_handler, sigset(SIGRTMIN, signal_handler));
+ ASSERT_EQ(0, signal_handler_call_count);
+ raise(SIGRTMIN);
+ ASSERT_EQ(1, signal_handler_call_count);
+}
+
+TEST(signal, sigset) {
+ static int signal_handler_call_count = 0;
+ auto signal_handler = [](int) { signal_handler_call_count++; };
+ ScopedSignalHandler ssh{SIGALRM, signal_handler};
+ SignalMaskRestorer mask_restorer;
+
+ ASSERT_EQ(0, signal_handler_call_count);
+ raise(SIGALRM);
+ ASSERT_EQ(1, signal_handler_call_count);
+
+ // Block SIGALRM so the next sigset(SIGARLM) call will return SIG_HOLD.
+ sigset_t set;
+ sigemptyset(&set);
+ sigaddset(&set, SIGALRM);
+ ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &set, nullptr));
+
+ sigemptyset(&set);
+ ASSERT_EQ(SIG_HOLD, sigset(SIGALRM, signal_handler));
ASSERT_EQ(0, sigprocmask(SIG_BLOCK, nullptr, &set));
EXPECT_FALSE(sigismember(&set, SIGALRM));
- ASSERT_EQ(sigalrm_handler, sigset(SIGALRM, SIG_IGN));
+ ASSERT_EQ(signal_handler, sigset(SIGALRM, SIG_IGN));
ASSERT_EQ(0, sigprocmask(SIG_BLOCK, nullptr, &set));
EXPECT_FALSE(sigismember(&set, SIGALRM));
diff --git a/tests/spawn_test.cpp b/tests/spawn_test.cpp
index d2e4ea1..dfce0dc 100644
--- a/tests/spawn_test.cpp
+++ b/tests/spawn_test.cpp
@@ -376,6 +376,7 @@
sigset_t just_SIGALRM;
sigemptyset(&just_SIGALRM);
sigaddset(&just_SIGALRM, SIGALRM);
+
ASSERT_EQ(0, posix_spawnattr_setsigdefault(&sa, &just_SIGALRM));
ASSERT_EQ(0, posix_spawnattr_setflags(&sa, POSIX_SPAWN_SETSIGDEF));
@@ -393,15 +394,18 @@
// child without first defaulting any caught signals (http://b/68707996).
static pid_t parent = getpid();
+ setpgid(0, 0);
+
pid_t pid = fork();
ASSERT_NE(-1, pid);
if (pid == 0) {
+ signal(SIGRTMIN, SIG_IGN);
for (size_t i = 0; i < 1024; ++i) {
- kill(0, SIGWINCH);
+ kill(0, SIGRTMIN);
usleep(10);
}
- return;
+ _exit(99);
}
// We test both with and without attributes, because they used to be
@@ -417,11 +421,15 @@
posix_spawnattr_t* attrs[] = { nullptr, &attr1, &attr2 };
- ScopedSignalHandler ssh(SIGWINCH, [](int) { ASSERT_EQ(getpid(), parent); });
+ // We use a real-time signal because that's a tricky case for LP32
+ // because our sigset_t was too small.
+ ScopedSignalHandler ssh(SIGRTMIN, [](int) { ASSERT_EQ(getpid(), parent); });
ExecTestHelper eth;
eth.SetArgs({"true", nullptr});
for (size_t i = 0; i < 128; ++i) {
posix_spawn(nullptr, "true", nullptr, attrs[i % 3], eth.GetArgs(), nullptr);
}
+
+ AssertChildExited(pid, 99);
}