Crypto++ 8.9 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>
58 struct SignalHandler
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
config.h
Library configuration file.
CryptoPP
Crypto++ library namespace.
SignalHandlerFn
void(* SignalHandlerFn)(int)
Signal handler function pointer.
Definition: ossig.h:26
NullSignalHandler
void NullSignalHandler(int unused)
Null signal handler function.
Definition: ossig.h:36
SignalHandler
Signal handler for Linux and Unix compatibles.
Definition: ossig.h:59
SignalHandler::SignalHandler
SignalHandler(SignalHandlerFn pfn=NULL, int flags=0)
Construct a signal handler.
Definition: ossig.h:78