Fixed Control-C race.
authorIain Patterson <me@iain.cx>
Mon, 28 Oct 2013 20:51:56 +0000 (20:51 +0000)
committerIain Patterson <me@iain.cx>
Mon, 28 Oct 2013 20:51:56 +0000 (20:51 +0000)
A typo in kill_console() could cause the application to be restarted
when it was supposed to stop.

When kill_console() successfully generated a Control-C event and the
application exited, the function was supposed to return 0, indicating to
its parent function kill_process() that the application had been killed.

Due to a mistake in the test of WaitForSingleObject()'s return code,
kill_console() would instead return non-zero when the application exited
in response to Control-C.  This would lead NSSM to continue with other
methods of trying to kill the application, leading to a race when
another thread detected that the application had exited without
recognising that it had done so in response to a stop control.

Thanks Barrett Lewis.

process.cpp

index b55da50..67bc978 100644 (file)
@@ -204,7 +204,7 @@ int kill_console(char *service_name, HANDLE process_handle, unsigned long pid) {
     ret = 4;
   }
 
-  /* Sent the event. */
+  /* Send the event. */
   if (! ret) {
     if (! GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0)) {
       log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_GENERATECONSOLECTRLEVENT_FAILED, service_name, error_string(GetLastError()), 0);
@@ -218,7 +218,7 @@ int kill_console(char *service_name, HANDLE process_handle, unsigned long pid) {
   }
 
   /* Wait for process to exit. */
-  if (WaitForSingleObject(process_handle, NSSM_KILL_CONSOLE_GRACE_PERIOD)) return 6;
+  if (WaitForSingleObject(process_handle, NSSM_KILL_CONSOLE_GRACE_PERIOD)) return 6;
 
   return ret;
 }