Add `struct sigaction64` and `sigaction64`.
Bug: http://b/72493232
Test: ran tests
Change-Id: I47b0560a30aa33a9b1f1978dfb7f84d2e3d389b8
diff --git a/docs/32-bit-abi.md b/docs/32-bit-abi.md
index 21f9b71..0ea94d4 100644
--- a/docs/32-bit-abi.md
+++ b/docs/32-bit-abi.md
@@ -59,6 +59,9 @@
In the 64-bit ABI, `off_t` is always 64-bit.
+For source compatibility, the names containing `64` are also available
+in the 64-bit ABI even though they're identical to the non-`64` names.
+
## `sigset_t` is too small for real-time signals
@@ -68,8 +71,15 @@
for every function that takes a `sigset_t` (so `sigprocmask64` takes a
`sigset64_t` where `sigprocmask` takes a `sigset_t`).
+On 32-bit Android, `struct sigaction` is also too small because it contains
+a `sigset_t`. We also offer a `struct sigaction64` and `sigaction64` function
+to work around this.
+
In the 64-bit ABI, `sigset_t` is the correct size for every architecture.
+For source compatibility, the names containing `64` are also available
+in the 64-bit ABI even though they're identical to the non-`64` names.
+
## `time_t` is 32-bit
diff --git a/docs/status.md b/docs/status.md
index 8cef5b7..2666e58 100644
--- a/docs/status.md
+++ b/docs/status.md
@@ -49,11 +49,12 @@
* `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)
+ * <signal.h> support for `sigaction64_t` and `sigset64_t` allowing LP32 access to real-time signals
* <spawn.h>
* `swab`
* `syncfs`
- * `%C` and `%S` support in the printf family (previously only the wprintf family supported these).
- * `%mc`/`%ms`/`%m[` support in the scanf family.
+ * `%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/bionic/abort.cpp b/libc/bionic/abort.cpp
index ec26a50..d2c99a5 100644
--- a/libc/bionic/abort.cpp
+++ b/libc/bionic/abort.cpp
@@ -67,13 +67,10 @@
sigprocmask64(SIG_SETMASK, &mask, nullptr);
inline_tgkill(pid, tid, SIGABRT);
- // If SIGABRT ignored, or caught and the handler returns,
+ // If SIGABRT is ignored or it's caught and the handler returns,
// remove the SIGABRT signal handler and raise SIGABRT again.
- struct sigaction sa;
- sa.sa_handler = SIG_DFL;
- sa.sa_flags = SA_RESTART;
- sigemptyset(&sa.sa_mask);
- sigaction(SIGABRT, &sa, &sa);
+ struct sigaction64 sa = { .sa_handler = SIG_DFL, .sa_flags = SA_RESTART };
+ sigaction64(SIGABRT, &sa, nullptr);
sigprocmask64(SIG_SETMASK, &mask, nullptr);
inline_tgkill(pid, tid, SIGABRT);
diff --git a/libc/bionic/sigaction.cpp b/libc/bionic/sigaction.cpp
index 0633748..e5a7d5f 100644
--- a/libc/bionic/sigaction.cpp
+++ b/libc/bionic/sigaction.cpp
@@ -27,6 +27,7 @@
*/
#include <signal.h>
+#include <string.h>
extern "C" void __restore_rt(void);
extern "C" void __restore(void);
@@ -75,28 +76,49 @@
return result;
}
+__strong_alias(sigaction64, sigaction);
+
#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_action, struct sigaction* bionic_old_action) {
+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,
- // so we have to use sigaction(2) rather than rt_sigaction(2).
- struct sigaction kernel_new_action;
- if (bionic_new_action != NULL) {
- kernel_new_action.sa_flags = bionic_new_action->sa_flags;
- kernel_new_action.sa_handler = bionic_new_action->sa_handler;
- kernel_new_action.sa_mask = bionic_new_action->sa_mask;
-#if defined(SA_RESTORER)
- kernel_new_action.sa_restorer = bionic_new_action->sa_restorer;
-
- if (!(kernel_new_action.sa_flags & SA_RESTORER)) {
- kernel_new_action.sa_flags |= SA_RESTORER;
- kernel_new_action.sa_restorer = (kernel_new_action.sa_flags & SA_SIGINFO) ? &__restore_rt : &__restore;
- }
-#endif
+ // so we have to translate to struct sigaction64 first.
+ struct sigaction64 kernel_new;
+ if (bionic_new) {
+ kernel_new = {};
+ kernel_new.sa_flags = bionic_new->sa_flags;
+ kernel_new.sa_handler = bionic_new->sa_handler;
+ memcpy(&kernel_new.sa_mask, &bionic_new->sa_mask, sizeof(bionic_new->sa_mask));
}
- return __sigaction(signal, (bionic_new_action != NULL) ? &kernel_new_action : NULL, bionic_old_action);
+
+ struct sigaction64 kernel_old;
+ int result = sigaction64(signal, bionic_new ? &kernel_new : nullptr, &kernel_old);
+ if (bionic_old) {
+ *bionic_old = {};
+ bionic_old->sa_flags = kernel_old.sa_flags;
+ bionic_old->sa_handler = kernel_old.sa_handler;
+ memcpy(&bionic_old->sa_mask, &kernel_old.sa_mask, sizeof(bionic_old->sa_mask));
+ }
+ return result;
+}
+
+int sigaction64(int signal, const struct sigaction64* bionic_new, struct sigaction64* bionic_old) {
+ struct sigaction64 kernel_new;
+ if (bionic_new) {
+ kernel_new = *bionic_new;
+ if (!(kernel_new.sa_flags & SA_RESTORER)) {
+ kernel_new.sa_flags |= SA_RESTORER;
+ kernel_new.sa_restorer = (kernel_new.sa_flags & SA_SIGINFO) ? &__restore_rt : &__restore;
+ }
+ }
+
+ return __rt_sigaction(signal,
+ bionic_new ? &kernel_new : nullptr,
+ bionic_old,
+ sizeof(kernel_new.sa_mask));
}
#endif
diff --git a/libc/bionic/signal.cpp b/libc/bionic/signal.cpp
index 099944a..fbfe0ce 100644
--- a/libc/bionic/signal.cpp
+++ b/libc/bionic/signal.cpp
@@ -147,22 +147,19 @@
}
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);
+ struct sigaction64 sa = { .sa_handler = SIG_IGN };
+ return sigaction64(sig, &sa, nullptr);
}
int siginterrupt(int sig, int flag) {
- struct sigaction act;
- sigaction(sig, nullptr, &act);
+ struct sigaction64 act;
+ sigaction64(sig, nullptr, &act);
if (flag) {
act.sa_flags &= ~SA_RESTART;
} else {
act.sa_flags |= SA_RESTART;
}
- return sigaction(sig, &act, nullptr);
+ return sigaction64(sig, &act, nullptr);
}
template <typename SigSetT>
@@ -185,16 +182,8 @@
}
__LIBC_HIDDEN__ sighandler_t _signal(int sig, sighandler_t handler, int flags) {
- struct sigaction sa;
- sigemptyset(&sa.sa_mask);
- sa.sa_handler = handler;
- sa.sa_flags = flags;
-
- if (sigaction(sig, &sa, &sa) == -1) {
- return SIG_ERR;
- }
-
- return sa.sa_handler;
+ struct sigaction64 sa = { .sa_handler = handler, .sa_flags = flags };
+ return (sigaction64(sig, &sa, &sa) == -1) ? SIG_ERR : sa.sa_handler;
}
sighandler_t signal(int sig, sighandler_t handler) {
@@ -262,15 +251,11 @@
}
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 sigaction64 new_sa;
+ if (disp != SIG_HOLD) new_sa = { .sa_handler = disp };
- struct sigaction old_sa;
- if (sigaction(sig, (disp == SIG_HOLD) ? nullptr : &new_sa, &old_sa) == -1) {
+ struct sigaction64 old_sa;
+ if (sigaction64(sig, (disp == SIG_HOLD) ? nullptr : &new_sa, &old_sa) == -1) {
return SIG_ERR;
}
diff --git a/libc/bionic/spawn.cpp b/libc/bionic/spawn.cpp
index 7422a0b..fde102c 100644
--- a/libc/bionic/spawn.cpp
+++ b/libc/bionic/spawn.cpp
@@ -98,17 +98,17 @@
// POSIX: "Signals set to be caught by the calling process shall be
// set to the default action in the child process."
bool use_sigdefault = ((flags & POSIX_SPAWN_SETSIGDEF) != 0);
- const struct sigaction default_sa = { .sa_handler = SIG_DFL };
+ const struct sigaction64 default_sa = { .sa_handler = SIG_DFL };
for (int s = 1; s < _NSIG; ++s) {
bool reset = false;
if (use_sigdefault && sigismember64(&(*attr)->sigdefault.sigset64, s)) {
reset = true;
} else {
- struct sigaction current;
- if (sigaction(s, nullptr, ¤t) == -1) _exit(127);
+ struct sigaction64 current;
+ if (sigaction64(s, nullptr, ¤t) == -1) _exit(127);
reset = (current.sa_handler != SIG_IGN && current.sa_handler != SIG_DFL);
}
- if (reset && sigaction(s, &default_sa, nullptr) == -1) _exit(127);
+ if (reset && sigaction64(s, &default_sa, nullptr) == -1) _exit(127);
}
if ((flags & POSIX_SPAWN_SETPGROUP) != 0 && setpgid(0, (*attr)->pgroup) == -1) _exit(127);
diff --git a/libc/include/signal.h b/libc/include/signal.h
index 61bb395..2027d70 100644
--- a/libc/include/signal.h
+++ b/libc/include/signal.h
@@ -40,7 +40,8 @@
/* For 64-bit (and mips), the kernel's struct sigaction doesn't match the
* POSIX one, so we need to expose our own and translate behind the scenes.
* For 32-bit, we're stuck with the definitions we already shipped,
- * even though they contain a sigset_t that's too small. */
+ * even though they contain a sigset_t that's too small. See sigaction64.
+ */
#define sigaction __kernel_sigaction
#include <linux/signal.h>
#undef sigaction
@@ -89,43 +90,65 @@
#if defined(__LP64__)
+#define __SIGACTION_BODY \
+ int sa_flags; \
+ union { \
+ sighandler_t sa_handler; \
+ void (*sa_sigaction)(int, struct siginfo*, void*); \
+ }; \
+ sigset_t sa_mask; \
+ void (*sa_restorer)(void); \
+
+struct sigaction { __SIGACTION_BODY };
+struct sigaction64 { __SIGACTION_BODY };
+
+#undef __SIGACTION_BODY
+
+#elif defined(__mips__)
+
+#define __SIGACTION_BODY \
+ int sa_flags; \
+ union { \
+ sighandler_t sa_handler; \
+ void (*sa_sigaction)(int, struct siginfo*, void*); \
+ }; \
+ sigset_t sa_mask; \
+
+struct sigaction { __SIGACTION_BODY };
+struct sigaction64 { __SIGACTION_BODY };
+
+#undef __SIGACTION_BODY
+
+#else
+
+#undef sa_handler
+#undef sa_sigaction
+
struct sigaction {
- int sa_flags;
union {
sighandler_t sa_handler;
void (*sa_sigaction)(int, struct siginfo*, void*);
};
sigset_t sa_mask;
+ int sa_flags;
void (*sa_restorer)(void);
};
-#elif defined(__mips__)
-
-struct sigaction {
- int sa_flags;
+/* This matches the kernel's internal structure. */
+struct sigaction64 {
union {
sighandler_t sa_handler;
- void (*sa_sigaction) (int, struct siginfo*, void*);
+ void (*sa_sigaction)(int, struct siginfo*, void*);
};
- sigset_t sa_mask;
-};
-
-#else
-
-struct sigaction {
- union {
- sighandler_t _sa_handler;
- void (*_sa_sigaction)(int, struct siginfo*, void*);
- } _u;
- sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void);
+ sigset64_t sa_mask;
};
#endif
-// TODO: sigaction contains a sigset_t that's too small on LP32.
int sigaction(int __signal, const struct sigaction* __new_action, struct sigaction* __old_action);
+int sigaction64(int __signal, const struct sigaction64* __new_action, struct sigaction64* __old_action) __INTRODUCED_IN(28);
int siginterrupt(int __signal, int __flag);
@@ -191,4 +214,4 @@
#include <android/legacy_signal_inlines.h>
-#endif /* _SIGNAL_H_ */
+#endif
diff --git a/libc/libc.arm.map b/libc/libc.arm.map
index c345ba6..839c406 100644
--- a/libc/libc.arm.map
+++ b/libc/libc.arm.map
@@ -1386,6 +1386,7 @@
sethostent;
setnetent;
setprotoent;
+ sigaction64;
sigaddset64;
sigdelset64;
sigemptyset64;
diff --git a/libc/libc.arm64.map b/libc/libc.arm64.map
index 3af0d42..a39a233 100644
--- a/libc/libc.arm64.map
+++ b/libc/libc.arm64.map
@@ -1306,6 +1306,7 @@
sethostent;
setnetent;
setprotoent;
+ sigaction64;
sigaddset64;
sigdelset64;
sigemptyset64;
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index 5c54ba1..b3bfa8a 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -1411,6 +1411,7 @@
sethostent;
setnetent;
setprotoent;
+ sigaction64;
sigaddset64;
sigdelset64;
sigemptyset64;
diff --git a/libc/libc.mips.map b/libc/libc.mips.map
index c364608..2a93132 100644
--- a/libc/libc.mips.map
+++ b/libc/libc.mips.map
@@ -1370,6 +1370,7 @@
sethostent;
setnetent;
setprotoent;
+ sigaction64;
sigaddset64;
sigdelset64;
sigemptyset64;
diff --git a/libc/libc.mips64.map b/libc/libc.mips64.map
index 3af0d42..a39a233 100644
--- a/libc/libc.mips64.map
+++ b/libc/libc.mips64.map
@@ -1306,6 +1306,7 @@
sethostent;
setnetent;
setprotoent;
+ sigaction64;
sigaddset64;
sigdelset64;
sigemptyset64;
diff --git a/libc/libc.x86.map b/libc/libc.x86.map
index eec2c19..d2e7399 100644
--- a/libc/libc.x86.map
+++ b/libc/libc.x86.map
@@ -1368,6 +1368,7 @@
sethostent;
setnetent;
setprotoent;
+ sigaction64;
sigaddset64;
sigdelset64;
sigemptyset64;
diff --git a/libc/libc.x86_64.map b/libc/libc.x86_64.map
index 3af0d42..a39a233 100644
--- a/libc/libc.x86_64.map
+++ b/libc/libc.x86_64.map
@@ -1306,6 +1306,7 @@
sethostent;
setnetent;
setprotoent;
+ sigaction64;
sigaddset64;
sigdelset64;
sigemptyset64;
diff --git a/libc/malloc_debug/BacktraceData.cpp b/libc/malloc_debug/BacktraceData.cpp
index d597280..57d8f2a 100644
--- a/libc/malloc_debug/BacktraceData.cpp
+++ b/libc/malloc_debug/BacktraceData.cpp
@@ -59,13 +59,10 @@
bool BacktraceData::Initialize(const Config& config) {
enabled_ = config.backtrace_enabled();
if (config.backtrace_enable_on_signal()) {
- struct sigaction enable_act;
- memset(&enable_act, 0, sizeof(enable_act));
-
+ struct sigaction64 enable_act = {};
enable_act.sa_sigaction = ToggleBacktraceEnable;
enable_act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
- sigemptyset(&enable_act.sa_mask);
- if (sigaction(config.backtrace_signal(), &enable_act, nullptr) != 0) {
+ if (sigaction64(config.backtrace_signal(), &enable_act, nullptr) != 0) {
error_log("Unable to set up backtrace signal enable function: %s", strerror(errno));
return false;
}
@@ -73,13 +70,10 @@
config.backtrace_signal(), getpid());
}
- struct sigaction act;
- memset(&act, 0, sizeof(act));
-
+ struct sigaction64 act = {};
act.sa_sigaction = EnableDump;
act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
- sigemptyset(&act.sa_mask);
- if (sigaction(config.backtrace_dump_signal(), &act, nullptr) != 0) {
+ if (sigaction64(config.backtrace_dump_signal(), &act, nullptr) != 0) {
error_log("Unable to set up backtrace dump signal function: %s", strerror(errno));
return false;
}
diff --git a/libc/malloc_debug/RecordData.cpp b/libc/malloc_debug/RecordData.cpp
index 5a68deb..55d9943 100644
--- a/libc/malloc_debug/RecordData.cpp
+++ b/libc/malloc_debug/RecordData.cpp
@@ -179,13 +179,10 @@
}
bool RecordData::Initialize(const Config& config) {
- struct sigaction dump_act;
- memset(&dump_act, 0, sizeof(dump_act));
-
+ struct sigaction64 dump_act = {};
dump_act.sa_sigaction = RecordDump;
dump_act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
- sigemptyset(&dump_act.sa_mask);
- if (sigaction(config.record_allocs_signal(), &dump_act, nullptr) != 0) {
+ if (sigaction64(config.record_allocs_signal(), &dump_act, nullptr) != 0) {
error_log("Unable to set up record dump signal function: %s", strerror(errno));
return false;
}
diff --git a/tests/BionicDeathTest.h b/tests/BionicDeathTest.h
index 3e8d7b2..6826ab7 100644
--- a/tests/BionicDeathTest.h
+++ b/tests/BionicDeathTest.h
@@ -21,25 +21,28 @@
#include <gtest/gtest.h>
+#if !defined(__BIONIC__)
+#define sigaction64 sigaction
+#endif
+
class BionicDeathTest : public testing::Test {
protected:
virtual void SetUp() {
// Suppress debuggerd stack traces. Too slow.
for (int signo : { SIGABRT, SIGBUS, SIGSEGV, SIGSYS }) {
- struct sigaction action = {};
- action.sa_handler = SIG_DFL;
- sigaction(signo, &action, &previous_);
+ struct sigaction64 action = { .sa_handler = SIG_DFL };
+ sigaction64(signo, &action, &previous_);
}
}
virtual void TearDown() {
for (int signo : { SIGABRT, SIGBUS, SIGSEGV, SIGSYS }) {
- sigaction(signo, &previous_, nullptr);
+ sigaction64(signo, &previous_, nullptr);
}
}
private:
- struct sigaction previous_;
+ struct sigaction64 previous_;
};
#endif // BIONIC_TESTS_BIONIC_DEATH_TEST_H_
diff --git a/tests/ScopedSignalHandler.h b/tests/ScopedSignalHandler.h
index 85c41a8..36bbf10 100644
--- a/tests/ScopedSignalHandler.h
+++ b/tests/ScopedSignalHandler.h
@@ -26,6 +26,7 @@
#define posix_spawnattr_setsigdefault64 posix_spawnattr_setsigdefault
#define posix_spawnattr_setsigmask64 posix_spawnattr_setsigmask
#define pthread_sigmask64 pthread_sigmask
+#define sigaction64 sigaction
#define sigaddset64 sigaddset
#define sigdelset64 sigdelset
#define sigemptyset64 sigemptyset
@@ -47,7 +48,7 @@
memset(&action_, 0, sizeof(action_));
action_.sa_flags = sa_flags;
action_.sa_handler = handler;
- sigaction(signal_number_, &action_, &old_action_);
+ sigaction64(signal_number_, &action_, &old_action_);
}
ScopedSignalHandler(int signal_number, void (*action)(int, siginfo_t*, void*),
@@ -56,20 +57,20 @@
memset(&action_, 0, sizeof(action_));
action_.sa_flags = sa_flags;
action_.sa_sigaction = action;
- sigaction(signal_number_, &action_, &old_action_);
+ sigaction64(signal_number_, &action_, &old_action_);
}
ScopedSignalHandler(int signal_number) : signal_number_(signal_number) {
- sigaction(signal_number, nullptr, &old_action_);
+ sigaction64(signal_number, nullptr, &old_action_);
}
~ScopedSignalHandler() {
- sigaction(signal_number_, &old_action_, NULL);
+ sigaction64(signal_number_, &old_action_, NULL);
}
private:
- struct sigaction action_;
- struct sigaction old_action_;
+ struct sigaction64 action_;
+ struct sigaction64 old_action_;
const int signal_number_;
};
diff --git a/tests/signal_test.cpp b/tests/signal_test.cpp
index ebc079e..87a918f 100644
--- a/tests/signal_test.cpp
+++ b/tests/signal_test.cpp
@@ -269,55 +269,63 @@
ASSERT_EQ(1, g_sigsuspend64_signal_handler_call_count);
}
-static void EmptySignalHandler(int) {}
-static void EmptySignalAction(int, siginfo_t*, void*) {}
-
-TEST(signal, sigaction) {
+template <typename SigActionT, typename SigSetT>
+static void TestSigAction(int (sigaction_fn)(int, const SigActionT*, SigActionT*),
+ int (sigaddset_fn)(SigSetT*, int),
+ int sig) {
// Both bionic and glibc set SA_RESTORER when talking to the kernel on arm,
// arm64, x86, and x86-64. The version of glibc we're using also doesn't
// define SA_RESTORER, but luckily it's the same value everywhere, and mips
// doesn't use the bit for anything.
static const unsigned sa_restorer = 0x4000000;
- // See what's currently set for SIGALRM.
- struct sigaction original_sa;
- memset(&original_sa, 0, sizeof(original_sa));
- ASSERT_EQ(0, sigaction(SIGALRM, NULL, &original_sa));
+ // See what's currently set for this signal.
+ SigActionT original_sa = {};
+ ASSERT_EQ(0, sigaction_fn(sig, NULL, &original_sa));
ASSERT_TRUE(original_sa.sa_handler == NULL);
ASSERT_TRUE(original_sa.sa_sigaction == NULL);
ASSERT_EQ(0U, original_sa.sa_flags & ~sa_restorer);
// Set a traditional sa_handler signal handler.
- struct sigaction sa;
- memset(&sa, 0, sizeof(sa));
- sigaddset(&sa.sa_mask, SIGALRM);
+ auto no_op_signal_handler = [](int) {};
+ SigActionT sa = {};
+ sigaddset_fn(&sa.sa_mask, sig);
sa.sa_flags = SA_ONSTACK;
- sa.sa_handler = EmptySignalHandler;
- ASSERT_EQ(0, sigaction(SIGALRM, &sa, NULL));
+ sa.sa_handler = no_op_signal_handler;
+ ASSERT_EQ(0, sigaction_fn(sig, &sa, NULL));
// Check that we can read it back.
- memset(&sa, 0, sizeof(sa));
- ASSERT_EQ(0, sigaction(SIGALRM, NULL, &sa));
- ASSERT_TRUE(sa.sa_handler == EmptySignalHandler);
+ sa = {};
+ ASSERT_EQ(0, sigaction_fn(sig, NULL, &sa));
+ 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);
// Set a new-style sa_sigaction signal handler.
- memset(&sa, 0, sizeof(sa));
- sigaddset(&sa.sa_mask, SIGALRM);
+ auto no_op_sigaction = [](int, siginfo_t*, void*) {};
+ sa = {};
+ sigaddset_fn(&sa.sa_mask, sig);
sa.sa_flags = SA_ONSTACK | SA_SIGINFO;
- sa.sa_sigaction = EmptySignalAction;
- ASSERT_EQ(0, sigaction(SIGALRM, &sa, NULL));
+ sa.sa_sigaction = no_op_sigaction;
+ ASSERT_EQ(0, sigaction_fn(sig, &sa, NULL));
// Check that we can read it back.
- memset(&sa, 0, sizeof(sa));
- ASSERT_EQ(0, sigaction(SIGALRM, NULL, &sa));
- ASSERT_TRUE(sa.sa_sigaction == EmptySignalAction);
+ sa = {};
+ ASSERT_EQ(0, sigaction_fn(sig, NULL, &sa));
+ 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);
// Put everything back how it was.
- ASSERT_EQ(0, sigaction(SIGALRM, &original_sa, NULL));
+ ASSERT_EQ(0, sigaction_fn(sig, &original_sa, NULL));
+}
+
+TEST(signal, sigaction) {
+ TestSigAction(sigaction, sigaddset, SIGALRM);
+}
+
+TEST(signal, sigaction64_SIGRTMIN) {
+ TestSigAction(sigaction64, sigaddset64, SIGRTMIN);
}
TEST(signal, sys_signame) {
@@ -495,8 +503,7 @@
"* https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=66dd34ad31e5963d72a700ec3f2449291d322921\n";
static siginfo received;
- struct sigaction handler;
- memset(&handler, 0, sizeof(handler));
+ struct sigaction handler = {};
handler.sa_sigaction = [](int, siginfo_t* siginfo, void*) { received = *siginfo; };
handler.sa_flags = SA_SIGINFO;