Merge "Document the set*id functions."
diff --git a/libc/Android.bp b/libc/Android.bp
index 61d00cd..fe65ace 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -1456,6 +1456,7 @@
"bionic/pthread_mutex.cpp",
"bionic/pthread_once.cpp",
"bionic/pthread_rwlock.cpp",
+ "bionic/pthread_sigqueue.cpp",
"bionic/pthread_self.cpp",
"bionic/pthread_setname_np.cpp",
"bionic/pthread_setschedparam.cpp",
diff --git a/libc/bionic/fdsan.cpp b/libc/bionic/fdsan.cpp
index 0f17184..ad1ddee 100644
--- a/libc/bionic/fdsan.cpp
+++ b/libc/bionic/fdsan.cpp
@@ -176,12 +176,20 @@
return;
}
+ struct {
+ size_t size;
+ char buf[512];
+ } abort_message;
+
va_list va;
va_start(va, fmt);
if (error_level == ANDROID_FDSAN_ERROR_LEVEL_FATAL) {
async_safe_fatal_va_list("fdsan", fmt, va);
} else {
async_safe_format_log_va_list(ANDROID_LOG_ERROR, "fdsan", fmt, va);
+ size_t len =
+ async_safe_format_buffer_va_list(abort_message.buf, sizeof(abort_message.buf), fmt, va);
+ abort_message.size = len + sizeof(size_t);
}
va_end(va);
@@ -192,7 +200,9 @@
__BIONIC_FALLTHROUGH;
case ANDROID_FDSAN_ERROR_LEVEL_WARN_ALWAYS:
// DEBUGGER_SIGNAL
- raise(__SIGRTMIN + 3);
+ sigval abort_msg;
+ abort_msg.sival_ptr = &abort_message;
+ pthread_sigqueue(pthread_self(), __SIGRTMIN + 3, abort_msg);
break;
case ANDROID_FDSAN_ERROR_LEVEL_FATAL:
@@ -218,7 +228,7 @@
return result;
}
-static const char* __tag_to_type(uint64_t tag) {
+const char* android_fdsan_get_tag_type(uint64_t tag) {
uint64_t type = tag >> 56;
switch (type) {
case ANDROID_FDSAN_OWNER_TYPE_FILE:
@@ -235,6 +245,8 @@
return "RandomAccessFile";
case ANDROID_FDSAN_OWNER_TYPE_PARCELFILEDESCRIPTOR:
return "ParcelFileDescriptor";
+ case ANDROID_FDSAN_OWNER_TYPE_SQLITE:
+ return "sqlite";
case ANDROID_FDSAN_OWNER_TYPE_GENERIC_00:
default:
@@ -251,7 +263,7 @@
}
}
-static uint64_t __tag_to_owner(uint64_t tag) {
+uint64_t android_fdsan_get_tag_value(uint64_t tag) {
// Lop off the most significant byte and sign extend.
return static_cast<uint64_t>(static_cast<int64_t>(tag << 8) >> 8);
}
@@ -264,10 +276,10 @@
uint64_t tag = expected_tag;
if (!atomic_compare_exchange_strong(&fde->close_tag, &tag, 0)) {
- const char* expected_type = __tag_to_type(expected_tag);
- uint64_t expected_owner = __tag_to_owner(expected_tag);
- const char* actual_type = __tag_to_type(tag);
- uint64_t actual_owner = __tag_to_owner(tag);
+ const char* expected_type = android_fdsan_get_tag_type(expected_tag);
+ uint64_t expected_owner = android_fdsan_get_tag_value(expected_tag);
+ const char* actual_type = android_fdsan_get_tag_type(tag);
+ uint64_t actual_owner = android_fdsan_get_tag_value(tag);
if (expected_tag && tag) {
fdsan_error(
"attempted to close file descriptor %d, "
@@ -297,6 +309,14 @@
return rc;
}
+uint64_t android_fdsan_get_owner_tag(int fd) {
+ FdEntry* fde = GetFdEntry(fd);
+ if (!fde) {
+ return 0;
+ }
+ return fde->close_tag;
+}
+
void android_fdsan_exchange_owner_tag(int fd, uint64_t expected_tag, uint64_t new_tag) {
FdEntry* fde = GetFdEntry(fd);
if (!fde) {
@@ -309,18 +329,18 @@
fdsan_error(
"failed to exchange ownership of file descriptor: fd %d is "
"owned by %s 0x%" PRIx64 ", was expected to be owned by %s 0x%" PRIx64,
- fd, __tag_to_type(tag), __tag_to_owner(tag), __tag_to_type(expected_tag),
- __tag_to_owner(expected_tag));
+ fd, android_fdsan_get_tag_type(tag), android_fdsan_get_tag_value(tag),
+ android_fdsan_get_tag_type(expected_tag), android_fdsan_get_tag_value(expected_tag));
} else if (expected_tag && !tag) {
fdsan_error(
"failed to exchange ownership of file descriptor: fd %d is "
"unowned, was expected to be owned by %s 0x%" PRIx64,
- fd, __tag_to_type(expected_tag), __tag_to_owner(expected_tag));
+ fd, android_fdsan_get_tag_type(expected_tag), android_fdsan_get_tag_value(expected_tag));
} else if (!expected_tag && tag) {
fdsan_error(
"failed to exchange ownership of file descriptor: fd %d is "
"owned by %s 0x%" PRIx64 ", was expected to be unowned",
- fd, __tag_to_type(tag), __tag_to_owner(tag));
+ fd, android_fdsan_get_tag_type(tag), android_fdsan_get_tag_value(tag));
} else if (!expected_tag && !tag) {
// This should never happen: our CAS failed, but expected == actual?
async_safe_fatal(
diff --git a/libc/bionic/pthread_sigqueue.cpp b/libc/bionic/pthread_sigqueue.cpp
new file mode 100644
index 0000000..34bda38
--- /dev/null
+++ b/libc/bionic/pthread_sigqueue.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2018 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 <sys/syscall.h>
+#include <unistd.h>
+
+#include "private/ErrnoRestorer.h"
+#include "pthread_internal.h"
+
+int pthread_sigqueue(pthread_t t, int sig, const union sigval value) {
+ ErrnoRestorer errno_restorer;
+
+ pid_t tid = pthread_gettid_np(t);
+ if (tid == -1) return ESRCH;
+
+ siginfo_t siginfo;
+ siginfo.si_code = SI_QUEUE;
+ siginfo.si_pid = getpid();
+ siginfo.si_uid = getuid();
+ siginfo.si_value = value;
+
+ return syscall(__NR_rt_tgsigqueueinfo, getpid(), tid, sig, &siginfo) ? errno : 0;
+}
diff --git a/libc/include/android/fdsan.h b/libc/include/android/fdsan.h
index 2aa29e3..cbea460 100644
--- a/libc/include/android/fdsan.h
+++ b/libc/include/android/fdsan.h
@@ -97,17 +97,20 @@
/* android::base::unique_fd */
ANDROID_FDSAN_OWNER_TYPE_UNIQUE_FD = 3,
+ /* sqlite-owned file descriptors */
+ ANDROID_FDSAN_OWNER_TYPE_SQLITE = 4,
+
/* java.io.FileInputStream */
- ANDROID_FDSAN_OWNER_TYPE_FILEINPUTSTREAM = 251,
+ ANDROID_FDSAN_OWNER_TYPE_FILEINPUTSTREAM = 5,
/* java.io.FileOutputStream */
- ANDROID_FDSAN_OWNER_TYPE_FILEOUTPUTSTREAM = 252,
+ ANDROID_FDSAN_OWNER_TYPE_FILEOUTPUTSTREAM = 6,
/* java.io.RandomAccessFile */
- ANDROID_FDSAN_OWNER_TYPE_RANDOMACCESSFILE = 253,
+ ANDROID_FDSAN_OWNER_TYPE_RANDOMACCESSFILE = 7,
/* android.os.ParcelFileDescriptor */
- ANDROID_FDSAN_OWNER_TYPE_PARCELFILEDESCRIPTOR = 254,
+ ANDROID_FDSAN_OWNER_TYPE_PARCELFILEDESCRIPTOR = 8,
};
/*
@@ -129,6 +132,25 @@
*/
int android_fdsan_close_with_tag(int fd, uint64_t tag) __INTRODUCED_IN_FUTURE __attribute__((__weak__));
+/*
+ * Get a file descriptor's current owner tag.
+ *
+ * Returns 0 for untagged and invalid file descriptors.
+ */
+uint64_t android_fdsan_get_owner_tag(int fd);
+
+/*
+ * Get an owner tag's string representation.
+ *
+ * The return value points to memory with static lifetime, do not attempt to modify it.
+ */
+const char* android_fdsan_get_tag_type(uint64_t tag);
+
+/*
+ * Get an owner tag's value, with the type masked off.
+ */
+uint64_t android_fdsan_get_tag_value(uint64_t tag);
+
enum android_fdsan_error_level {
// No errors.
ANDROID_FDSAN_ERROR_LEVEL_DISABLED,
diff --git a/libc/include/android/versioning.h b/libc/include/android/versioning.h
index 4e1a185..cab1156 100644
--- a/libc/include/android/versioning.h
+++ b/libc/include/android/versioning.h
@@ -17,15 +17,15 @@
#ifndef ANDROID_VERSIONING_H
#define ANDROID_VERSIONING_H
-#define __INTRODUCED_IN(api_level) __attribute__((annotate("introduced_in=" #api_level)))
+#define __INTRODUCED_IN(api_level) __attribute__((annotate("introduced_in=" __STRING(api_level))))
#define __INTRODUCED_IN_FUTURE __attribute__((annotate("introduced_in_future")))
-#define __DEPRECATED_IN(api_level) __attribute__((annotate("deprecated_in=" #api_level)))
-#define __REMOVED_IN(api_level) __attribute__((annotate("obsoleted_in=" #api_level)))
-#define __INTRODUCED_IN_32(api_level) __attribute__((annotate("introduced_in_32=" #api_level)))
-#define __INTRODUCED_IN_64(api_level) __attribute__((annotate("introduced_in_64=" #api_level)))
-#define __INTRODUCED_IN_ARM(api_level) __attribute__((annotate("introduced_in_arm=" #api_level)))
-#define __INTRODUCED_IN_X86(api_level) __attribute__((annotate("introduced_in_x86=" #api_level)))
-#define __INTRODUCED_IN_MIPS(api_level) __attribute__((annotate("introduced_in_mips=" #api_level)))
+#define __DEPRECATED_IN(api_level) __attribute__((annotate("deprecated_in=" __STRING(api_level))))
+#define __REMOVED_IN(api_level) __attribute__((annotate("obsoleted_in=" __STRING(api_level))))
+#define __INTRODUCED_IN_32(api_level) __attribute__((annotate("introduced_in_32=" __STRING(api_level))))
+#define __INTRODUCED_IN_64(api_level) __attribute__((annotate("introduced_in_64=" __STRING(api_level))))
+#define __INTRODUCED_IN_ARM(api_level) __attribute__((annotate("introduced_in_arm=" __STRING(api_level))))
+#define __INTRODUCED_IN_X86(api_level) __attribute__((annotate("introduced_in_x86=" __STRING(api_level))))
+#define __INTRODUCED_IN_MIPS(api_level) __attribute__((annotate("introduced_in_mips=" __STRING(api_level))))
#define __VERSIONER_NO_GUARD __attribute__((annotate("versioner_no_guard")))
diff --git a/libc/include/poll.h b/libc/include/poll.h
index 13b7385..e3a9039 100644
--- a/libc/include/poll.h
+++ b/libc/include/poll.h
@@ -49,7 +49,7 @@
* Returns the number of ready file descriptors on success, 0 for timeout,
* and returns -1 and sets `errno` on failure.
*/
-int poll(struct pollfd* _Nonnull __fds, nfds_t __count, int __timeout_ms);
+int poll(struct pollfd* _Nullable __fds, nfds_t __count, int __timeout_ms);
/**
* [ppoll(3)](http://man7.org/linux/man-pages/man3/ppoll.3.html) waits on a set of file descriptors
@@ -61,12 +61,12 @@
*
* Available since API level 28.
*/
-int ppoll(struct pollfd* _Nonnull __fds, nfds_t __count, const struct timespec* _Nullable __timeout, const sigset_t* _Nullable __mask) __INTRODUCED_IN(21);
+int ppoll(struct pollfd* _Nullable __fds, nfds_t __count, const struct timespec* _Nullable __timeout, const sigset_t* _Nullable __mask) __INTRODUCED_IN(21);
/**
* Like ppoll() but allows setting a signal mask with RT signals even from a 32-bit process.
*/
-int ppoll64(struct pollfd* _Nonnull __fds, nfds_t __count, const struct timespec* _Nullable __timeout, const sigset64_t* _Nullable __mask) __INTRODUCED_IN(28);
+int ppoll64(struct pollfd* _Nullable __fds, nfds_t __count, const struct timespec* _Nullable __timeout, const sigset64_t* _Nullable __mask) __INTRODUCED_IN(28);
#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
#define _POLL_H_
diff --git a/libc/include/signal.h b/libc/include/signal.h
index 00860d5..9d1030a 100644
--- a/libc/include/signal.h
+++ b/libc/include/signal.h
@@ -113,6 +113,10 @@
void psignal(int __signal, const char* __msg) __INTRODUCED_IN(17);
int pthread_kill(pthread_t __pthread, int __signal);
+#if defined(__USE_GNU)
+int pthread_sigqueue(pthread_t __pthread, int __signal, const union sigval __value) __INTRODUCED_IN(__ANDROID_API_Q__);
+#endif
+
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);
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index 13ad4fe..26a05c8 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -38,7 +38,6 @@
#define _SYS_CDEFS_H_
#include <android/api-level.h>
-#include <android/versioning.h>
#define __BIONIC__ 1
@@ -92,7 +91,6 @@
#define ___STRING(x) __STRING(x)
#define ___CONCAT(x,y) __CONCAT(x,y)
-#if defined(__STDC__) || defined(__cplusplus)
#define __P(protos) protos /* full-blown ANSI C */
#define __CONCAT1(x,y) x ## y
#define __CONCAT(x,y) __CONCAT1(x,y)
@@ -102,12 +100,9 @@
#define __inline inline /* convert to C++ keyword */
#endif /* !__cplusplus */
-#else /* !(__STDC__ || __cplusplus) */
-#define __P(protos) () /* traditional C preprocessor */
-#define __CONCAT(x,y) x/**/y
-#define __STRING(x) "x"
+#include <android/versioning.h>
-#endif /* !(__STDC__ || __cplusplus) */
+#include <android/versioning.h>
#define __always_inline __attribute__((__always_inline__))
#define __attribute_const__ __attribute__((__const__))
diff --git a/libc/include/sys/socket.h b/libc/include/sys/socket.h
index bbde88b..e54dd65 100644
--- a/libc/include/sys/socket.h
+++ b/libc/include/sys/socket.h
@@ -288,6 +288,7 @@
#define SOL_ALG 279
#define SOL_NFC 280
#define SOL_KCM 281
+#define SOL_TLS 282
#define IPX_TYPE 1
diff --git a/libc/libc.arm.map b/libc/libc.arm.map
index 6d39812..8fb07f7 100644
--- a/libc/libc.arm.map
+++ b/libc/libc.arm.map
@@ -1426,8 +1426,12 @@
android_fdsan_close_with_tag;
android_fdsan_create_owner_tag;
android_fdsan_exchange_owner_tag;
+ android_fdsan_get_owner_tag;
+ android_fdsan_get_tag_type;
+ android_fdsan_get_tag_value;
android_fdsan_get_error_level;
android_fdsan_set_error_level;
+ pthread_sigqueue;
timespec_get;
} LIBC_P;
diff --git a/libc/libc.arm64.map b/libc/libc.arm64.map
index 1cf48b1..8c5eb89 100644
--- a/libc/libc.arm64.map
+++ b/libc/libc.arm64.map
@@ -1347,8 +1347,12 @@
android_fdsan_close_with_tag;
android_fdsan_create_owner_tag;
android_fdsan_exchange_owner_tag;
+ android_fdsan_get_owner_tag;
+ android_fdsan_get_tag_type;
+ android_fdsan_get_tag_value;
android_fdsan_get_error_level;
android_fdsan_set_error_level;
+ pthread_sigqueue;
timespec_get;
} LIBC_P;
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index 135206e..c5f0910 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -1451,8 +1451,12 @@
android_fdsan_close_with_tag;
android_fdsan_create_owner_tag;
android_fdsan_exchange_owner_tag;
+ android_fdsan_get_owner_tag;
+ android_fdsan_get_tag_type;
+ android_fdsan_get_tag_value;
android_fdsan_get_error_level;
android_fdsan_set_error_level;
+ pthread_sigqueue;
timespec_get;
} LIBC_P;
diff --git a/libc/libc.mips.map b/libc/libc.mips.map
index a330a45..fbaf508 100644
--- a/libc/libc.mips.map
+++ b/libc/libc.mips.map
@@ -1410,8 +1410,12 @@
android_fdsan_close_with_tag;
android_fdsan_create_owner_tag;
android_fdsan_exchange_owner_tag;
+ android_fdsan_get_owner_tag;
+ android_fdsan_get_tag_type;
+ android_fdsan_get_tag_value;
android_fdsan_get_error_level;
android_fdsan_set_error_level;
+ pthread_sigqueue;
timespec_get;
} LIBC_P;
diff --git a/libc/libc.mips64.map b/libc/libc.mips64.map
index 1cf48b1..8c5eb89 100644
--- a/libc/libc.mips64.map
+++ b/libc/libc.mips64.map
@@ -1347,8 +1347,12 @@
android_fdsan_close_with_tag;
android_fdsan_create_owner_tag;
android_fdsan_exchange_owner_tag;
+ android_fdsan_get_owner_tag;
+ android_fdsan_get_tag_type;
+ android_fdsan_get_tag_value;
android_fdsan_get_error_level;
android_fdsan_set_error_level;
+ pthread_sigqueue;
timespec_get;
} LIBC_P;
diff --git a/libc/libc.x86.map b/libc/libc.x86.map
index 7a2fe9a..db86e55 100644
--- a/libc/libc.x86.map
+++ b/libc/libc.x86.map
@@ -1408,8 +1408,12 @@
android_fdsan_close_with_tag;
android_fdsan_create_owner_tag;
android_fdsan_exchange_owner_tag;
+ android_fdsan_get_owner_tag;
+ android_fdsan_get_tag_type;
+ android_fdsan_get_tag_value;
android_fdsan_get_error_level;
android_fdsan_set_error_level;
+ pthread_sigqueue;
timespec_get;
} LIBC_P;
diff --git a/libc/libc.x86_64.map b/libc/libc.x86_64.map
index 1cf48b1..8c5eb89 100644
--- a/libc/libc.x86_64.map
+++ b/libc/libc.x86_64.map
@@ -1347,8 +1347,12 @@
android_fdsan_close_with_tag;
android_fdsan_create_owner_tag;
android_fdsan_exchange_owner_tag;
+ android_fdsan_get_owner_tag;
+ android_fdsan_get_tag_type;
+ android_fdsan_get_tag_value;
android_fdsan_get_error_level;
android_fdsan_set_error_level;
+ pthread_sigqueue;
timespec_get;
} LIBC_P;
diff --git a/tests/signal_test.cpp b/tests/signal_test.cpp
index cc95ef7..52a097b 100644
--- a/tests/signal_test.cpp
+++ b/tests/signal_test.cpp
@@ -597,6 +597,42 @@
ASSERT_EQ(1, g_sigqueue_signal_handler_call_count);
}
+TEST(signal, pthread_sigqueue_self) {
+ ScopedSignalHandler ssh(SIGALRM, SigqueueSignalHandler, SA_SIGINFO);
+ sigval_t sigval;
+ sigval.sival_int = 1;
+ errno = 0;
+ ASSERT_EQ(0, pthread_sigqueue(pthread_self(), SIGALRM, sigval));
+ ASSERT_EQ(0, errno);
+ ASSERT_EQ(1, g_sigqueue_signal_handler_call_count);
+}
+
+TEST(signal, pthread_sigqueue_other) {
+ ScopedSignalHandler ssh(SIGALRM, SigqueueSignalHandler, SA_SIGINFO);
+ sigval_t sigval;
+ sigval.sival_int = 1;
+
+ sigset_t mask;
+ sigfillset(&mask);
+ pthread_sigmask(SIG_SETMASK, &mask, nullptr);
+ pthread_t thread;
+ int rc = pthread_create(&thread, nullptr,
+ [](void*) -> void* {
+ sigset_t mask;
+ sigemptyset(&mask);
+ sigsuspend(&mask);
+ return nullptr;
+ },
+ nullptr);
+ ASSERT_EQ(0, rc);
+
+ errno = 0;
+ ASSERT_EQ(0, pthread_sigqueue(thread, SIGALRM, sigval));
+ ASSERT_EQ(0, errno);
+ pthread_join(thread, nullptr);
+ ASSERT_EQ(1, g_sigqueue_signal_handler_call_count);
+}
+
TEST(signal, sigwaitinfo) {
SignalMaskRestorer smr;