Imported Upstream version 0.3.3
[anytun.git] / src / signalController.cpp
index 2e4a53e..6a20588 100644 (file)
 
 #include <map>
 #include <iostream>
+#include <boost/bind.hpp>
 
 #include "signalController.h"
 #include "log.h"
 #include "anytunError.h"
 #include "threadUtils.hpp"
 
-#ifndef _MSC_VER
-#include <csignal>
-#include <boost/bind.hpp>
-#else
-#include <windows.h>
-#endif
-
 SignalController* SignalController::inst = NULL;
 Mutex SignalController::instMutex;
 SignalController& gSignalController = SignalController::instance();
@@ -59,157 +53,28 @@ SignalController& SignalController::instance()
        return *inst;
 }
 
-int SigErrorHandler::handle(const std::string& msg)
+int SigErrorHandler(int /*sig*/, const std::string& msg)
 {
   AnytunError::throwErr() << msg;
 
   return 0;
 }
 
+//use system specific signal handler
 #ifndef _MSC_VER
-
-int SigIntHandler::handle()
-{
-  cLog.msg(Log::PRIO_NOTICE) << "SIG-Int caught, exiting";
-
-  return 1;
-}
-
-int SigQuitHandler::handle()
-{
-  cLog.msg(Log::PRIO_NOTICE) << "SIG-Quit caught, exiting";
-
-  return 1;
-}
-
-int SigHupHandler::handle()
-{
-  cLog.msg(Log::PRIO_NOTICE) << "SIG-Hup caught";
-
-  return 0;
-}
-
-int SigTermHandler::handle()
-{
-  cLog.msg(Log::PRIO_NOTICE) << "SIG-Term caughtm, exiting";
-
-  return 1;
-}
-
-int SigUsr1Handler::handle()
-{
-  cLog.msg(Log::PRIO_NOTICE) << "SIG-Usr1 caught";
-
-  return 0;
-}
-
-int SigUsr2Handler::handle()
-{
-  cLog.msg(Log::PRIO_NOTICE) << "SIG-Usr2 caught";
-
-  return 0;
-}
-#else
-int CtrlCHandler::handle()
-{
-  cLog.msg(Log::PRIO_NOTICE) << "CTRL-C Event received, exitting";
-
-  return 1;
-}
-
-int CtrlBreakHandler::handle()
-{
-  cLog.msg(Log::PRIO_NOTICE) << "CTRL-Break Event received, ignoring";
-
-  return 0;
-}
-
-int CtrlCloseHandler::handle()
-{
-  cLog.msg(Log::PRIO_NOTICE) << "Close Event received, exitting";
-
-  return 1;
-}
-
-int CtrlLogoffHandler::handle()
-{
-  cLog.msg(Log::PRIO_NOTICE) << "LogOff Event received, exitting";
-
-  return 1;
-}
-
-int CtrlShutdownHandler::handle()
-{
-  cLog.msg(Log::PRIO_NOTICE) << "Shutdown Event received, exitting";
-
-  return 1;
-}
-#endif
-
-SignalController::~SignalController() 
-{
-  for(HandlerMap::iterator it = handler.begin(); it != handler.end(); ++it)
-    delete it->second;
-}
-
-#ifndef _MSC_VER
-void SignalController::handle()
-{
-  sigset_t signal_set;
-  int sigNum;
-
-  while(1) 
-  {
-    sigfillset(&signal_set);
-    sigwait(&signal_set, &sigNum);
-    inject(sigNum);
-  }
-}
+#include "signalHandler.hpp"
 #else
-bool SignalController::handle(DWORD ctrlType)
-{
-  gSignalController.inject(ctrlType);
-  return true;
-}
+ #ifdef WIN_SERVICE
+ #include "win32/signalServiceHandler.hpp"
+ #else
+ #include "win32/signalHandler.hpp"
+ #endif
 #endif
 
-void SignalController::init()
+void SignalController::init(DaemonService& service)
 {
-#ifndef _MSC_VER
-  sigset_t signal_set;
-  
-  sigfillset(&signal_set);        
-  sigdelset(&signal_set, SIGCHLD);
-  sigdelset(&signal_set, SIGSEGV);
-  sigdelset(&signal_set, SIGBUS);
-  sigdelset(&signal_set, SIGFPE);
-
-#if defined(BOOST_HAS_PTHREADS)
-  pthread_sigmask(SIG_BLOCK, &signal_set, NULL);
-#else
-#error The signalhandler works only with pthreads
-#endif
-  
-  boost::thread(boost::bind(&SignalController::handle, this));
-
-  handler[SIGINT] = new SigIntHandler;
-  handler[SIGQUIT] = new SigQuitHandler;
-  handler[SIGHUP] = new SigHupHandler;
-  handler[SIGTERM] = new SigTermHandler;
-  handler[SIGUSR1] = new SigUsr1Handler;
-  handler[SIGUSR2] = new SigUsr2Handler;
-#else
-  if(!SetConsoleCtrlHandler((PHANDLER_ROUTINE)SignalController::handle, true))
-    AnytunError::throwErr() << "Error on SetConsoleCtrlhandler: " << AnytunErrno(GetLastError());
-
-  handler[CTRL_C_EVENT] = new CtrlCHandler;
-  handler[CTRL_BREAK_EVENT] = new CtrlBreakHandler;
-  handler[CTRL_CLOSE_EVENT] = new CtrlCloseHandler;
-  handler[CTRL_LOGOFF_EVENT] = new CtrlLogoffHandler;
-  handler[CTRL_SHUTDOWN_EVENT] = new CtrlShutdownHandler;
-#endif
-
-  handler[SIGERROR] = new SigErrorHandler;
+  registerSignalHandler(*this, service);
+  handler[SIGERROR] = boost::bind(SigErrorHandler, _1, _2);
 }
 
 void SignalController::inject(int sig, const std::string& msg)
@@ -223,6 +88,11 @@ void SignalController::inject(int sig, const std::string& msg)
 
 int SignalController::run()
 {
+  for(CallbackMap::iterator it = callbacks.begin(); it != callbacks.end(); ++it)
+    if(it->first == CALLB_RUNNING)
+      it->second();
+
+  int ret = 0;
   while(1) {
     sigQueueSem.down();
     SigPair sig;
@@ -235,18 +105,24 @@ int SignalController::run()
     HandlerMap::iterator it = handler.find(sig.first);
     if(it != handler.end())
     {
-      int ret;
-      if(sig.second == "")
-        ret = it->second->handle();
-      else
-        ret = it->second->handle(sig.second);
+      ret = it->second(sig.first, sig.second);
 
       if(ret)
-        return ret;
+        break;
+    }
+    else {
+      it = handler.find(SIGUNKNOWN);
+      if(it != handler.end())
+        it->second(sig.first, sig.second);
+      else
+        cLog.msg(Log::PRIO_NOTICE) << "SIG " << sig.first << " caught with message '" << sig.second << "' - ignoring";
     }
-    else
-      cLog.msg(Log::PRIO_NOTICE) << "SIG " << sig.first << " caught with message '" << sig.second << "' - ignoring";
   }
-  return 0;
+
+  for(CallbackMap::iterator it = callbacks.begin(); it != callbacks.end(); ++it)
+    if(it->first == CALLB_STOPPING)
+      it->second();
+
+  return ret;
 }