diff options
author | Edward Welbourne <edward.welbourne@qt.io> | 2021-11-16 16:28:18 +0100 |
---|---|---|
committer | Edward Welbourne <edward.welbourne@qt.io> | 2021-11-18 18:13:20 +0100 |
commit | 771657e55f66c354e9e4ee682e6a0bd259521e06 (patch) | |
tree | 7ab90a09b7797faaaf80ab1a1faaf5c412b48faf /src/testlib/qtestcase.cpp | |
parent | f75d36fd18f58b91689aca2a389c62627c38e6b4 (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.cpp | 30 |
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) } |