summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Pointner <equinox@anytun.org>2009-02-22 06:16:10 +0000
committerChristian Pointner <equinox@anytun.org>2009-02-22 06:16:10 +0000
commit5c0eb60b509edf766e649d081d30ab8dea83a8f4 (patch)
tree7e7ffa3e6aaa42f65ea13ac3297890e64b66944b
parentfixed build on Windows (after logging chances) (diff)
added signal controller (console control handler) to windows
-rw-r--r--src/anytun-controld.cpp7
-rw-r--r--src/anytun.cpp5
-rw-r--r--src/anytun.suobin64000 -> 66048 bytes
-rw-r--r--src/anytun.vcproj12
-rw-r--r--src/signalController.cpp98
-rw-r--r--src/signalController.h77
-rw-r--r--src/win32/winService.cpp12
7 files changed, 185 insertions, 26 deletions
diff --git a/src/anytun-controld.cpp b/src/anytun-controld.cpp
index 680d143..2c6c619 100644
--- a/src/anytun-controld.cpp
+++ b/src/anytun-controld.cpp
@@ -150,14 +150,13 @@ int main(int argc, char* argv[])
pidFile << pid;
pidFile.close();
}
-
- SignalController sig;
- sig.init();
+
+ gSignalController.init();
boost::thread * syncListenerThread;
syncListenerThread = new boost::thread(boost::bind(syncListener));
- int ret = sig.run();
+ int ret = gSignalController.run();
return ret;
}
diff --git a/src/anytun.cpp b/src/anytun.cpp
index 1fb1fd8..b6f370b 100644
--- a/src/anytun.cpp
+++ b/src/anytun.cpp
@@ -476,8 +476,7 @@ int main(int argc, char* argv[])
#endif
#ifndef NO_SIGNALCONTROLLER
- SignalController sig;
- sig.init();
+ gSignalController.init();
#endif
OptionHost* connTo = new OptionHost();
@@ -503,7 +502,7 @@ int main(int argc, char* argv[])
int ret = 0;
gWinService.waitForStop();
#elif !defined(NO_SIGNALCONTROLLER)
- int ret = sig.run();
+ int ret = gSignalController.run();
#else
receiver(&p);
int ret = 0;
diff --git a/src/anytun.suo b/src/anytun.suo
index 05fc354..2392b5f 100644
--- a/src/anytun.suo
+++ b/src/anytun.suo
Binary files differ
diff --git a/src/anytun.vcproj b/src/anytun.vcproj
index 16cb37f..696e905 100644
--- a/src/anytun.vcproj
+++ b/src/anytun.vcproj
@@ -42,7 +42,7 @@
Name="VCCLCompilerTool"
AdditionalOptions="/I &quot;C:\Program Files\boost\boost_1_35_0\&quot;"
Optimization="0"
- PreprocessorDefinitions="LOG_FILE;LOG_STDOUT;LOG_WINEVENTLOG;USE_SSL_CRYPTO;NO_DAEMON;NO_EXEC;NO_SIGNALCONTROLLER;WIN32_LEAN_AND_MEAN"
+ PreprocessorDefinitions="LOG_FILE;LOG_STDOUT;LOG_WINEVENTLOG;USE_SSL_CRYPTO;NO_DAEMON;NO_EXEC;WIN32_LEAN_AND_MEAN"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
@@ -116,7 +116,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- PreprocessorDefinitions="LOG_FILE;LOG_STDOUT;LOG_WINEVENTLOG;USE_SSL_CRYPTO;NO_DAEMON;NO_EXEC;NO_SIGNALCONTROLLER;WIN32_LEAN_AND_MEAN"
+ PreprocessorDefinitions="LOG_FILE;LOG_STDOUT;LOG_WINEVENTLOG;USE_SSL_CRYPTO;NO_DAEMON;NO_EXEC;WIN32_LEAN_AND_MEAN"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
@@ -433,6 +433,10 @@
>
</File>
<File
+ RelativePath=".\signalController.h"
+ >
+ </File>
+ <File
RelativePath=".\syncBuffer.h"
>
</File>
@@ -617,6 +621,10 @@
>
</File>
<File
+ RelativePath=".\signalController.cpp"
+ >
+ </File>
+ <File
RelativePath=".\syncBuffer.cpp"
>
</File>
diff --git a/src/signalController.cpp b/src/signalController.cpp
index 8d9c78f..4868d55 100644
--- a/src/signalController.cpp
+++ b/src/signalController.cpp
@@ -29,16 +29,37 @@
* along with anytun. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <csignal>
-#include <map>
+#ifndef NO_SIGNALCONTROLLER
+#include <map>
#include <iostream>
-#include <boost/bind.hpp>
-#include "threadUtils.hpp"
#include "signalController.h"
#include "log.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();
+
+SignalController& SignalController::instance()
+{
+ Lock lock(instMutex);
+ static instanceCleaner c;
+ if(!inst)
+ inst = new SignalController();
+
+ return *inst;
+}
+
+#ifndef _MSC_VER
int SigIntHandler::handle()
{
@@ -81,14 +102,54 @@ int SigUsr2Handler::handle()
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
if(thread) delete thread;
+#endif
}
+#ifndef _MSC_VER
void SignalController::handle(void *s)
{
SignalController* self = reinterpret_cast<SignalController*>(s);
@@ -106,9 +167,18 @@ void SignalController::handle(void *s)
self->sigQueueSem.up();
}
}
+#else
+bool SignalController::handle(DWORD ctrlType)
+{
+ gSignalController.sigQueue.push(ctrlType);
+ gSignalController.sigQueueSem.up();
+ return true;
+}
+#endif
void SignalController::init()
{
+#ifndef _MSC_VER
sigset_t signal_set;
sigfillset(&signal_set);
@@ -122,7 +192,7 @@ void SignalController::init()
#else
#error The signalhandler works only with pthreads
#endif
-
+
thread = new boost::thread(boost::bind(handle, this));
handler[SIGINT] = new SigIntHandler;
@@ -131,12 +201,24 @@ void SignalController::init()
handler[SIGTERM] = new SigTermHandler;
handler[SIGUSR1] = new SigUsr1Handler;
handler[SIGUSR2] = new SigUsr2Handler;
+#else
+ if(!SetConsoleCtrlHandler((PHANDLER_ROUTINE)SignalController::handle, true)) {
+ std::stringstream msg;
+ msg << "Error on SetConsoleCtrlhandler: " << LogErrno(GetLastError());
+ throw std::runtime_error(msg.str());
+ }
+
+ 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
}
int SignalController::run()
{
- while(1)
- {
+ while(1) {
sigQueueSem.down();
int sigNum;
{
@@ -157,3 +239,5 @@ int SignalController::run()
}
return 0;
}
+
+#endif \ No newline at end of file
diff --git a/src/signalController.h b/src/signalController.h
index d99e168..c893e15 100644
--- a/src/signalController.h
+++ b/src/signalController.h
@@ -32,12 +32,17 @@
#ifndef _SIGNAL_CONTROLLER_H_
#define _SIGNAL_CONTROLLER_H_
-#include <csignal>
+#ifndef NO_SIGNALCONTROLLER
+
#include <map>
#include <queue>
#include "threadUtils.hpp"
+#ifndef _MSC_VER
+#include <csignal>
+#endif
+
class SignalHandler
{
public:
@@ -53,6 +58,7 @@ private:
friend class SignalController;
};
+#ifndef _MSC_VER
class SigIntHandler : public SignalHandler
{
public:
@@ -95,12 +101,53 @@ public:
int handle();
};
+#else
+
+class CtrlCHandler : public SignalHandler
+{
+public:
+ CtrlCHandler() : SignalHandler(CTRL_C_EVENT) {}
+ int handle();
+};
+
+class CtrlBreakHandler : public SignalHandler
+{
+public:
+ CtrlBreakHandler() : SignalHandler(CTRL_BREAK_EVENT) {}
+ int handle();
+};
+
+class CtrlCloseHandler : public SignalHandler
+{
+public:
+ CtrlCloseHandler() : SignalHandler(CTRL_BREAK_EVENT) {}
+ int handle();
+};
+
+class CtrlLogoffHandler : public SignalHandler
+{
+public:
+ CtrlLogoffHandler() : SignalHandler(CTRL_BREAK_EVENT) {}
+ int handle();
+};
+
+class CtrlShutdownHandler : public SignalHandler
+{
+public:
+ CtrlShutdownHandler() : SignalHandler(CTRL_BREAK_EVENT) {}
+ int handle();
+};
+#endif
+
class SignalController
{
public:
- SignalController() { thread = NULL; }
- ~SignalController();
+ static SignalController& instance();
+#ifndef _MSC_VER
static void handle(void* s);
+#else
+ static bool handle(DWORD ctrlType);
+#endif
void init();
int run();
@@ -108,15 +155,37 @@ public:
private:
typedef std::map<int, SignalHandler*> HandlerMap;
+#ifndef _MSC_VER
+ SignalController() : thread(null) {};
+#else
+ SignalController() {};
+#endif
+ ~SignalController();
SignalController(const SignalController &s);
void operator=(const SignalController &s);
-
+
+ static SignalController* inst;
+ static Mutex instMutex;
+ class instanceCleaner {
+ public: ~instanceCleaner() {
+ if(SignalController::inst != NULL)
+ delete SignalController::inst;
+ }
+ };
+ friend class instanceCleaner;
+
std::queue<int> sigQueue;
Mutex sigQueueMutex;
Semaphore sigQueueSem;
+#ifdef _MSC_VER
boost::thread* thread;
+#endif
HandlerMap handler;
};
+extern SignalController& gSignalController;
+
+#endif
+
#endif
diff --git a/src/win32/winService.cpp b/src/win32/winService.cpp
index 78558de..fb20f8f 100644
--- a/src/win32/winService.cpp
+++ b/src/win32/winService.cpp
@@ -145,7 +145,8 @@ void WinService::waitForStop()
{
if(!started_)
throw std::runtime_error("Service not started correctly");
-
+
+ reportStatus(SERVICE_RUNNING, NO_ERROR);
WaitForSingleObject(stop_event_, INFINITE);
reportStatus(SERVICE_STOP_PENDING, NO_ERROR);
}
@@ -175,16 +176,15 @@ VOID WINAPI WinService::main(DWORD dwArgc, LPTSTR *lpszArgv)
gWinService.status_.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
gWinService.status_.dwServiceSpecificExitCode = 0;
gWinService.reportStatus(SERVICE_START_PENDING, NO_ERROR);
-
+ gWinService.started_ = true;
+
gWinService.stop_event_ = CreateEvent(NULL, true, false, NULL);
if(!gWinService.stop_event_) {
- cLog.msg(Log::PRIO_ERR) << "Error on CreateEvent: " << LogErrno(GetLastError());
+ cLog.msg(Log::PRIO_ERR) << "WinService Error on CreateEvent: " << LogErrno(GetLastError());
gWinService.reportStatus(SERVICE_STOPPED, -1);
return;
}
- gWinService.started_ = true;
- gWinService.reportStatus(SERVICE_RUNNING, NO_ERROR);
-
+
real_main(dwArgc, lpszArgv);
}