Ver Fonte

Merge pull request #11 from efficks/author

Latest update from the original depot
Kirill Kovalenko há 8 anos atrás
pai
commit
9b37719195
7 ficheiros alterados com 44 adições e 168 exclusões
  1. 2 0
      README.txt
  2. 0 148
      console.cpp
  3. 1 1
      gui.cpp
  4. 8 14
      io.cpp
  5. 21 1
      nssm.cpp
  6. 9 1
      nssm.vcproj
  7. 3 3
      service.cpp

+ 2 - 0
README.txt

@@ -1043,6 +1043,8 @@ Thanks to Nicolas Ducrocq for suggesting timestamping redirected output.
 Thanks to Meang Akira Tanaka for suggestion and initial implementation of
 Thanks to Meang Akira Tanaka for suggestion and initial implementation of
 the statuscode command.
 the statuscode command.
 Thanks to Kirill Kovalenko for reporting a crash with NANO server.
 Thanks to Kirill Kovalenko for reporting a crash with NANO server.
+Thanks to Connor Reynolds for spotting a potential buffer overflow.
+Thanks to foi for spotting a hang with 64 cores.
 
 
 Licence
 Licence
 -------
 -------

+ 0 - 148
console.cpp

@@ -21,156 +21,8 @@ bool check_console() {
   return false;
   return false;
 }
 }
 
 
