test
CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
UnixSignalHandlers.cc
Go to the documentation of this file.
1 #include <iostream>
2 #include <iomanip>
3 #include <cstdlib>
4 #include <cstdio>
5 #include <cstring>
6 
9 
10 #if !defined(NSIG)
11 #if defined(_NSIG)
12 #define NSIG _NSIG
13 #elif defined(__DARWIN_NSIG)
14 #define NSIG __DARWIN_NSIG
15 #endif
16 #endif
17 
18 namespace edm {
19 
20 //--------------------------------------------------------------
21 
22  volatile std::atomic<bool> shutdown_flag{false};
23 
24  extern "C" {
25  void ep_sigusr2(int,siginfo_t*,void*)
26  {
27  FDEBUG(1) << "in sigusr2 handler\n";
28  shutdown_flag.store(true);
29  }
30  }
31 #define MUST_BE_ZERO(fun) if((fun) != 0) \
32 { perror("UnixSignalHandlers::setupSignal: sig function failed"); abort(); }
33 
34 //--------------------------------------------------------------
35 
36  void disableAllSigs( sigset_t* oldset )
37  {
38  sigset_t myset;
39  // all blocked for now
40  MUST_BE_ZERO(sigfillset(&myset));
41  MUST_BE_ZERO(pthread_sigmask(SIG_SETMASK,&myset,oldset));
42  }
43 
44 //--------------------------------------------------------------
45 
47  {
48 #if defined(__linux__)
49  // ignore all the RT signals
50  sigset_t myset;
51  MUST_BE_ZERO(sigemptyset(&myset));
52 
53  struct sigaction tmpact;
54  memset(&tmpact,0,sizeof(tmpact));
55  tmpact.sa_handler = SIG_IGN;
56 
57  for(int num = SIGRTMIN; num < SIGRTMAX; ++num) {
58  MUST_BE_ZERO(sigaddset(&myset,num));
59  MUST_BE_ZERO(sigaction(num,&tmpact,NULL));
60  }
61 
62  MUST_BE_ZERO(pthread_sigmask(SIG_BLOCK,&myset,0));
63 #endif
64  }
65 
66 //--------------------------------------------------------------
67 
68  void reenableSigs( sigset_t* oldset )
69  {
70  // reenable the signals
71  MUST_BE_ZERO(pthread_sigmask(SIG_SETMASK,oldset,0));
72  }
73 
74 //--------------------------------------------------------------
75 
76  void enableSignal( sigset_t* newset, const int signum )
77  {
78  // enable the specified signal
79  MUST_BE_ZERO(sigaddset(newset, signum));
80  }
81 
82 
83 //--------------------------------------------------------------
84 
85  void disableSignal( sigset_t* newset, const int signum )
86  {
87  // disable the specified signal
88  MUST_BE_ZERO(sigdelset(newset, signum));
89  }
90 
91 //--------------------------------------------------------------
92 
93  void installCustomHandler( const int signum, CFUNC func )
94  {
95  sigset_t oldset;
96  edm::disableAllSigs(&oldset);
97 #if defined(__linux__)
99 #endif
100  edm::installSig(signum,func);
101  edm::reenableSigs(&oldset);
102  }
103 
104 //--------------------------------------------------------------
105 
106  void installSig( const int signum, CFUNC func )
107  {
108  // set up my RT signal now
109  struct sigaction act;
110  memset(&act,0,sizeof(act));
111  act.sa_sigaction = func;
112  act.sa_flags = SA_RESTART;
113 
114  // get my signal number
115  int mysig = signum;
116  if( mysig == SIGKILL ) {
117  perror("Cannot install handler for KILL signal");
118  return;
119  } else if( mysig == SIGSTOP ) {
120  perror("Cannot install handler for STOP signal");
121  return;
122  }
123 
124  if(sigaction(mysig,&act,NULL) != 0) {
125  perror("sigaction failed");
126  abort();
127  }
128 
129  sigset_t newset;
130  MUST_BE_ZERO(sigemptyset(&newset));
131  MUST_BE_ZERO(sigaddset(&newset,mysig));
132  MUST_BE_ZERO(pthread_sigmask(SIG_UNBLOCK,&newset,0));
133  }
134 
135 //--------------------------------------------------------------
136 
138  {
139  sigset_t tmpset, oldset;
140 // Make a full house set of signals, except for SIGKILL = 9
141 // and SIGSTOP = 19 which cannot be blocked
142  MUST_BE_ZERO(sigfillset(&tmpset));
143  MUST_BE_ZERO(sigdelset(&tmpset, SIGKILL));
144  MUST_BE_ZERO(sigdelset(&tmpset, SIGSTOP));
145 // Swap it with the current sigset_t
146  MUST_BE_ZERO(pthread_sigmask( SIG_SETMASK, &tmpset, &oldset ));
147 // Now see what's included in the set
148  for(int k=1; k<NSIG; ++k) {
149  std::cerr << "sigismember is " << sigismember( &tmpset, k )
150  << " for signal " << std::setw(2) << k
151 #if defined(__linux__)
152  << " (" << strsignal(k) << ")"
153 #endif
154  << std::endl;
155  }
156 // Finally put the original sigset_t back
157  MUST_BE_ZERO(pthread_sigmask( SIG_SETMASK, &oldset, &tmpset));
158  }
159 
160 } // end of namespace edm
void installSig(int signum, CFUNC func)
void disableAllSigs(sigset_t *oldset)
#define NULL
Definition: scimark2.h:8
volatile std::atomic< bool > shutdown_flag
void installCustomHandler(int signum, CFUNC func)
#define FDEBUG(lev)
Definition: DebugMacros.h:18
void enableSignal(sigset_t *newset, int signum)
void reenableSigs(sigset_t *oldset)
void disableSignal(sigset_t *newset, int signum)
void sigInventory()
void ep_sigusr2(int, siginfo_t *, void *)
void(* CFUNC)(int, siginfo_t *, void *)
#define MUST_BE_ZERO(fun)
void disableRTSigs()