From 69f975c05a5df201375fdef9bef88282cc2d7fbb Mon Sep 17 00:00:00 2001 From: magiblot Date: Sun, 15 Oct 2023 23:57:54 +0200 Subject: [PATCH] platform: handle SIG_IGN properly in SignalHandler --- source/platform/sighandl.cpp | 12 ++++++++++-- test/platform/sighandl.test.cpp | 12 ++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/source/platform/sighandl.cpp b/source/platform/sighandl.cpp index bf8b839b..855dcb91 100644 --- a/source/platform/sighandl.cpp +++ b/source/platform/sighandl.cpp @@ -98,15 +98,23 @@ void SignalHandler::handleSignal(int signo, siginfo_t *info, void *context) } } +template +static inline bool isCustomHandler(T &&handler) +{ + return (void *) handler != (void *) SIG_DFL + && (void *) handler != (void *) SIG_IGN; +} + bool SignalHandler::invokeHandlerOrDefault( int signo, const struct sigaction &action, siginfo_t *info, void *context ) noexcept { // If the handler is a custom one, invoke it directly. - if ((action.sa_flags & SA_SIGINFO) && action.sa_sigaction) + if ((action.sa_flags & SA_SIGINFO) && isCustomHandler(action.sa_sigaction)) action.sa_sigaction(signo, info, context); - else if (!(action.sa_flags & SA_SIGINFO) && action.sa_handler) + else if (!(action.sa_flags & SA_SIGINFO) && isCustomHandler(action.sa_handler)) action.sa_handler(signo); else + // Run default handler by re-raising the signal. return invokeDefault(signo, info); return false; } diff --git a/test/platform/sighandl.test.cpp b/test/platform/sighandl.test.cpp index ed7850e6..bcbd2e7f 100644 --- a/test/platform/sighandl.test.cpp +++ b/test/platform/sighandl.test.cpp @@ -158,6 +158,18 @@ TEST_F(SignalHandlerTest, ShouldOnlyInvokeCallbackOnEnterWhenSignalKillsTheProce ASSERT_EQ(counters->callbackExitInvocations, 0); } +TEST_F(SignalHandlerTest, ShouldInvokeCallbackOnEnterAndExitWhenSignalIsIgnored) +{ + installSignalHandler(SIGINT, SIG_IGN); + SignalHandler::enable(signalCallbackThatTemporarilyDisablesSignalHandler); + for (int i = 1; i <= 2; ++i) + { + ASSERT_NE(raise(SIGINT), -1); + ASSERT_EQ(counters->callbackEnterInvocations, i); + ASSERT_EQ(counters->callbackExitInvocations, i); + } +} + TEST_F(SignalHandlerTest, ShouldFallBackToDefaultHandlerWhenCallbackAborts) { installSignalHandler(SIGABRT, signalHandlerThatDoesNotKillTheProcess);