Crypto++  8.6
Free C++ class library of cryptographic schemes
ossig.h
Go to the documentation of this file.
1 // ossig.h - written and placed in the public domain by Jeffrey Walton
2 //
3 /// \file ossig.h
4 /// \brief Utility class for trapping OS signals.
5 /// \since Crypto++ 5.6.5
6 
7 #ifndef CRYPTOPP_OS_SIGNAL_H
8 #define CRYPTOPP_OS_SIGNAL_H
9 
10 #include "config.h"
11 
12 #if defined(UNIX_SIGNALS_AVAILABLE)
13 # include <signal.h>
14 #endif
15 
16 NAMESPACE_BEGIN(CryptoPP)
17 
18 // ************** Unix and Linux compatibles ***************
19 
20 #if defined(UNIX_SIGNALS_AVAILABLE) || defined(CRYPTOPP_DOXYGEN_PROCESSING)
21 
22 /// \brief Signal handler function pointer
23 /// \details SignalHandlerFn is provided as a stand alone function pointer with external "C" linkage
24 /// \sa SignalHandler, NullSignalHandler
25 extern "C" {
26  typedef void (*SignalHandlerFn) (int);
27 }
28 
29 /// \brief Null signal handler function
30 /// \param unused the signal number
31 /// \details NullSignalHandler is provided as a stand alone function with external "C" linkage
32 /// and not a static member function due to the member function's implicit
33 /// external "C++" linkage.
34 /// \sa SignalHandler, SignalHandlerFn
35 extern "C" {
36  inline void NullSignalHandler(int unused) {CRYPTOPP_UNUSED(unused);}
37 }
38 
39 /// Signal handler for Linux and Unix compatibles
40 /// \tparam S Signal number
41 /// \tparam O Flag indicating if an existing handler should be overwritten
42 /// \details SignalHandler() can be used to install a signal handler with the signature
43 /// <tt>void handler_fn(int)</tt>. If <tt>SignalHandlerFn</tt> is not <tt>NULL</tt>, then
44 /// the sigaction is set to the function and the sigaction flags is set to the flags.
45 /// If <tt>SignalHandlerFn</tt> is <tt>NULL</tt>, then a default handler is installed
46 /// using sigaction flags set to 0. The default handler only returns from the call.
47 /// \details Upon destruction the previous signal handler is restored if the former signal handler
48 /// was replaced.
49 /// \details On Cygwin systems using Newlib, you should define <tt>_XOPEN_SOURCE=700</tt> or
50 /// <tt>_GNU_SOURCE</tt>; or use <tt>-std=gnu++03</tt>, <tt>-std=gnu++11</tt>, or similar. If
51 /// you compile with <tt>-std=c++03</tt>, <tt>-std=c++11</tt> or similar, then define
52 /// <tt>_XOPEN_SOURCE=700</tt>.
53 /// \warning Do not use SignalHandler in a code block that uses <tt>setjmp</tt> or <tt>longjmp</tt>
54 /// because the destructor may not run.
55 /// \since Crypto++ 5.6.5
56 /// \sa NullSignalHandler, SignalHandlerFn, \ref CRYPTOPP_ASSERT "CRYPTOPP_ASSERT", DebugTrapHandler
57 template <int S, bool O=false>
59 {
60  /// \brief Construct a signal handler
61  /// \param pfn Pointer to a signal handler function
62  /// \param flags Flags to use with the signal handler
63  /// \details SignalHandler() installs a signal handler with the signature
64  /// <tt>void handler_fn(int)</tt>. If <tt>SignalHandlerFn</tt> is not <tt>NULL</tt>, then
65  /// the sigaction is set to the function and the sigaction flags is set to the flags.
66  /// If <tt>SignalHandlerFn</tt> is <tt>NULL</tt>, then a default handler is installed
67  /// using sigaction flags set to 0. The default handler only returns from the call.
68  /// \details Upon destruction the previous signal handler is restored if the former signal handler
69  /// was overwritten.
70  /// \details On Cygwin systems using Newlib, you should define <tt>_XOPEN_SOURCE=700</tt> or
71  /// <tt>_GNU_SOURCE</tt>; or use <tt>-std=gnu++03</tt>, <tt>-std=gnu++11</tt>, or similar. If
72  /// you compile with <tt>-std=c++03</tt>, <tt>-std=c++11</tt> or similar, then define
73  /// <tt>_XOPEN_SOURCE=700</tt>.
74  /// \warning Do not use SignalHandler in a code block that uses <tt>setjmp</tt> or <tt>longjmp</tt>
75  /// because the destructor may not run. <tt>setjmp</tt> is why cpu.cpp does not use SignalHandler
76  /// during CPU feature testing.
77  /// \since Crypto++ 5.6.5
78  SignalHandler(SignalHandlerFn pfn = NULLPTR, int flags = 0) : m_installed(false)
79  {
80  // http://pubs.opengroup.org/onlinepubs/007908799/xsh/sigaction.html
81  struct sigaction new_handler;
82 
83  do
84  {
85  int ret = 0;
86 
87  ret = sigaction (S, 0, &m_old);
88  if (ret != 0) break; // Failed
89 
90  // Don't step on another's handler if Overwrite=false
91  if (m_old.sa_handler != 0 && !O) break;
92 
93  // Cygwin/Newlib requires -D_XOPEN_SOURCE=700
94  ret = sigemptyset (&new_handler.sa_mask);
95  if (ret != 0) break; // Failed
96 
97  new_handler.sa_handler = (pfn ? pfn : &NullSignalHandler);
98  new_handler.sa_flags = (pfn ? flags : 0);
99 
100  // Install it
101  ret = sigaction (S, &new_handler, 0);
102  if (ret != 0) break; // Failed
103 
104  m_installed = true;
105 
106  } while(0);
107  }
108 
109  ~SignalHandler()
110  {
111  if (m_installed)
112  sigaction (S, &m_old, 0);
113  }
114 
115 private:
116  struct sigaction m_old;
117  bool m_installed;
118 
119 private:
120  // Not copyable
121  SignalHandler(const SignalHandler &);
122  void operator=(const SignalHandler &);
123 };
124 #endif
125 
126 NAMESPACE_END
127 
128 #endif // CRYPTOPP_OS_SIGNAL_H
SignalHandler
Signal handler for Linux and Unix compatibles.
Definition: ossig.h:58
SignalHandlerFn
void(* SignalHandlerFn)(int)
Signal handler function pointer.
Definition: ossig.h:26
CryptoPP
Crypto++ library namespace.
config.h
Library configuration file.
NullSignalHandler
void NullSignalHandler(int unused)
Null signal handler function.
Definition: ossig.h:36
SignalHandler::SignalHandler
SignalHandler(SignalHandlerFn pfn=NULL, int flags=0)
Construct a signal handler.
Definition: ossig.h:78