diff options
author | Christian Pointner <equinox@anytun.org> | 2009-02-22 06:16:10 +0000 |
---|---|---|
committer | Christian Pointner <equinox@anytun.org> | 2009-02-22 06:16:10 +0000 |
commit | 5c0eb60b509edf766e649d081d30ab8dea83a8f4 (patch) | |
tree | 7e7ffa3e6aaa42f65ea13ac3297890e64b66944b | |
parent | fixed build on Windows (after logging chances) (diff) |
added signal controller (console control handler) to windows
-rw-r--r-- | src/anytun-controld.cpp | 7 | ||||
-rw-r--r-- | src/anytun.cpp | 5 | ||||
-rw-r--r-- | src/anytun.suo | bin | 64000 -> 66048 bytes | |||
-rw-r--r-- | src/anytun.vcproj | 12 | ||||
-rw-r--r-- | src/signalController.cpp | 98 | ||||
-rw-r--r-- | src/signalController.h | 77 | ||||
-rw-r--r-- | src/win32/winService.cpp | 12 |
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 Binary files differindex 05fc354..2392b5f 100644 --- a/src/anytun.suo +++ b/src/anytun.suo 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 "C:\Program Files\boost\boost_1_35_0\""
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);
}
|