#include #ifdef __linux #ifndef SIGSYS #define SIGSYS SIGUNUSED #endif #endif // ***************************************************************************** // * SignalManager::reporter : // * This is the declaration for the error reporter. // ***************************************************************************** ErrorReporter SignalManager::reporter; // ***************************************************************************** // * SignalHandler::SignalHandler : // * This is the initializer for a SignalHandler class. It holds the // * information needed to handle a single signal number. // ***************************************************************************** _SignalHandler_::_SignalHandler_ ( void ) : signo(0), handler(NULL), oldHandler(NULL) { } // ***************************************************************************** // * SignalHandler::~SignalHandler : // * This is the destructor for the SignlaHandler class. It will call the // * uninstall method to remove the handler that was imposed for the signal. // ***************************************************************************** _SignalHandler_::~_SignalHandler_ ( void ) { uninstall (); } // ***************************************************************************** // * SignalHandler::install : // * This method will install the specified signal handler function on the // * signal number specified by signo. The old handler will be preserved // * for later restoration. // ***************************************************************************** void _SignalHandler_::install ( int newSigno, SignalHandlerFunc newHandler ) { // ********************************************************************* // * If a local signal handler has already been installed on the // * specified signal number, uninstall it before proceeding. // ********************************************************************* if(handler!=NULL && signo==newSigno) uninstall(); // ********************************************************************* // * Setup the control variables. // ********************************************************************* signo = newSigno; handler = newHandler; // ********************************************************************* // * Install the new signal handler, preserving the old handler in the // * oact sigaction structure. // ********************************************************************* oldHandler = signal(signo, handler); } // ***************************************************************************** // * SignalHandler::uninstall : // * This method will remove a user specified signal handler and will restore // * the previously installed handler. // ***************************************************************************** void _SignalHandler_::uninstall ( void ) { // ********************************************************************* // * Check to see if the signal handler has been installed. If so, // * call sigaction to confirm that the current signal handler is the // * one that was installed. // ********************************************************************* if(signo!=0 && handler!=NULL) { SignalHandlerFunc current = signal(signo, SIG_DFL); if(current==handler) signal(signo, oldHandler); else signal(signo, current); } signo = 0; handler = NULL; } // ***************************************************************************** // * SignalManager::installHandler : // * This method will install the specified signal handler. // ***************************************************************************** void SignalManager::installHandler (int signo, SignalHandlerFunc handler ) { if(signo>0 && signo<=MAXSIGNAL) signals[signo-1].install(signo, handler); } // ***************************************************************************** // * SignalManager::uninstallHandler : // * This method will remove a signal handler that was previously installed. // ***************************************************************************** void SignalManager::uninstallHandler ( int signo ) { if(signo>0 && signo<=MAXSIGNAL) signals[signo-1].uninstall(); } // ***************************************************************************** // * SignalManager::installDefaults : // * This method will install a default collection of signal handlers. // ***************************************************************************** void SignalManager::installDefaults ( void ) { static int sigList[] = { #if !defined (_WIN32) SIGFPE, // Erroneous arithmetic operation. SIGHUP, // Hangup. SIGILL, // Illegal instruction. SIGINT, // Terminal interrupt signal. SIGPIPE, // Write on a socket with no one to read SIGQUIT, // Terminal quit signal. SIGSEGV, // Invalid memory reference. SIGTERM, // Termination signal. SIGBUS, // Bus error. SIGSYS, // Bad system call. #else SIGABRT, // Process abort signal. SIGFPE, // Erroneous arithmetic operation. SIGILL, // Illegal instruction. SIGINT, // Terminal interrupt signal. SIGSEGV, // Invalid memory reference. SIGTERM, // Termination signal. #endif 0 }; for(int i=0; sigList[i]!=0; i++) installHandler(sigList[i], defaultHandler); } // ***************************************************************************** // * SignalManager::defaultHandler : // * This is the default signal handler method. // ***************************************************************************** void SignalManager::defaultHandler( int signo ) { switch(signo) { // ************************************************************* // * Process the interrupt signal by reporting it and exiting. // ************************************************************* case SIGINT: reporter.outputError ( CDEV_SEVERITY_INFO, "Signal Manager", "[SIGINT] Terminating at user's request"); exit(0); // ************************************************************* // * Process the terminate signal by reporting it and exiting. // ************************************************************* case SIGTERM: reporter.outputError ( CDEV_SEVERITY_INFO, "Signal Manager", "[SIGTERM] Terminating normally"); exit(0); // ************************************************************* // * Process abort signal by reporting the error and exiting. // ************************************************************* case SIGABRT: reporter.outputError ( CDEV_SEVERITY_SEVERE, "Signal Manager", "[SIGABRT] Application terminating due to abort signal"); abort(); // ************************************************************* // * Process erroneous arithmetic operations by reporting them // * and exiting. // ************************************************************* case SIGFPE: reporter.outputError ( CDEV_SEVERITY_SEVERE, "Signal Manager", "[SIGFPE] Floating point error - terminating\n"); abort(); // ************************************************************* // * Process illegal instructions by reporting them and exiting. // ************************************************************* case SIGILL: reporter.outputError ( CDEV_SEVERITY_SEVERE, "Signal Manager", "[SIGILL] Illegal instruction"); abort(); // ************************************************************* // * Process the segmentation fault signal by reporting the // * error and terminating. // ************************************************************* case SIGSEGV: reporter.outputError ( CDEV_SEVERITY_SEVERE, "Signal Manager", "[SIGSEGV] Segmentation fault"); abort(); #if !defined(_WIN32) // ************************************************************* // * Report pipe errors, however, do not terminate. // ************************************************************* case SIGPIPE: reporter.outputError ( CDEV_SEVERITY_ERROR, "Signal Manager", "[SIGPIPE] Write on a pipe with no one to read it"); errno = SIGPIPE; break; // ************************************************************* // * Process a bus error by reporting it and exiting. // ************************************************************* case SIGBUS: reporter.outputError ( CDEV_SEVERITY_SEVERE, "Signal Manager", "[SIGBUS] Bus error"); abort(); // ************************************************************* // * Process a bad system call by reporting it and exiting. // ************************************************************* case SIGSYS: reporter.outputError ( CDEV_SEVERITY_SEVERE, "Signal Manager", "[SIGSYS] Bad system call"); abort(); // ************************************************************* // * Ignore the following signals: // * SIGHUP: hangup signal. // * SIGQUIT: terminal quit signal // * default: All other signals // ************************************************************* case SIGHUP: case SIGQUIT: #endif default: break; } signal(signo, SignalManager::defaultHandler); }