- Code: Select all
#include <Poco/SignalHandler.h>
#include <Poco/Exception.h>
#if defined(POCO_OS_FAMILY_UNIX)
#include <csignal>
#include <cstdlib>
POCO_DECLARE_EXCEPTION(Foundation_API, SignalExceptionTerm, Poco::LogicException);
POCO_IMPLEMENT_EXCEPTION(SignalExceptionTerm, Poco::LogicException, "Signal received");
class SignalHandlerTerm : public Poco::SignalHandler {
public:
SignalHandlerTerm() {
JumpBufferVec& jbv = jumpBufferVec();
JumpBuffer buf;
jbv.push_back(buf);
}
~SignalHandlerTerm() {
jumpBufferVec().pop_back();
}
static void throwSignalException(int sig) {
switch (sig) {
case SIGINT:
throw SignalExceptionTerm("Interrupt");
case SIGTERM:
throw SignalExceptionTerm("Termination");
}
}
static void install() {
#ifndef POCO_NO_SIGNAL_HANDLER
struct sigaction sa;
sa.sa_handler = handleSignal;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
sigaction(SIGINT, &sa, 0);
sigaction(SIGTERM, &sa, 0);
#endif
}
static void handleSignal(int sig) {
JumpBufferVec& jb = jumpBufferVec();
if (!jb.empty())
siglongjmp(jb.back().buf, sig);
// Abort if no jump buffer registered
std::abort();
}
private:
friend class ThreadImpl;
static JumpBufferVec _jumpBufferVec;
};
SignalHandlerTerm::JumpBufferVec SignalHandlerTerm::_jumpBufferVec;
#define throw_on_exit \
SignalHandlerTerm signal_handler_term; \
SignalHandlerTerm::install(); \
int _term_signal = sigsetjmp(signal_handler_term.jumpBuffer(), 1); \
if (_term_signal) signal_handler_term.throwSignalException(_term_signal);
#else
#define throw_on_exit
#endif // POCO_OS_FAMILY_UNIX
int main(int argc, char** argv) {
try {
throw_on_exit;
sleep(100);
}
#if defined(POCO_OS_FAMILY_UNIX)
catch (SignalExceptionTerm& exc) {
LogDebug(Poco::Logger::get("Main"), "Stop Application: " << exc.displayText());
return Poco::Util::Application::EXIT_OK;
}
#else
catch(...) {}
#endif // POCO_OS_FAMILY_UNIX
return Poco::Util::Application::EXIT_OK;
}





