//=========================================================================== // @(#) $Name: cflowd-2-1-b1 $ $Id: Signal.cc,v 1.1 1998/09/14 17:06:33 dwm Exp $ //=========================================================================== extern "C" { #include #include #include } using namespace std; #include #include "Signal.hh" static const string rcsid = "@(#) $Name: cflowd-2-1-b1 $ $Id: Signal.cc,v 1.1 1998/09/14 17:06:33 dwm Exp $"; static sigset_t _caughtSignals; struct sigaction curAction[NSIG+1]; //--------------------------------------------------------------------------- // Signal::Signal(int sigNum) //........................................................................... // Constructor //--------------------------------------------------------------------------- Signal::Signal(int sigNum) { struct sigaction action; assert(sigNum > 0); assert(sigNum <= NSIG); memset(&action,0,sizeof(action)); sigemptyset(&_caughtSignals); this->signalNumber = sigNum; curAction[sigNum].sa_handler = SIG_DFL; curAction[sigNum].sa_flags = 0; action.sa_flags = 0; action.sa_handler = SIG_DFL; this->sigactionStack.push_front(action); } //--------------------------------------------------------------------------- // static void _interceptSigHandler(int sigNum) //........................................................................... // //--------------------------------------------------------------------------- static void _interceptSigHandler(int sigNum) { sigaddset(&_caughtSignals,sigNum); curAction[sigNum].sa_handler(sigNum); return; } //--------------------------------------------------------------------------- // int Signal::Block() //........................................................................... // Blocks signal. Returns 0. //--------------------------------------------------------------------------- int Signal::Block() { sigset_t blockSet; sigemptyset(&blockSet); sigaddset(&blockSet,this->signalNumber); sigprocmask(SIG_BLOCK,&blockSet,NULL); return(0); } //--------------------------------------------------------------------------- // int Signal::IsBlocked() //........................................................................... // Returns 1 if signal is currently blocked, else returns 0. //--------------------------------------------------------------------------- int Signal::IsBlocked() { sigset_t blockSet; sigemptyset(&blockSet); sigprocmask(SIG_BLOCK,NULL,&blockSet); if (sigismember(&blockSet,this->signalNumber)) return(1); else return(0); } //--------------------------------------------------------------------------- // int Signal::Unblock() //........................................................................... // Unblocks signal. Returns 0. //--------------------------------------------------------------------------- int Signal::Unblock() { sigset_t blockSet; sigemptyset(&blockSet); sigaddset(&blockSet,this->signalNumber); sigprocmask(SIG_UNBLOCK,&blockSet,NULL); return(0); } //--------------------------------------------------------------------------- // int Signal::IsPending() //........................................................................... // Returns 1 if signal is pending, 0 if it is not, and -1 on error. //--------------------------------------------------------------------------- int Signal::IsPending() { sigset_t pendingSet; sigemptyset(&pendingSet); if (sigpending(&pendingSet) == 0) { if (sigismember(&pendingSet,this->signalNumber)) { return(1); } else { return(0); } } else { syslog(LOG_ERR,"[E] %s:%d sigpending(%p) failed: %m",__FILE__,__LINE__, &pendingSet); return(-1); } } //--------------------------------------------------------------------------- // int Signal::InstallHandler(void (*handler)(int)) //........................................................................... // Install function (*handler)(int) as signal handler for signal. // Push the handler onto a stack which can be popped later with // RemoveHandler(). Returns 0 if successful, -1 on error. //--------------------------------------------------------------------------- int Signal::InstallHandler(void (*handler)(int)) { struct sigaction action, oldAction, interceptAction; sigaction(this->signalNumber,NULL,&oldAction); memcpy(&action,&oldAction,sizeof(action)); action.sa_handler = handler; action.sa_flags = 0; this->sigactionStack.push_front(action); curAction[this->signalNumber].sa_handler = handler; memcpy(&interceptAction,&action,sizeof(interceptAction)); interceptAction.sa_handler = _interceptSigHandler; if (sigaction(this->signalNumber,&interceptAction,&oldAction) < 0) { syslog(LOG_ERR,"[E] %s:%d sigaction(%d,%p,%p) failed: %m", __FILE__,__LINE__,this->signalNumber,&interceptAction,&oldAction); return(-1); } return(0); } //--------------------------------------------------------------------------- // int Signal::RemoveHandler() //........................................................................... // Pops the current signal handler for signal sigNum off the stack, and if // the stack still has a handler in it, instantiates the front handler on // the stack. Returns 0 on success and -1 on failure. //--------------------------------------------------------------------------- int Signal::RemoveHandler() { this->sigactionStack.pop_front(); sigdelset(&_caughtSignals,this->signalNumber); if (this->sigactionStack.size() > 0) { if (sigaction(this->signalNumber, &(this->sigactionStack.front()),NULL) < 0) { syslog(LOG_ERR,"[E] %s:%d sigaction(%d,%p,NULL) failed: %m", __FILE__,__LINE__,this->signalNumber, &(this->sigactionStack.front())); return(-1); } return(0); } return(-1); } //--------------------------------------------------------------------------- // int Signal::Caught() //........................................................................... // //--------------------------------------------------------------------------- int Signal::Caught() { return(sigismember(&_caughtSignals,this->signalNumber)); } //--------------------------------------------------------------------------- // void Signal::Catch() //........................................................................... // //--------------------------------------------------------------------------- void Signal::Catch() { sigdelset(&_caughtSignals,this->signalNumber); return; }