Shutdown cleanly when receiving a Windows console shutdown request.
authorEtienne Dechamps <etienne@edechamps.fr>
Sat, 12 Jul 2014 16:47:01 +0000 (17:47 +0100)
committerEtienne Dechamps <etienne@edechamps.fr>
Sat, 12 Jul 2014 16:47:01 +0000 (17:47 +0100)
This commit makes tinc exit cleanly on Windows when hitting CTRL+C at
the console or when the user logs off. This change has no effect when
running tinc as a service.

src/process.c
src/process.h
src/tincd.c

index 9f99a94..6135efb 100644 (file)
@@ -109,7 +109,7 @@ static bool install_service(void) {
        return true;
 }
 
-static io_t stop_io;
+io_t stop_io;
 
 DWORD WINAPI controlhandler(DWORD request, DWORD type, LPVOID boe, LPVOID bah) {
        switch(request) {
@@ -135,17 +135,9 @@ DWORD WINAPI controlhandler(DWORD request, DWORD type, LPVOID boe, LPVOID bah) {
        return NO_ERROR;
 }
 
-static void stop_handler(void *data, int flags) {
-       event_exit();
-}
-
 VOID WINAPI run_service(DWORD argc, LPTSTR* argv) {
        extern int main2(int argc, char **argv);
 
-       io_add_event(&stop_io, stop_handler, NULL, WSACreateEvent());
-       if (stop_io.event == FALSE)
-               abort();
-
        status.dwServiceType = SERVICE_WIN32;
        status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
        status.dwWin32ExitCode = 0;
@@ -172,9 +164,6 @@ VOID WINAPI run_service(DWORD argc, LPTSTR* argv) {
                SetServiceStatus(statushandle, &status);
        }
 
-       if (WSACloseEvent(stop_io.event) == FALSE)
-               abort();
-       io_del(&stop_io);
        return;
 }
 
index 4cdf711..ce2daed 100644 (file)
@@ -29,6 +29,7 @@ extern bool detach(void);
 extern bool kill_other(int);
 
 #ifdef HAVE_MINGW
+extern io_t stop_io;
 extern bool init_service(void);
 #endif
 
index 9f83a3c..748fe13 100644 (file)
@@ -49,6 +49,7 @@
 #include "control.h"
 #include "crypto.h"
 #include "device.h"
+#include "event.h"
 #include "logger.h"
 #include "names.h"
 #include "net.h"
@@ -303,6 +304,17 @@ static bool drop_privs(void) {
 
 #ifdef HAVE_MINGW
 # define setpriority(level) !SetPriorityClass(GetCurrentProcess(), (level))
+
+static void stop_handler(void *data, int flags) {
+       event_exit();
+}
+
+static BOOL WINAPI console_ctrl_handler(DWORD type) {
+       logger(DEBUG_ALWAYS, LOG_NOTICE, "Got console shutdown request");
+       if (WSASetEvent(stop_io.event) == FALSE)
+               abort();
+       return TRUE;
+}
 #else
 # define NORMAL_PRIORITY_CLASS 0
 # define BELOW_NORMAL_PRIORITY_CLASS 10
@@ -371,10 +383,21 @@ int main(int argc, char **argv) {
 #endif
 
 #ifdef HAVE_MINGW
-       if(!do_detach || !init_service())
-               return main2(argc, argv);
-       else
-               return 1;
+       io_add_event(&stop_io, stop_handler, NULL, WSACreateEvent());
+       if (stop_io.event == FALSE)
+               abort();
+
+       int result;
+       if(!do_detach || !init_service()) {
+               SetConsoleCtrlHandler(console_ctrl_handler, TRUE);
+               result = main2(argc, argv);
+       } else
+               result = 1;
+
+       if (WSACloseEvent(stop_io.event) == FALSE)
+               abort();
+       io_del(&stop_io);
+       return result;
 }
 
 int main2(int argc, char **argv) {