1 /* 2 * Portable Agile C++ Classes (PACC) 3 * Copyright (C) 2004 by Marc Parizeau 4 * http://manitou.gel.ulaval.ca/~parizeau/PACC 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * 20 * Contact: 21 * Laboratoire de Vision et Systemes Numeriques 22 * Departement de genie electrique et de genie informatique 23 * Universite Laval, Quebec, Canada, G1K 7P4 24 * http://vision.gel.ulaval.ca 25 * 26 */ 27 28 /*! 29 * \file PACC/Util/SignalHandler.hpp 30 * \brief Class definition for the portable signal handler. 31 * \author Marc Dubreuil and Christian Gagne, Laboratoire de vision et systèmes numériques, Université Laval 32 * $Revision: 1.5.2.1 $ 33 * $Date: 2007/09/10 18:24:10 $ 34 */ 35 36 #ifndef PACC_SIGNALHANDLER_HPP 37 #define PACC_SIGNALHANDLER_HPP 38 39 #include <stack> 40 #include <signal.h> 41 42 namespace PACC { 43 44 using namespace std; 45 46 /*! 47 * \brief Portable signal handling. 48 * \author Marc Dubreuil, Christian Gagne and Marc Parizeau, Laboratoire de vision et systèmes numériques, Université Laval 49 * \ingroup Util 50 * 51 * This class can be used to handle common signals. To define custom handlers, 52 * it should be subclassed and virtual method SignalHandler::main should be 53 * overloaded. For example, the following code snippet defines a custom 54 * handler for signal SignalType::eSigInt (Ctl-C): 55 \verbatim 56 class SigIntHandler : public SignalHandler { 57 public: 58 SigIntHandler(void) {setCustomAction(eSigInt);} 59 60 virtual void main(SignalType inType) { 61 switch(inType) { 62 case eSigInt: 63 cout << "My custom handler!" << endl; 64 exit(-1); 65 default: 66 cout << "Unsupported signal!" << endl; 67 break; 68 } 69 } 70 }; 71 \endverbatim 72 Furthermore, for each signal type, a stack of actions can be managed using methods SignalHandler::pushAction and SignalHandler::popAction. 73 */ 74 class SignalHandler { 75 public: 76 //! Enumeration of supported signal types. 77 enum SignalType { 78 eSigAbrt=0, //!< Abort (ANSI). 79 eSigFPE, //!< Floating-point exception (ANSI). 80 eSigIll, //!< Illegal instruction (ANSI). 81 eSigInt, //!< Interrupt (ANSI). 82 eSigSegV, //!< Segmentation violation (ANSI). 83 eSigTerm, //!< Termination (ANSI). 84 eSigAlrm, //!< Alarm clock (POSIX). 85 eSigChld, //!< Child status has changed (POSIX). 86 eSigCont, //!< Continue (POSIX). 87 eSigHUp, //!< Hangup (POSIX). 88 eSigKill, //!< Kill, unblockable (POSIX). 89 eSigPipe, //!< Broken pipe (POSIX). 90 eSigQuit, //!< Quit (POSIX). 91 eSigStop, //!< Stop, unblockable (POSIX). 92 eSigTStp, //!< Keyboard stop (POSIX). 93 eSigTrap, //!< Trace trap (POSIX). 94 eSigTTin, //!< Background read from tty (POSIX). 95 eSigTTou, //!< Background write to tty (POSIX). 96 eSigUsr1, //!< User-defined signal 1 (POSIX). 97 eSigUsr2, //!< User-defined signal 2 (POSIX). 98 NSIGNALS 99 }; 100 101 //! Construct this signal handler. SignalHandler(void)102 SignalHandler(void) {} 103 104 //! delete this signal handler. ~SignalHandler(void)105 virtual ~SignalHandler(void) {} 106 107 /*! \brief Main function of signal handler. 108 109 This pure virtual method must be overloaded in a subclass in order to 110 define custom signal actions. Argument \c inType specifies the signal 111 type that must be processed for the current pending signal. 112 */ 113 virtual void main(SignalType inType) = 0; 114 115 //! Pop previous action for signals of type \c inType. 116 static void popAction(SignalType inType); 117 118 //! Push current action for signals of type \c inType. 119 static void pushAction(SignalType inType); 120 121 //! Make this signal handler process future signals of type \c inType. 122 void setCustomAction(SignalType inType); 123 124 //! Make the default system action process future signals of type \c inType. 125 static void setDefaultAction(SignalType inType); 126 127 //! Specifies that future signals of type \c inType should be ignored. 128 static void setIgnoreAction(SignalType inType); 129 130 protected: 131 //! Convert native signal number into a portable signal type. 132 static SignalType convertFromNativeSignal(int inNativeNumber); 133 134 //! Convert a portable signal type into a native signal number. 135 static int convertToNativeSignal(SignalType inType); 136 137 private: 138 //! Pointer to signal handler function. 139 typedef void (*HandlerPointer) (int); 140 141 //! Action structure (pointer to either internal or external handler). 142 struct Action { 143 SignalHandler* mHandler; 144 HandlerPointer mFunc; ActionPACC::SignalHandler::Action145 Action(SignalHandler* inHandler, HandlerPointer inFunc) : mHandler(inHandler), mFunc(inFunc) {} 146 }; 147 148 static stack<Action> smActions[NSIGNALS]; //!< Table of signal handler stacks. 149 150 //! Run the current custom action for native signal \c inSignal. 151 static void runAction(int inSignal); 152 }; 153 154 } // end of PACC namespace 155 156 #endif 157