-/* Helpers for drawing the banner. */
-static inline void block(unsigned int a, short x, short y, unsigned long n) {
-  HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
-  TCHAR s = _T(' ');
-
-  unsigned long out;
-  COORD c = { x, y };
-  FillConsoleOutputAttribute(h, a, n, c, &out);
-  FillConsoleOutputCharacter(h, s, n, c, &out);
-}
-
-static inline void R(short x, short y, unsigned long n) {
-  block(BACKGROUND_RED | BACKGROUND_INTENSITY, x, y, n);
-}
-
-static inline void r(short x, short y, unsigned long n) {
-  block(BACKGROUND_RED, x, y, n);
-}
-
-static inline void b(short x, short y, unsigned long n) {
-  block(0, x, y, n);
-}
-
 void alloc_console(nssm_service_t *service) {
 void alloc_console(nssm_service_t *service) {
   if (service->no_console) return;
   if (service->no_console) return;
 
 
   AllocConsole();
   AllocConsole();
-
-  /* Disable accidental closure. */
-  HWND window = GetConsoleWindow();
-  HMENU menu = GetSystemMenu(window, false);
-  EnableMenuItem(menu, SC_CLOSE, MF_GRAYED);
-
-  /* Set a title like "[NSSM] Jenkins" */
-  TCHAR displayname[SERVICE_NAME_LENGTH];
-  unsigned long len = _countof(displayname);
-  SC_HANDLE services = open_service_manager(SC_MANAGER_CONNECT);
-  if (services) {
-    if (! GetServiceDisplayName(services, service->name, displayname, &len)) ZeroMemory(displayname, sizeof(displayname));
-    CloseServiceHandle(services);
-  }
-  if (! displayname[0]) _sntprintf_s(displayname, _countof(displayname), _TRUNCATE, _T("%s"), service->name);
-
-  TCHAR title[65535];
-  _sntprintf_s(title, _countof(title), _TRUNCATE, _T("[%s] %s"), NSSM, displayname);
-  SetConsoleTitle(title);
-
-  /* Draw the NSSM logo on the console window. */
-  short y = 0;
-
-  b(0, y, 80);
-  y++;
-
-  b(0, y, 80);
-  y++;
-
-  b(0, y, 80);
-  y++;
-
-  b(0, y, 80);
-  y++;
-
-  b(0, y, 80);
-  r(18, y, 5); r(28, y, 4); r(41, y, 4); r(68, y, 1);
-  R(6, y, 5); R(19, y, 4); R(29, y, 1); R(32, y, 3); R(42, y, 1); R(45, y, 3); R(52, y, 5); R(69, y, 4);
-  y++;
-
-  b(0, y, 80);
-  r(8, y, 4); r(20, y, 1); r(28, y, 1); r(33, y, 3); r(41, y, 1); r(46, y, 3); r (57, y, 1);
-  R(9, y, 2); R(21, y, 1); R(27, y, 1); R(34, y, 1); R(40, y, 1); R(47, y, 1); R(54, y, 3); R(68, y, 3);
-  y++;
-
-  b(0, y, 80);
-  r(12, y, 1); r(20, y, 1); r(26, y, 1); r(34, y, 2); r(39, y, 1); r(47, y, 2); r(67, y, 2);
-  R(9, y, 3); R(21, y, 1); R(27, y, 1); R(40, y, 1); R(54, y, 1); R(56, y, 2); R(67, y, 1); R(69, y, 2);
-  y++;
-
-  b(0, y, 80);
-  r(9, y, 1); r(20, y, 1); r(26, y, 1); r (35, y, 1); r(39, y, 1); r(48, y, 1); r(58, y, 1);
-  R(10, y, 3); R(21, y, 1); R(27, y, 1); R(40, y, 1); R(54, y, 1); R(56, y, 2); R(67, y, 1); R(69, y, 2);
-  y++;
-
-  b(0, y, 80);
-  r(9, y, 1); r(56, y, 1); r(66, y, 2);
-  R(11, y, 3); R(21, y, 1); R(26, y, 2); R(39, y, 2); R(54, y, 1); R(57, y, 2); R(69, y, 2);
-  y++;
-
-  b(0, y, 80);
-  r(9, y, 1); r(26, y, 1); r(39, y, 1); r(59, y, 1);
-  R(12, y, 3); R(21, y, 1); R(27, y, 2); R(40, y, 2); R(54, y, 1); R(57, y, 2); R(66, y, 1); R(69, y, 2);
-  y++;
-
-  b(0, y, 80);
-  r(9, y, 1); r(12, y, 4); r(30, y, 1); r(43, y, 1); r(57, y, 1); r(65, y, 2);
-  R(13, y, 2); R(21, y, 1); R(27, y, 3); R(40, y, 3); R(54, y, 1); R(58, y, 2); R(69, y, 2);
-  y++;
-
-  b(0, y, 80);
-  r(9, y, 1); r(13, y, 4); r(27, y, 7); r(40, y, 7);
-  R(14, y, 2); R(21, y, 1); R(28, y, 5); R(41, y, 5); R(54, y, 1); R(58, y, 2); R(65, y, 1); R(69, y, 2);
-  y++;
-
-  b(0, y, 80);
-  r(9, y, 1); r(60, y, 1); r(65, y, 1);
-  R(14, y, 3); R(21, y, 1); R(29, y, 6); R(42, y, 6); R(54, y, 1); R(58, y, 2); R(69, y, 2);
-  y++;
-
-  b(0, y, 80);
-  r(9, y, 1); r(31, y, 1); r(44, y, 1); r(58, y, 1); r(64, y, 1);
-  R(15, y, 3); R(21, y, 1); R(32, y, 4); R(45, y, 4); R(54, y, 1); R(59, y, 2); R(69, y, 2);
-  y++;
-
-  b(0, y, 80);
-  r(9, y, 1); r(33, y, 1); r(46, y, 1); r(61, y, 1); r(64, y, 1);
-  R(16, y, 3); R(21, y, 1); R(34, y, 2); R(47, y, 2); R(54, y, 1); R(59, y, 2); R(69, y, 2);
-  y++;
-
-  b(0, y, 80);
-  r(9, y, 1); r(16, y, 4); r(36, y, 1); r(49, y, 1); r(59, y, 1); r(63, y, 1);
-  R(17, y, 2); R(21, y, 1); R(34, y, 2); R(47, y, 2); R(54, y, 1); R(60, y, 2); R(69, y, 2);
-  y++;
-
-  b(0, y, 80);
-  r(9, y, 1); r(17, y, 4); r(26, y, 1); r(36, y, 1); r(39, y, 1); r(49, y, 1);
-  R(18, y, 2); R(21, y, 1); R(35, y, 1); R(48, y, 1); R(54, y, 1); R(60, y, 2); R(63, y, 1); R(69, y, 2);
-  y++;
-
-  b(0, y, 80);
-  r(26, y, 2); r(39, y, 2); r(63, y, 1);
-  R(9, y, 1); R(18, y, 4); R(35, y, 1); R(48, y, 1); R(54, y, 1); R(60, y, 3); R(69, y, 2);
-  y++;
-
-  b(0, y, 80);
-  r(34, y, 1); r(47, y, 1); r(60, y, 1);
-  R(9, y, 1); R(19, y, 3); R(26, y, 2); R(35, y, 1); R(39, y, 2); R(48, y, 1); R(54, y, 1); R(61, y, 2); R(69, y, 2);
-  y++;
-
-  b(0, y, 80);
-  r(8, y, 1); r(35, y, 1); r(48, y, 1); r(62, y, 1); r(71, y, 1);
-  R(9, y, 1); R(20, y, 2); R(26, y, 3); R(34, y, 1); R(39, y, 3); R(47, y, 1); R(54, y, 1); R(61, y, 1); R(69, y, 2);
-  y++;
-
-  b(0, y, 80);
-  r(11, y, 1); r(26, y, 1); r(28, y, 5); r(39, y, 1); r(41, y, 5); r(51, y, 7); r(61, y, 1); r(66, y, 8);
-  R(7, y, 4); R(21, y, 1); R(29, y, 1); R(33, y, 1); R(42, y, 1); R(46, y, 1); R(52, y, 5); R(67, y, 7);
-  y++;
-
-  b(0, y, 80);
-  y++;
-
-  b(0, y, 80);
-  y++;
 }
 }

