Crypto++  5.6.5
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 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 exsting handler should be overwriiten
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 //! \warning Do not use SignalHandler in a code block that uses <tt>setjmp</tt> or <tt>longjmp</tt>
50 //! because the destructor may not run.
51 //! \since Crypto++ 5.6.5
52 //! \sa NullSignalHandler, SignalHandlerFn, \ref CRYPTOPP_ASSERT "CRYPTOPP_ASSERT", DebugTrapHandler
53 template <int S, bool O=false>
55 {
56  //! \brief Construct a signal handler
57  //! \param pfn Pointer to a signal handler function
58  //! \param flags Flags to use with the signal handler
59  //! \details SignalHandler() installs a signal handler with the signature
60  //! <tt>void handler_fn(int)</tt>. If <tt>SignalHandlerFn</tt> is not <tt>NULL</tt>, then
61  //! the sigaction is set to the function and the sigaction flags is set to the flags.
62  //! If <tt>SignalHandlerFn</tt> is <tt>NULL</tt>, then a default handler is installed
63  //! using sigaction flags set to 0. The default handler only returns from the call.
64  //! \details Upon destruction the previous signal handler is restored if the former signal handler
65  //! was overwritten.
66  //! \warning Do not use SignalHandler in a code block that uses <tt>setjmp</tt> or <tt>longjmp</tt>
67  //! because the destructor may not run. <tt>setjmp</tt> is why cpu.cpp does not use SignalHandler
68  //! during CPU feature testing.
69  //! \since Crypto++ 5.6.5
70  SignalHandler(SignalHandlerFn pfn = NULL, int flags = 0) : m_installed(false)
71  {
72  // http://pubs.opengroup.org/onlinepubs/007908799/xsh/sigaction.html
73  struct sigaction new_handler;
74 
75  do
76  {
77  int ret = 0;
78 
79  ret = sigaction (S, 0, &m_old);
80  if (ret != 0) break; // Failed
81 
82  // Don't step on another's handler if Overwrite=false
83  if (m_old.sa_handler != 0 && !O) break;
84 
85 #if defined __CYGWIN__
86  // http://github.com/weidai11/cryptopp/issues/315
87  memset(&new_handler, 0x00, sizeof(new_handler));
88 #else
89  ret = sigemptyset (&new_handler.sa_mask);
90  if (ret != 0) break; // Failed
91 #endif
92 
93  new_handler.sa_handler = (pfn ? pfn : &NullSignalHandler);
94  new_handler.sa_flags = (pfn ? flags : 0);
95 
96  // Install it
97  ret = sigaction (S, &new_handler, 0);
98  if (ret != 0) break; // Failed
99 
100  m_installed = true;
101 
102  } while(0);
103  }
104 
105  ~SignalHandler()
106  {
107  if (m_installed)
108  sigaction (S, &m_old, 0);
109  }
110 
111 private:
112  struct sigaction m_old;
113  bool m_installed;
114 
115 private:
116  // Not copyable
117  SignalHandler(const SignalHandler &);
118  void operator=(const SignalHandler &);
119 };
120 #endif
121 
122 NAMESPACE_END
123 
124 #endif // CRYPTOPP_OS_SIGNAL_H
void NullSignalHandler(int unused)
Null signal handler function.
Definition: ossig.h:36
Signal handler for Linux and Unix compatibles.
Definition: ossig.h:54
Library configuration file.
void(* SignalHandlerFn)(int)
Signal handler function pointer.
Definition: ossig.h:26
SignalHandler(SignalHandlerFn pfn=NULL, int flags=0)
Construct a signal handler.
Definition: ossig.h:70