source: branches/alilink/TEMPLATES/SigHandler.h

Last change on this file was 9342, checked in by westram, 12 years ago
  • fixed compilation of NDEBUG-version with assertions
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 3.2 KB
Line 
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
23typedef 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
37inline bool is_default_or_ignore_sighandler(SigHandler sh) {
38    return sh == SIG_DFL || sh == SIG_IGN;
39}
40
41#ifdef DEBUG
42
43// #define TRACE_SIGNAL_HANDLERS
44
45inline 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
61inline 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
78inline SigHandler install_SigHandler(int sig, SigHandler handler) {
79    return signal(sig, handler);
80}
81inline 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
Note: See TracBrowser for help on using the repository browser.