/* * Portable Agile C++ Classes (PACC) * Copyright (C) 2004 by Marc Parizeau * http://manitou.gel.ulaval.ca/~parizeau/PACC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Contact: * Laboratoire de Vision et Systemes Numeriques * Departement de genie electrique et de genie informatique * Universite Laval, Quebec, Canada, G1K 7P4 * http://vision.gel.ulaval.ca * */ /*! * \file PACC/Util/SignalHandler.hpp * \brief Class definition for the portable signal handler. * \author Marc Dubreuil and Christian Gagne, Laboratoire de vision et systèmes numériques, Université Laval * $Revision: 1.5.2.1 $ * $Date: 2007/09/10 18:24:10 $ */ #ifndef PACC_SIGNALHANDLER_HPP #define PACC_SIGNALHANDLER_HPP #include #include namespace PACC { using namespace std; /*! * \brief Portable signal handling. * \author Marc Dubreuil, Christian Gagne and Marc Parizeau, Laboratoire de vision et systèmes numériques, Université Laval * \ingroup Util * * This class can be used to handle common signals. To define custom handlers, * it should be subclassed and virtual method SignalHandler::main should be * overloaded. For example, the following code snippet defines a custom * handler for signal SignalType::eSigInt (Ctl-C): \verbatim class SigIntHandler : public SignalHandler { public: SigIntHandler(void) {setCustomAction(eSigInt);} virtual void main(SignalType inType) { switch(inType) { case eSigInt: cout << "My custom handler!" << endl; exit(-1); default: cout << "Unsupported signal!" << endl; break; } } }; \endverbatim Furthermore, for each signal type, a stack of actions can be managed using methods SignalHandler::pushAction and SignalHandler::popAction. */ class SignalHandler { public: //! Enumeration of supported signal types. enum SignalType { eSigAbrt=0, //!< Abort (ANSI). eSigFPE, //!< Floating-point exception (ANSI). eSigIll, //!< Illegal instruction (ANSI). eSigInt, //!< Interrupt (ANSI). eSigSegV, //!< Segmentation violation (ANSI). eSigTerm, //!< Termination (ANSI). eSigAlrm, //!< Alarm clock (POSIX). eSigChld, //!< Child status has changed (POSIX). eSigCont, //!< Continue (POSIX). eSigHUp, //!< Hangup (POSIX). eSigKill, //!< Kill, unblockable (POSIX). eSigPipe, //!< Broken pipe (POSIX). eSigQuit, //!< Quit (POSIX). eSigStop, //!< Stop, unblockable (POSIX). eSigTStp, //!< Keyboard stop (POSIX). eSigTrap, //!< Trace trap (POSIX). eSigTTin, //!< Background read from tty (POSIX). eSigTTou, //!< Background write to tty (POSIX). eSigUsr1, //!< User-defined signal 1 (POSIX). eSigUsr2, //!< User-defined signal 2 (POSIX). NSIGNALS }; //! Construct this signal handler. SignalHandler(void) {} //! delete this signal handler. virtual ~SignalHandler(void) {} /*! \brief Main function of signal handler. This pure virtual method must be overloaded in a subclass in order to define custom signal actions. Argument \c inType specifies the signal type that must be processed for the current pending signal. */ virtual void main(SignalType inType) = 0; //! Pop previous action for signals of type \c inType. static void popAction(SignalType inType); //! Push current action for signals of type \c inType. static void pushAction(SignalType inType); //! Make this signal handler process future signals of type \c inType. void setCustomAction(SignalType inType); //! Make the default system action process future signals of type \c inType. static void setDefaultAction(SignalType inType); //! Specifies that future signals of type \c inType should be ignored. static void setIgnoreAction(SignalType inType); protected: //! Convert native signal number into a portable signal type. static SignalType convertFromNativeSignal(int inNativeNumber); //! Convert a portable signal type into a native signal number. static int convertToNativeSignal(SignalType inType); private: //! Pointer to signal handler function. typedef void (*HandlerPointer) (int); //! Action structure (pointer to either internal or external handler). struct Action { SignalHandler* mHandler; HandlerPointer mFunc; Action(SignalHandler* inHandler, HandlerPointer inFunc) : mHandler(inHandler), mFunc(inFunc) {} }; static stack smActions[NSIGNALS]; //!< Table of signal handler stacks. //! Run the current custom action for native signal \c inSignal. static void runAction(int inSignal); }; } // end of PACC namespace #endif