Files
cdev-1.7.2n/extensions/cdevGenericServer/lib/SignalManager.cc
2022-12-13 12:44:04 +01:00

258 lines
9.0 KiB
C++
Executable File

#include <SignalManager.h>
#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);
}