+ 1 - 1
gui.cpp

@@ -924,7 +924,7 @@ void browse(HWND window, TCHAR *current, unsigned long flags, ...) {
     va_start(arg, flags);
     va_start(arg, flags);
     while (i = va_arg(arg, int)) {
     while (i = va_arg(arg, int)) {
       TCHAR *localised = message_string(i);
       TCHAR *localised = message_string(i);
-      _sntprintf_s((TCHAR *) ofn.lpstrFilter + len, bufsize, _TRUNCATE, localised);
+      _sntprintf_s((TCHAR *) ofn.lpstrFilter + len, bufsize - len, _TRUNCATE, localised);
       len += _tcslen(localised) + 1;
       len += _tcslen(localised) + 1;
       LocalFree(localised);
       LocalFree(localised);
       TCHAR *filter = browse_filter(i);
       TCHAR *filter = browse_filter(i);

+ 8 - 14
io.cpp

@@ -305,6 +305,7 @@ void rotate_file(TCHAR *service_name, TCHAR *path, unsigned long seconds, unsign
 
 
 int get_output_handles(nssm_service_t *service, STARTUPINFO *si) {
 int get_output_handles(nssm_service_t *service, STARTUPINFO *si) {
   if (! si) return 1;
   if (! si) return 1;
+  bool inherit_handles = false;
 
 
   /* Allocate a new console so we get a fresh stdin, stdout and stderr. */
   /* Allocate a new console so we get a fresh stdin, stdout and stderr. */
   alloc_console(service);
   alloc_console(service);
@@ -316,6 +317,8 @@ int get_output_handles(nssm_service_t *service, STARTUPINFO *si) {
       log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_CREATEFILE_FAILED, service->stdin_path, error_string(GetLastError()), 0);
       log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_CREATEFILE_FAILED, service->stdin_path, error_string(GetLastError()), 0);
       return 2;
       return 2;
     }
     }
+
+    inherit_handles = true;

   }
   }
 
 
   /* stdout */
   /* stdout */
@@ -341,6 +344,8 @@ int get_output_handles(nssm_service_t *service, STARTUPINFO *si) {
     }
     }
 
 
     if (dup_handle(service->stdout_si, &si->hStdOutput, _T("stdout_si"), _T("stdout"))) close_handle(&service->stdout_thread);
     if (dup_handle(service->stdout_si, &si->hStdOutput, _T("stdout_si"), _T("stdout"))) close_handle(&service->stdout_thread);
+
+    inherit_handles = true;

   }
   }
 
 
   /* stderr */
   /* stderr */
@@ -379,26 +384,15 @@ int get_output_handles(nssm_service_t *service, STARTUPINFO *si) {
     }
     }
 
 
     if (dup_handle(service->stderr_si, &si->hStdError, _T("stderr_si"), _T("stderr"))) close_handle(&service->stderr_thread);
     if (dup_handle(service->stderr_si, &si->hStdError, _T("stderr_si"), _T("stderr"))) close_handle(&service->stderr_thread);
+
+    inherit_handles = true;

   }
   }
 
 
   /*
   /*
     We need to set the startup_info flags to make the new handles
     We need to set the startup_info flags to make the new handles
     inheritable by the new process.
     inheritable by the new process.
   */
   */
-  si->dwFlags |= STARTF_USESTDHANDLES;
-
-  if (service->no_console) return 0;
-
-  /* Redirect other handles. */
-  if (! si->hStdInput) {
-    if (dup_handle(GetStdHandle(STD_INPUT_HANDLE), &si->hStdInput, _T("STD_INPUT_HANDLE"), _T("stdin"))) return 8;
-  }
-  if (! si->hStdOutput) {
-    if (dup_handle(GetStdHandle(STD_OUTPUT_HANDLE), &si->hStdOutput, _T("STD_OUTPUT_HANDLE"), _T("stdout"))) return 9;
-  }
-  if (! si->hStdError)  {
-    if (dup_handle(GetStdHandle(STD_ERROR_HANDLE), &si->hStdError, _T("STD_ERROR_HANDLE"), _T("stderr"))) return 10;
-  }
+  if (inherit_handles) si->dwFlags |= STARTF_USESTDHANDLES;
 
 
   return 0;
   return 0;
 }
 }

