Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:55:06

0001 // ossig.h - written and placed in the public domain by Jeffrey Walton

0002 //

0003 /// \file ossig.h

0004 /// \brief Utility class for trapping OS signals.

0005 /// \since Crypto++ 5.6.5

0006 
0007 #ifndef CRYPTOPP_OS_SIGNAL_H
0008 #define CRYPTOPP_OS_SIGNAL_H
0009 
0010 #include "config.h"
0011 
0012 #if defined(UNIX_SIGNALS_AVAILABLE)
0013 # include <signal.h>
0014 #endif
0015 
0016 NAMESPACE_BEGIN(CryptoPP)
0017 
0018 // ************** Unix and Linux compatibles ***************

0019 
0020 #if defined(UNIX_SIGNALS_AVAILABLE) || defined(CRYPTOPP_DOXYGEN_PROCESSING)
0021 
0022 /// \brief Signal handler function pointer

0023 /// \details SignalHandlerFn is provided as a stand alone function pointer with external "C" linkage

0024 /// \sa SignalHandler, NullSignalHandler

0025 extern "C" {
0026     typedef void (*SignalHandlerFn) (int);
0027 }
0028 
0029 /// \brief Null signal handler function

0030 /// \param unused the signal number

0031 /// \details NullSignalHandler is provided as a stand alone function with external "C" linkage

0032 ///  and not a static member function due to the member function's implicit

0033 ///  external "C++" linkage.

0034 /// \sa SignalHandler, SignalHandlerFn

0035 extern "C" {
0036     inline void NullSignalHandler(int unused) {CRYPTOPP_UNUSED(unused);}
0037 }
0038 
0039 /// Signal handler for Linux and Unix compatibles

0040 /// \tparam S Signal number

0041 /// \tparam O Flag indicating if an existing handler should be overwritten

0042 /// \details SignalHandler() can be used to install a signal handler with the signature

0043 ///  <tt>void handler_fn(int)</tt>. If <tt>SignalHandlerFn</tt> is not <tt>NULL</tt>, then

0044 ///  the sigaction is set to the function and the sigaction flags is set to the flags.

0045 ///  If <tt>SignalHandlerFn</tt> is <tt>NULL</tt>, then a default handler is installed

0046 ///  using sigaction flags set to 0. The default handler only returns from the call.

0047 /// \details Upon destruction the previous signal handler is restored if the former signal handler

0048 ///  was replaced.

0049 /// \details On Cygwin systems using Newlib, you should define <tt>_XOPEN_SOURCE=700</tt> or

0050 ///  <tt>_GNU_SOURCE</tt>; or use <tt>-std=gnu++03</tt>, <tt>-std=gnu++11</tt>, or similar. If

0051 ///  you compile with <tt>-std=c++03</tt>, <tt>-std=c++11</tt> or similar, then define

0052 ///  <tt>_XOPEN_SOURCE=700</tt>.

0053 /// \warning Do not use SignalHandler in a code block that uses <tt>setjmp</tt> or <tt>longjmp</tt>

0054 ///  because the destructor may not run.

0055 /// \since Crypto++ 5.6.5

0056 /// \sa NullSignalHandler, SignalHandlerFn, \ref CRYPTOPP_ASSERT "CRYPTOPP_ASSERT", DebugTrapHandler

0057 template <int S, bool O=false>
0058 struct SignalHandler
0059 {
0060     /// \brief Construct a signal handler

0061     /// \param pfn Pointer to a signal handler function

0062     /// \param flags Flags to use with the signal handler

0063     /// \details SignalHandler() installs a signal handler with the signature

0064     ///  <tt>void handler_fn(int)</tt>. If <tt>SignalHandlerFn</tt> is not <tt>NULL</tt>, then

0065     ///  the sigaction is set to the function and the sigaction flags is set to the flags.

0066     ///  If <tt>SignalHandlerFn</tt> is <tt>NULL</tt>, then a default handler is installed

0067     ///  using sigaction flags set to 0. The default handler only returns from the call.

0068     /// \details Upon destruction the previous signal handler is restored if the former signal handler

0069     ///  was overwritten.

0070     /// \details On Cygwin systems using Newlib, you should define <tt>_XOPEN_SOURCE=700</tt> or

0071     ///  <tt>_GNU_SOURCE</tt>; or use <tt>-std=gnu++03</tt>, <tt>-std=gnu++11</tt>, or similar. If

0072     ///  you compile with <tt>-std=c++03</tt>, <tt>-std=c++11</tt> or similar, then define

0073     ///  <tt>_XOPEN_SOURCE=700</tt>.

0074     /// \warning Do not use SignalHandler in a code block that uses <tt>setjmp</tt> or <tt>longjmp</tt>

0075     ///  because the destructor may not run. <tt>setjmp</tt> is why cpu.cpp does not use SignalHandler

0076     ///  during CPU feature testing.

0077     /// \since Crypto++ 5.6.5

0078     SignalHandler(SignalHandlerFn pfn = NULLPTR, int flags = 0) : m_installed(false)
0079     {
0080         // http://pubs.opengroup.org/onlinepubs/007908799/xsh/sigaction.html

0081         struct sigaction new_handler;
0082 
0083         do
0084         {
0085             int ret = 0;
0086 
0087             ret = sigaction (S, 0, &m_old);
0088             if (ret != 0) break; // Failed

0089 
0090             // Don't step on another's handler if Overwrite=false

0091             if (m_old.sa_handler != 0 && !O) break;
0092 
0093             // Cygwin/Newlib requires -D_XOPEN_SOURCE=700

0094             ret = sigemptyset (&new_handler.sa_mask);
0095             if (ret != 0) break; // Failed

0096 
0097             new_handler.sa_handler = (pfn ? pfn : &NullSignalHandler);
0098             new_handler.sa_flags = (pfn ? flags : 0);
0099 
0100             // Install it

0101             ret = sigaction (S, &new_handler, 0);
0102             if (ret != 0) break; // Failed

0103 
0104             m_installed = true;
0105 
0106         } while(0);
0107     }
0108 
0109     ~SignalHandler()
0110     {
0111         if (m_installed)
0112             sigaction (S, &m_old, 0);
0113     }
0114 
0115 private:
0116     struct sigaction m_old;
0117     bool m_installed;
0118 
0119 private:
0120     // Not copyable

0121     SignalHandler(const SignalHandler &);
0122     void operator=(const SignalHandler &);
0123 };
0124 #endif
0125 
0126 NAMESPACE_END
0127 
0128 #endif // CRYPTOPP_OS_SIGNAL_H