ARB
SigHandler.h
Go to the documentation of this file.
1 // =============================================================== //
2 // //
3 // File : SigHandler.h //
4 // Purpose : declare function type for signal handlers //
5 // and wrappers for install/uninstall //
6 // //
7 // Institute of Microbiology (Technical University Munich) //
8 // http://www.arb-home.de/ //
9 // //
10 // =============================================================== //
11 
12 #ifndef SIGHANDLER_H
13 #define SIGHANDLER_H
14 
15 #if defined(LINUX)
16 # include <signal.h>
17 # ifdef SIG_PF
18 # define SigHandler SIG_PF
19 # else
20 # define SigHandler __sighandler_t
21 # endif
22 #else
23 typedef void (*SigHandler)(int);
24 #endif
25 
26 #ifndef _GLIBCXX_CSTDIO
27 #include <cstdio>
28 #endif
29 #ifndef _GLIBCXX_CERRNO
30 #include <cerrno>
31 #endif
32 
33 #ifndef ARB_ASSERT_H
34 #error missing include to arb_assert.h
35 #endif
36 
38  return sh == SIG_DFL || sh == SIG_IGN;
39 }
40 
41 #ifdef DEBUG
42 
43 // #define TRACE_SIGNAL_HANDLERS
44 
45 inline SigHandler install_SigHandler(int sig, SigHandler handler, const char *context, const char *signame) {
46  arb_assert(handler != SIG_ERR);
47  SigHandler old_handler = signal(sig, handler);
48 #if defined(TRACE_SIGNAL_HANDLERS)
49  fprintf(stderr, "> sighandler[%s] changed (%p->%p)\n", signame, old_handler, handler);
50  fflush(stderr);
51 #endif // TRACE_SIGNAL_HANDLERS
52  if (old_handler == SIG_ERR) {
53  fprintf(stderr, "%s: failed to install %s handler (Reason: %s)\n",
54  context, signame, strerror(errno));
55  fflush(stderr);
56  arb_assert(0);
57  }
58  return old_handler;
59 }
60 
61 inline void uninstall_SigHandler(int sig, SigHandler handler, SigHandler old_handler, const char *context, const char *signame) {
62  if (old_handler != SIG_ERR) { // do not try to uninstall if installation failed
63  SigHandler uninstalled_handler = install_SigHandler(sig, old_handler, context, signame);
64 
65  if (uninstalled_handler != SIG_IGN) {
66  // if signal occurred, handler might have been reset to SIG_IGN
67  // (this behavior is implementation defined)
68  arb_assert(uninstalled_handler == handler);
69  }
70  }
71 }
72 
73 #define INSTALL_SIGHANDLER(sig, handler, context) install_SigHandler(sig, handler, context, #sig)
74 #define UNINSTALL_SIGHANDLER(sig, handler, old_handler, context) uninstall_SigHandler(sig, handler, old_handler, context, #sig)
75 
76 #else
77 
78 inline SigHandler install_SigHandler(int sig, SigHandler handler) {
79  return signal(sig, handler);
80 }
81 inline void uninstall_SigHandler(int sig, SigHandler IF_ASSERTION_USED(handler), SigHandler old_handler) {
82  if (old_handler != SIG_ERR) {
83  ASSERT_RESULT(SigHandler, handler, signal(sig, old_handler));
84  }
85 }
86 
87 #define INSTALL_SIGHANDLER(sig, handler, context) install_SigHandler(sig, handler)
88 #define UNINSTALL_SIGHANDLER(sig, handler, old_handler, context) uninstall_SigHandler(sig, handler, old_handler)
89 
90 #endif
91 
92 #else
93 #error SigHandler.h included twice
94 #endif // SIGHANDLER_H
#define arb_assert(cond)
Definition: arb_assert.h:245
SigHandler install_SigHandler(int sig, SigHandler handler)
Definition: SigHandler.h:78
#define ASSERT_RESULT(Type, Expected, Expr)
Definition: arb_assert.h:336
fflush(stdout)
bool is_default_or_ignore_sighandler(SigHandler sh)
Definition: SigHandler.h:37
#define IF_ASSERTION_USED(x)
Definition: arb_assert.h:308
void uninstall_SigHandler(int sig, SigHandler IF_ASSERTION_USED(handler), SigHandler old_handler)
Definition: SigHandler.h:81
void(* SigHandler)(int)
Definition: SigHandler.h:23