+ 21 - 1
nssm.cpp

@@ -32,6 +32,21 @@ int str_number(const TCHAR *string, unsigned long *number, TCHAR **bogus) {
   return 0;
   return 0;
 }
 }
 
 
+/* User requested us to print our version. */
+static bool is_version(const TCHAR *s) {
+  if (! s || ! *s) return false;
+  /* /version */
+  if (*s == '/') s++;
+  else if (*s == '-') {
+    /* -v, -V, -version, --version */
+    s++;
+    if (*s == '-') s++;
+    else if (str_equiv(s, _T("v"))) return true;
+  }
+  if (str_equiv(s, _T("version"))) return true;
+  return false;
+}
+
 int str_number(const TCHAR *string, unsigned long *number) {
 int str_number(const TCHAR *string, unsigned long *number) {
   TCHAR *bogus;
   TCHAR *bogus;
   return str_number(string, number, &bogus);
   return str_number(string, number, &bogus);
@@ -208,7 +223,7 @@ static int elevate(int argc, TCHAR **argv, unsigned long message) {
 int num_cpus() {
 int num_cpus() {
   DWORD_PTR i, affinity, system_affinity;
   DWORD_PTR i, affinity, system_affinity;
   if (! GetProcessAffinityMask(GetCurrentProcess(), &affinity, &system_affinity)) return 64;
   if (! GetProcessAffinityMask(GetCurrentProcess(), &affinity, &system_affinity)) return 64;
-  for (i = 0; system_affinity & (1LL << i); i++);
+  for (i = 0; system_affinity & (1LL << i); i++) if (i == 64) break;
   return (int) i;
   return (int) i;
 }
 }
 
 
@@ -245,7 +260,12 @@ int _tmain(int argc, TCHAR **argv) {
     /*
     /*
       Valid commands are:
       Valid commands are:
       start, stop, pause, continue, install, edit, get, set, reset, unset, remove
       start, stop, pause, continue, install, edit, get, set, reset, unset, remove
+      status, statuscode, rotate, list, processes, version
     */
     */
+    if (is_version(argv[1])) {
+      _tprintf(_T("%s %s %s %s\n"), NSSM, NSSM_VERSION, NSSM_CONFIGURATION, NSSM_DATE);
+      nssm_exit(0);
+    }
     if (str_equiv(argv[1], _T("start"))) nssm_exit(control_service(NSSM_SERVICE_CONTROL_START, argc - 2, argv + 2));
     if (str_equiv(argv[1], _T("start"))) nssm_exit(control_service(NSSM_SERVICE_CONTROL_START, argc - 2, argv + 2));
     if (str_equiv(argv[1], _T("stop"))) nssm_exit(control_service(SERVICE_CONTROL_STOP, argc - 2, argv + 2));
     if (str_equiv(argv[1], _T("stop"))) nssm_exit(control_service(SERVICE_CONTROL_STOP, argc - 2, argv + 2));
     if (str_equiv(argv[1], _T("restart"))) {
     if (str_equiv(argv[1], _T("restart"))) {

+ 9 - 1
nssm.vcproj

@@ -63,7 +63,7 @@
 				ProgramDataBaseFileName="$(IntDir)/"
 				ProgramDataBaseFileName="$(IntDir)/"
 				WarningLevel="3"
 				WarningLevel="3"
 				SuppressStartupBanner="true"
 				SuppressStartupBanner="true"
-				DebugInformationFormat="4"
+				DebugInformationFormat="3"
 			/>
 			/>
 			<Tool
 			<Tool
 				Name="VCManagedResourceCompilerTool"
 				Name="VCManagedResourceCompilerTool"
@@ -253,6 +253,7 @@
 				ProgramDataBaseFileName="$(IntDir)/"
 				ProgramDataBaseFileName="$(IntDir)/"
 				WarningLevel="3"
 				WarningLevel="3"
 				SuppressStartupBanner="true"
 				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
 			/>
 			/>
 			<Tool
 			<Tool
 				Name="VCManagedResourceCompilerTool"
 				Name="VCManagedResourceCompilerTool"
@@ -270,8 +271,11 @@
 				AdditionalDependencies="psapi.lib shlwapi.lib"
 				AdditionalDependencies="psapi.lib shlwapi.lib"
 				LinkIncremental="1"
 				LinkIncremental="1"
 				SuppressStartupBanner="true"
 				SuppressStartupBanner="true"
+				GenerateDebugInformation="true"
 				ProgramDatabaseFile="$(OutDir)/$(ProjectName).pdb"
 				ProgramDatabaseFile="$(OutDir)/$(ProjectName).pdb"
 				SubSystem="1"
 				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
 				RandomizedBaseAddress="1"
 				RandomizedBaseAddress="1"
 				DataExecutionPrevention="0"
 				DataExecutionPrevention="0"
 				TargetMachine="1"
 				TargetMachine="1"
@@ -347,6 +351,7 @@
 				ProgramDataBaseFileName="$(IntDir)/"
 				ProgramDataBaseFileName="$(IntDir)/"
 				WarningLevel="3"
 				WarningLevel="3"
 				SuppressStartupBanner="true"
 				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
 			/>
 			/>
 			<Tool
 			<Tool
 				Name="VCManagedResourceCompilerTool"
 				Name="VCManagedResourceCompilerTool"
@@ -364,8 +369,11 @@
 				AdditionalDependencies="psapi.lib shlwapi.lib"
 				AdditionalDependencies="psapi.lib shlwapi.lib"
 				LinkIncremental="1"
 				LinkIncremental="1"
 				SuppressStartupBanner="true"
 				SuppressStartupBanner="true"
+				GenerateDebugInformation="true"
 				ProgramDatabaseFile="$(OutDir)/$(ProjectName).pdb"
 				ProgramDatabaseFile="$(OutDir)/$(ProjectName).pdb"
 				SubSystem="1"
 				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
 				RandomizedBaseAddress="1"
 				RandomizedBaseAddress="1"
 				DataExecutionPrevention="0"
 				DataExecutionPrevention="0"
 				TargetMachine="17"
 				TargetMachine="17"

+ 3 - 3
service.cpp

@@ -1875,11 +1875,12 @@ int start_service(nssm_service_t *service) {
     /* Set up I/O redirection. */
     /* Set up I/O redirection. */
     if (get_output_handles(service, &si)) {
     if (get_output_handles(service, &si)) {
       log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_GET_OUTPUT_HANDLES_FAILED, service->name, 0);
       log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_GET_OUTPUT_HANDLES_FAILED, service->name, 0);
-      if (! service->no_console) FreeConsole();
+      FreeConsole();
       close_output_handles(&si);
       close_output_handles(&si);
       unset_service_environment(service);
       unset_service_environment(service);
       return stop_service(service, 4, true, true);
       return stop_service(service, 4, true, true);
     }
     }
+    FreeConsole();
 
 
     /* Pre-start hook. May need I/O to have been redirected already. */
     /* Pre-start hook. May need I/O to have been redirected already. */
     if (nssm_hook(&hook_threads, service, NSSM_HOOK_EVENT_START, NSSM_HOOK_ACTION_PRE, &control, NSSM_SERVICE_STATUS_DEADLINE, false) == NSSM_HOOK_STATUS_ABORT) {
     if (nssm_hook(&hook_threads, service, NSSM_HOOK_EVENT_START, NSSM_HOOK_ACTION_PRE, &control, NSSM_SERVICE_STATUS_DEADLINE, false) == NSSM_HOOK_STATUS_ABORT) {
@@ -1897,6 +1898,7 @@ int start_service(nssm_service_t *service) {
     if (si.dwFlags & STARTF_USESTDHANDLES) inherit_handles = true;
     if (si.dwFlags & STARTF_USESTDHANDLES) inherit_handles = true;
     unsigned long flags = service->priority & priority_mask();
     unsigned long flags = service->priority & priority_mask();
     if (service->affinity) flags |= CREATE_SUSPENDED;
     if (service->affinity) flags |= CREATE_SUSPENDED;
+    if (! service->no_console) flags |= CREATE_NEW_CONSOLE;

     if (! CreateProcess(0, cmd, 0, 0, inherit_handles, flags, 0, service->dir, &si, &pi)) {
     if (! CreateProcess(0, cmd, 0, 0, inherit_handles, flags, 0, service->dir, &si, &pi)) {
       unsigned long exitcode = 3;
       unsigned long exitcode = 3;
       unsigned long error = GetLastError();
       unsigned long error = GetLastError();
@@ -1913,8 +1915,6 @@ int start_service(nssm_service_t *service) {
 
 
     close_output_handles(&si);
     close_output_handles(&si);
 
 
-    if (! service->no_console) FreeConsole();
-
     if (service->affinity) {
     if (service->affinity) {
       /*
       /*
         We are explicitly storing service->affinity as a 64-bit unsigned integer
         We are explicitly storing service->affinity as a 64-bit unsigned integer