Thanks to Bryan Senseman for noticing that applications with redirected stdout\r
and/or stderr which attempt to read from stdin would fail.\r
Thanks to Czenda Czendov for help with Visual Studio 2013 and Server 2012R2.\r
+Thanks to Alessandro Gherardi for reporting and draft fix of the bug whereby\r
+the second restart of the application would have a corrupted environment.\r
\r
Licence\r
-------\r
#include "nssm.h"
+/* Copy an environment block. */
+TCHAR *copy_environment_block(TCHAR *env) {
+ unsigned long len;
+
+ if (! env) return 0;
+ for (len = 0; env[len]; len++) while (env[len]) len++;
+ if (! len++) return 0;
+
+ TCHAR *newenv = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, len * sizeof(TCHAR));
+ if (! newenv) {
+ log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OUT_OF_MEMORY, _T("environment"), _T("copy_environment_block()"), 0);
+ return 0;
+ }
+
+ memmove(newenv, env, len * sizeof(TCHAR));
+ return newenv;
+}
+
/*
The environment block starts with variables of the form
=C:=C:\Windows\System32 which we ignore.
return 0;
}
+
+/*
+ Duplicate an environment block returned by GetEnvironmentStrings().
+ Since such a block is by definition readonly, and duplicate_environment()
+ modifies its inputs, this function takes a copy of the input and operates
+ on that.
+*/
+void duplicate_environment_strings(TCHAR *env) {
+ TCHAR *newenv = copy_environment_block(env);
+ if (! newenv) return;
+
+ duplicate_environment(newenv);
+ HeapFree(GetProcessHeap(), 0, newenv);
+}
#ifndef ENV_H
#define ENV_H
+TCHAR *copy_environment_block(TCHAR *);
TCHAR *useful_environment(TCHAR *);
TCHAR *expand_environment_string(TCHAR *);
int set_environment_block(TCHAR *);
int clear_environment();
int duplicate_environment(TCHAR *);
int test_environment(TCHAR *);
+void duplicate_environment_strings(TCHAR *);
#endif
unsigned long error = GetLastError();\r
log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_CREATEPROCESS_FAILED, service->name, service->exe, error_string(error), 0);\r
close_output_handles(&si);\r
- duplicate_environment(service->initial_env);\r
+ duplicate_environment_strings(service->initial_env);\r
return stop_service(service, exitcode, true, true);\r
}\r
service->process_handle = pi.hProcess;\r
if (! service->no_console) FreeConsole();\r
\r
/* Restore our environment. */\r
- duplicate_environment(service->initial_env);\r
+ duplicate_environment_strings(service->initial_env);\r
\r
if (service->affinity) {\r
/*\r