File indexing completed on 2024-04-06 12:13:14
0001 #include <iostream>
0002 #include <iomanip>
0003 #include <cstdlib>
0004 #include <cstdio>
0005 #include <cstring>
0006
0007 #include "FWCore/Utilities/interface/UnixSignalHandlers.h"
0008 #include "FWCore/Utilities/interface/DebugMacros.h"
0009
0010 #if !defined(NSIG)
0011 #if defined(_NSIG)
0012 #define NSIG _NSIG
0013 #elif defined(__DARWIN_NSIG)
0014 #define NSIG __DARWIN_NSIG
0015 #endif
0016 #endif
0017
0018 namespace edm {
0019
0020
0021
0022 volatile std::atomic<bool> shutdown_flag{false};
0023
0024 extern "C" {
0025 void ep_sigusr2(int, siginfo_t*, void*) {
0026 FDEBUG(1) << "in sigusr2 handler\n";
0027 shutdown_flag.store(true);
0028 }
0029 }
0030 #define MUST_BE_ZERO(fun) \
0031 if ((fun) != 0) { \
0032 perror("UnixSignalHandlers::setupSignal: sig function failed"); \
0033 abort(); \
0034 }
0035
0036
0037
0038 void disableAllSigs(sigset_t* oldset) {
0039 sigset_t myset;
0040
0041 MUST_BE_ZERO(sigfillset(&myset));
0042 MUST_BE_ZERO(pthread_sigmask(SIG_SETMASK, &myset, oldset));
0043 }
0044
0045
0046
0047 void disableRTSigs() {
0048 #if defined(__linux__)
0049
0050 sigset_t myset;
0051 MUST_BE_ZERO(sigemptyset(&myset));
0052
0053 struct sigaction tmpact;
0054 memset(&tmpact, 0, sizeof(tmpact));
0055 tmpact.sa_handler = SIG_IGN;
0056
0057 for (int num = SIGRTMIN; num <= SIGRTMAX; ++num) {
0058
0059 if (num == 38)
0060 continue;
0061
0062 MUST_BE_ZERO(sigaddset(&myset, num));
0063 MUST_BE_ZERO(sigaction(num, &tmpact, nullptr));
0064 }
0065
0066 MUST_BE_ZERO(pthread_sigmask(SIG_BLOCK, &myset, nullptr));
0067 #endif
0068 }
0069
0070
0071
0072 void reenableSigs(sigset_t* oldset) {
0073
0074 MUST_BE_ZERO(pthread_sigmask(SIG_SETMASK, oldset, nullptr));
0075 }
0076
0077
0078
0079 void enableSignal(sigset_t* newset, const int signum) {
0080
0081 MUST_BE_ZERO(sigaddset(newset, signum));
0082 }
0083
0084
0085
0086 void disableSignal(sigset_t* newset, const int signum) {
0087
0088 MUST_BE_ZERO(sigdelset(newset, signum));
0089 }
0090
0091
0092
0093 void installCustomHandler(const int signum, CFUNC func) {
0094 sigset_t oldset;
0095 edm::disableAllSigs(&oldset);
0096 #if defined(__linux__)
0097 edm::disableRTSigs();
0098 #endif
0099 edm::installSig(signum, func);
0100 edm::reenableSigs(&oldset);
0101 }
0102
0103
0104
0105 void installSig(const int signum, CFUNC func) {
0106
0107 struct sigaction act;
0108 memset(&act, 0, sizeof(act));
0109 act.sa_sigaction = func;
0110 act.sa_flags = SA_RESTART;
0111
0112
0113 int mysig = signum;
0114 if (mysig == SIGKILL) {
0115 perror("Cannot install handler for KILL signal");
0116 return;
0117 } else if (mysig == SIGSTOP) {
0118 perror("Cannot install handler for STOP signal");
0119 return;
0120 }
0121
0122 if (sigaction(mysig, &act, nullptr) != 0) {
0123 perror("sigaction failed");
0124 abort();
0125 }
0126
0127 sigset_t newset;
0128 MUST_BE_ZERO(sigemptyset(&newset));
0129 MUST_BE_ZERO(sigaddset(&newset, mysig));
0130 MUST_BE_ZERO(pthread_sigmask(SIG_UNBLOCK, &newset, nullptr));
0131 }
0132
0133
0134
0135 void sigInventory() {
0136 sigset_t tmpset, oldset;
0137
0138
0139 MUST_BE_ZERO(sigfillset(&tmpset));
0140 MUST_BE_ZERO(sigdelset(&tmpset, SIGKILL));
0141 MUST_BE_ZERO(sigdelset(&tmpset, SIGSTOP));
0142
0143 MUST_BE_ZERO(pthread_sigmask(SIG_SETMASK, &tmpset, &oldset));
0144
0145 for (int k = 1; k < NSIG; ++k) {
0146 std::cerr << "sigismember is " << sigismember(&tmpset, k) << " for signal " << std::setw(2) << k
0147 #if defined(__linux__)
0148 << " (" << strsignal(k) << ")"
0149 #endif
0150 << std::endl;
0151 }
0152
0153 MUST_BE_ZERO(pthread_sigmask(SIG_SETMASK, &oldset, &tmpset));
0154 }
0155
0156 }