aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Gao <jmgao@google.com>2018-08-27 16:00:58 -0700
committerJosh Gao <jmgao@google.com>2018-08-27 16:48:17 -0700
commit726b63f725ccfb270bf780c96bdf104a26e72dad (patch)
tree0b6e0e688d10a1dfdd109f036f73198ec87414ac
parentf3aa3007e34eb14e114bd86492d8e6b2673e83c6 (diff)
downloadandroid_bionic-726b63f725ccfb270bf780c96bdf104a26e72dad.tar.gz
android_bionic-726b63f725ccfb270bf780c96bdf104a26e72dad.tar.bz2
android_bionic-726b63f725ccfb270bf780c96bdf104a26e72dad.zip
Implement pthread_sigqueue.
Bug: http://b/112770187 Test: bionic-unit-tests Change-Id: I03382cd5df2490b2e87265dba9007e2cb1b14cd2
-rw-r--r--libc/Android.bp1
-rw-r--r--libc/bionic/pthread_sigqueue.cpp51
-rw-r--r--libc/include/signal.h4
-rw-r--r--libc/libc.arm.map1
-rw-r--r--libc/libc.arm64.map1
-rw-r--r--libc/libc.map.txt1
-rw-r--r--libc/libc.mips.map1
-rw-r--r--libc/libc.mips64.map1
-rw-r--r--libc/libc.x86.map1
-rw-r--r--libc/libc.x86_64.map1
-rw-r--r--tests/signal_test.cpp36
11 files changed, 99 insertions, 0 deletions
diff --git a/libc/Android.bp b/libc/Android.bp
index 61d00cd09..fe65acefa 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -1456,6 +1456,7 @@ cc_library_static {
"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/pthread_sigqueue.cpp b/libc/bionic/pthread_sigqueue.cpp
new file mode 100644
index 000000000..34bda38c4
--- /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/signal.h b/libc/include/signal.h
index 00860d5e6..9d1030ac2 100644
--- a/libc/include/signal.h
+++ b/libc/include/signal.h
@@ -113,6 +113,10 @@ void psiginfo(const siginfo_t* __info, const char* __msg) __INTRODUCED_IN(17);
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/libc.arm.map b/libc/libc.arm.map
index f1eec3c6a..8fb07f784 100644
--- a/libc/libc.arm.map
+++ b/libc/libc.arm.map
@@ -1431,6 +1431,7 @@ LIBC_Q { # introduced=Q
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 4d538cd64..8c5eb89d4 100644
--- a/libc/libc.arm64.map
+++ b/libc/libc.arm64.map
@@ -1352,6 +1352,7 @@ LIBC_Q { # introduced=Q
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 0f5abc0b9..c5f091076 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -1456,6 +1456,7 @@ LIBC_Q { # introduced=Q
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 f14f73173..fbaf508f6 100644
--- a/libc/libc.mips.map
+++ b/libc/libc.mips.map
@@ -1415,6 +1415,7 @@ LIBC_Q { # introduced=Q
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 4d538cd64..8c5eb89d4 100644
--- a/libc/libc.mips64.map
+++ b/libc/libc.mips64.map
@@ -1352,6 +1352,7 @@ LIBC_Q { # introduced=Q
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 d44001e68..db86e5511 100644
--- a/libc/libc.x86.map
+++ b/libc/libc.x86.map
@@ -1413,6 +1413,7 @@ LIBC_Q { # introduced=Q
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 4d538cd64..8c5eb89d4 100644
--- a/libc/libc.x86_64.map
+++ b/libc/libc.x86_64.map
@@ -1352,6 +1352,7 @@ LIBC_Q { # introduced=Q
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 cc95ef7b3..52a097bf3 100644
--- a/tests/signal_test.cpp
+++ b/tests/signal_test.cpp
@@ -597,6 +597,42 @@ TEST(signal, sigqueue) {
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;