// Copyright (c) 1999-2002 David Muse
// See the COPYING file for more information
#include <rudiments/signalclasses.h>
#include <rudiments/rawbuffer.h>
#include <rudiments/error.h>
#include <stddef.h>
#ifdef RUDIMENTS_HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <stdlib.h>
#ifdef RUDIMENTS_NAMESPACE
namespace rudiments {
#endif
class signalsetprivate {
friend class signalset;
private:
sigset_t _sigset;
};
// signalset methods
signalset::signalset() {
pvt=new signalsetprivate;
rawbuffer::zero(&pvt->_sigset,sizeof(pvt->_sigset));
}
signalset::~signalset() {
delete pvt;
}
bool signalset::addSignal(int signum) {
return !sigaddset(&pvt->_sigset,signum);
}
bool signalset::addAllSignals() {
return !sigfillset(&pvt->_sigset);
}
bool signalset::removeSignal(int signum) {
return !sigdelset(&pvt->_sigset,signum);
}
bool signalset::removeAllSignals() {
return !sigemptyset(&pvt->_sigset);
}
int signalset::signalIsInSet(int signum) const {
return sigismember(&pvt->_sigset,signum);
}
sigset_t *signalset::getSignalSet() {
return &pvt->_sigset;
}
// signalmanager methods
bool signalmanager::sendSignal(pid_t processid, int signum) {
int result;
do {
result=kill(processid,signum);
} while (result==-1 && error::getErrorNumber()==EINTR);
return !result;
}
bool signalmanager::raiseSignal(int signum) {
int result;
do {
result=raise(signum);
} while (result==-1 && error::getErrorNumber()==EINTR);
return !result;
}
unsigned int signalmanager::alarm(unsigned int seconds) {
return ::alarm(seconds);
}
bool signalmanager::ignoreSignals(const sigset_t *sigset) {
int result;
do {
result=sigprocmask(SIG_SETMASK,sigset,NULL);
} while (result==-1 && error::getErrorNumber()==EINTR);
return !result;
}
bool signalmanager::waitForSignals(const sigset_t *sigset) {
return (sigsuspend(sigset)==-1);
}
bool signalmanager::examineBlockedSignals(sigset_t *sigset) {
int result;
do {
result=sigpending(sigset);
} while (result==-1 && error::getErrorNumber()==EINTR);
return !result;
}
class signalhandlerprivate {
friend class signalhandler;
private:
struct sigaction _handlerstruct;
};
// signalhandler methods
signalhandler::signalhandler() {
pvt=new signalhandlerprivate;
removeAllSignalsFromMask();
removeAllFlags();
}
signalhandler::signalhandler(int signum, void *handler) {
pvt=new signalhandlerprivate;
removeAllSignalsFromMask();
removeAllFlags();
setHandler(handler);
handleSignal(signum);
}
signalhandler::~signalhandler() {
delete pvt;
}
void signalhandler::setHandler(void *handler) {
#ifdef RUDIMENTS_SIGNAL_HANDLER_INT
pvt->_handlerstruct.sa_handler=(void(*)(int))handler;
#else
pvt->_handlerstruct.sa_handler=(void(*)(void))handler;
#endif
}
void *signalhandler::getHandler() {
return (void *)pvt->_handlerstruct.sa_handler;
}
void signalhandler::removeAllFlags() {
pvt->_handlerstruct.sa_flags=0;
}
void signalhandler::addFlag(int flag) {
pvt->_handlerstruct.sa_flags|=flag;
}
bool signalhandler::addAllSignalsToMask() {
return !sigfillset(&pvt->_handlerstruct.sa_mask);
}
bool signalhandler::addSignalToMask(int signum) {
return !sigaddset(&pvt->_handlerstruct.sa_mask,signum);
}
bool signalhandler::removeSignalFromMask(int signum) {
return !sigdelset(&pvt->_handlerstruct.sa_mask,signum);
}
bool signalhandler::removeAllSignalsFromMask() {
return !sigemptyset(&pvt->_handlerstruct.sa_mask);
}
int signalhandler::signalIsInMask(int signum) const {
return sigismember(&pvt->_handlerstruct.sa_mask,signum);
}
sigset_t signalhandler::getMask() const {
return pvt->_handlerstruct.sa_mask;
}
int signalhandler::getFlags() const {
return pvt->_handlerstruct.sa_flags;
}
bool signalhandler::handleSignal(int signum) {
int result;
do {
result=sigaction(signum,&pvt->_handlerstruct,
static_cast<struct sigaction *>(NULL));
} while (result==-1 && error::getErrorNumber()==EINTR);
return !result;
}
bool signalhandler::handleSignal(int signum, signalhandler *oldhandler) {
struct sigaction oldaction;
int result;
do {
result=sigaction(signum,&pvt->_handlerstruct,&oldaction);
} while (result==-1 && error::getErrorNumber()==EINTR);
rawbuffer::copy(&oldhandler->pvt->_handlerstruct,&oldaction,
sizeof(struct sigaction));
return !result;
}
#ifdef RUDIMENTS_NAMESPACE
}
#endif
syntax highlighted by Code2HTML, v. 0.9.1