summaryrefslogtreecommitdiffstats
path: root/src/testlib/qtestcase.cpp
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2021-11-16 16:28:18 +0100
committerEdward Welbourne <edward.welbourne@qt.io>2021-11-18 18:13:20 +0100
commit771657e55f66c354e9e4ee682e6a0bd259521e06 (patch)
tree7ab90a09b7797faaaf80ab1a1faaf5c412b48faf /src/testlib/qtestcase.cpp
parentf75d36fd18f58b91689aca2a389c62627c38e6b4 (diff)
Test the return from sigaction()
If we fail to install our own action, the contents of oldact are noise anyway, so we can't use them to decide anything; and, in any case, we didn't replace the prior action, so have no duty to restore it. In the process, restructure and comment the code to make it easier to follow what's going on and why. Package a conditional in a lambda to make the #if-ery less problematic. This should also make it easier to hack any other complications into the condition, should they arise. Change-Id: I712335ee27f68a8594dc2fe6441a91f686967da2 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/testlib/qtestcase.cpp')
-rw-r--r--src/testlib/qtestcase.cpp30
1 files changed, 19 insertions, 11 deletions
diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp
index a160b07bde..79191861b1 100644
--- a/src/testlib/qtestcase.cpp
+++ b/src/testlib/qtestcase.cpp
@@ -1706,20 +1706,28 @@ public:
for (int i = 0; fatalSignals[i]; ++i)
sigaddset(&act.sa_mask, fatalSignals[i]);
- struct sigaction oldact;
-
- for (int i = 0; fatalSignals[i]; ++i) {
- sigaction(fatalSignals[i], &act, &oldact);
- if (
+ // The destructor can only restore SIG_DFL, so only register for signals
+ // that had default handling previously.
+ const auto isDefaultHandler = [](const struct sigaction &old) {
# ifdef SA_SIGINFO
- oldact.sa_flags & SA_SIGINFO ||
+ // void sa_sigaction(int, siginfo_t *, void *) is never the default:
+ if (old.sa_flags & SA_SIGINFO)
+ return false;
# endif
- oldact.sa_handler != SIG_DFL) {
- sigaction(fatalSignals[i], &oldact, nullptr);
- } else
- {
+ // Otherwise, the handler is void sa_handler(int) but may be
+ // SIG_DFL (default action) or SIG_IGN (ignore signal):
+ return old.sa_handler == SIG_DFL;
+ };
+
+ struct sigaction oldact;
+ for (int i = 0; fatalSignals[i]; ++i) {
+ // Registering reveals the existing handler:
+ if (sigaction(fatalSignals[i], &act, &oldact))
+ continue; // Failed to set our handler; nothing to restore.
+ if (isDefaultHandler(oldact))
sigaddset(&handledSignals, fatalSignals[i]);
- }
+ else // Restore non-default handler:
+ sigaction(fatalSignals[i], &oldact, nullptr);
}
#endif // defined(Q_OS_UNIX) && !defined(Q_OS_WASM)
}