Make sigaction consistent about SA_RESTORER and sa_restorer
Bug: http://b/72493232
Test: bionic-unit-tests --gtest_filter=*signal.sigaction*
Change-Id: Ia9fceb478498d09c8f2f6222d6a81725e1f6eb23
diff --git a/libc/bionic/sigaction.cpp b/libc/bionic/sigaction.cpp
index e5a7d5f..53b2a02 100644
--- a/libc/bionic/sigaction.cpp
+++ b/libc/bionic/sigaction.cpp
@@ -81,7 +81,6 @@
#else
extern "C" int __rt_sigaction(int, const struct sigaction64*, struct sigaction64*, size_t);
-extern "C" int __sigaction(int, const struct sigaction*, struct sigaction*);
int sigaction(int signal, const struct sigaction* bionic_new, struct sigaction* bionic_old) {
// The 32-bit ABI is broken. struct sigaction includes a too-small sigset_t,
@@ -91,6 +90,7 @@
kernel_new = {};
kernel_new.sa_flags = bionic_new->sa_flags;
kernel_new.sa_handler = bionic_new->sa_handler;
+ kernel_new.sa_restorer = bionic_new->sa_restorer;
memcpy(&kernel_new.sa_mask, &bionic_new->sa_mask, sizeof(bionic_new->sa_mask));
}
@@ -100,6 +100,7 @@
*bionic_old = {};
bionic_old->sa_flags = kernel_old.sa_flags;
bionic_old->sa_handler = kernel_old.sa_handler;
+ bionic_old->sa_restorer = kernel_old.sa_restorer;
memcpy(&bionic_old->sa_mask, &kernel_old.sa_mask, sizeof(bionic_old->sa_mask));
}
return result;
diff --git a/tests/signal_test.cpp b/tests/signal_test.cpp
index 87a918f..2b414e5 100644
--- a/tests/signal_test.cpp
+++ b/tests/signal_test.cpp
@@ -285,6 +285,7 @@
ASSERT_TRUE(original_sa.sa_handler == NULL);
ASSERT_TRUE(original_sa.sa_sigaction == NULL);
ASSERT_EQ(0U, original_sa.sa_flags & ~sa_restorer);
+ ASSERT_EQ(bool(original_sa.sa_flags & sa_restorer), bool(original_sa.sa_restorer));
// Set a traditional sa_handler signal handler.
auto no_op_signal_handler = [](int) {};
@@ -300,6 +301,7 @@
ASSERT_TRUE(sa.sa_handler == no_op_signal_handler);
ASSERT_TRUE((void*) sa.sa_sigaction == (void*) sa.sa_handler);
ASSERT_EQ(static_cast<unsigned>(SA_ONSTACK), sa.sa_flags & ~sa_restorer);
+ ASSERT_EQ(bool(sa.sa_flags & sa_restorer), bool(sa.sa_restorer));
// Set a new-style sa_sigaction signal handler.
auto no_op_sigaction = [](int, siginfo_t*, void*) {};
@@ -315,6 +317,7 @@
ASSERT_TRUE(sa.sa_sigaction == no_op_sigaction);
ASSERT_TRUE((void*) sa.sa_sigaction == (void*) sa.sa_handler);
ASSERT_EQ(static_cast<unsigned>(SA_ONSTACK | SA_SIGINFO), sa.sa_flags & ~sa_restorer);
+ ASSERT_EQ(bool(sa.sa_flags & sa_restorer), bool(sa.sa_restorer));
// Put everything back how it was.
ASSERT_EQ(0, sigaction_fn(sig, &original_sa, NULL));