SignalHandler: catch ctrl-c (SIGINT)

General discussion regarding the development of POCO for contributors.
Posts: 10
Joined: 22 Jan 2010, 07:08
Location: Germany

SignalHandler: catch ctrl-c (SIGINT)

Postby Rabenklaue » 03 Feb 2010, 00:14

As I did not find any way (except the waitForTermination() method in ServerApplication) to handle SIGINT (CTRL-C) signals in an aspired way on Linux (to ensure all destructors will be called or extra clean-up routines may be called), I inherited Poco::SignalHandler to handle those in a very similar way the actual implementation of SignalHandler does. Perhaps it is useful for anybody or could even be added to Poco (e.g. abstracting the waitForTermination() in a more C++ like way).

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 {

   SignalHandlerTerm() {
      JumpBufferVec& jbv = jumpBufferVec();
      JumpBuffer buf;

   ~SignalHandlerTerm() {

   static void throwSignalException(int sig) {
      switch (sig) {
         case SIGINT:
            throw SignalExceptionTerm("Interrupt");
         case SIGTERM:
            throw SignalExceptionTerm("Termination");

   static void install() {
      struct sigaction sa;
      sa.sa_handler = handleSignal;
      sa.sa_flags   = 0;
      sigaction(SIGINT, &sa, 0);
      sigaction(SIGTERM, &sa, 0);

   static void handleSignal(int sig) {
      JumpBufferVec& jb = jumpBufferVec();
      if (!jb.empty())
         siglongjmp(jb.back().buf, sig);

      // Abort if no jump buffer registered

   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);
#define throw_on_exit

int main(int argc, char** argv) {
   try {
#if defined(POCO_OS_FAMILY_UNIX)
   catch (SignalExceptionTerm& exc) {
      LogDebug(Poco::Logger::get("Main"), "Stop Application: " << exc.displayText());
      return Poco::Util::Application::EXIT_OK;
   catch(...) {}

   return Poco::Util::Application::EXIT_OK;

Posts: 10
Joined: 22 Jan 2010, 07:08
Location: Germany

Re: SignalHandler: catch ctrl-c (SIGINT)

Postby Rabenklaue » 10 Feb 2010, 14:20

Btw: In SignalHandler.cpp the

#include <signal.h>

should be changed to

#include <csignal> (seems more C++ conform)

Except that, why is SignalHandler only available for UNIX platforms (regarding the #ifdefs in the source)? As seen on MSDN it shall be available on Windows platforms as well.


Return to “Contributors”

Who is online

Users browsing this forum: No registered users and 1 guest