From 6b55e7827d7a54ba5c83b04fbbf4323e4cc8cc8c Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Mon, 21 Apr 2014 20:15:03 +0200 Subject: [PATCH] Implement support for environment variables on Windows. Fixes #6049 --- lib/base/process.cpp | 56 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/lib/base/process.cpp b/lib/base/process.cpp index e240be0f1..c1c654d80 100644 --- a/lib/base/process.cpp +++ b/lib/base/process.cpp @@ -306,16 +306,70 @@ void Process::Run(const boost::function& callback) strncpy(args, m_Arguments.CStr(), m_Arguments.GetLength() + 1); args[m_Arguments.GetLength()] = '\0'; - if (!CreateProcess(NULL, args, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) { + LPCH pEnvironment = GetEnvironmentStrings(); + size_t ioffset = 0, offset = 0; + + char *envp = NULL; + + for (;;) { + size_t len = strlen(pEnvironment + ioffset); + + if (len == 0) + break; + + char *eqp = strchr(pEnvironment + ioffset, '='); + if (eqp && m_ExtraEnvironment && m_ExtraEnvironment->Contains(String(pEnvironment + ioffset, eqp))) { + ioffset += len + 1; + continue; + } + + envp = static_cast(realloc(envp, offset + len + 1)); + + if (envp == NULL) + BOOST_THROW_EXCEPTION(std::bad_alloc()); + + strcpy(envp + offset, pEnvironment + ioffset); + offset += len + 1; + ioffset += len + 1; + } + + FreeEnvironmentStrings(pEnvironment); + + if (m_ExtraEnvironment) { + ObjectLock olock(m_ExtraEnvironment); + + BOOST_FOREACH(const Dictionary::Pair& kv, m_ExtraEnvironment) { + String skv = kv.first + "=" + Convert::ToString(kv.second); + + envp = static_cast(realloc(envp, offset + skv.GetLength() + 1)); + + if (envp == NULL) + BOOST_THROW_EXCEPTION(std::bad_alloc()); + + strcpy(envp + offset, skv.CStr()); + offset += skv.GetLength() + 1; + } + } + + envp = static_cast(realloc(envp, offset + 1)); + + if (envp == NULL) + BOOST_THROW_EXCEPTION(std::bad_alloc()); + + envp[offset] = '\0'; + + if (!CreateProcess(NULL, args, NULL, NULL, TRUE, 0, envp, NULL, &si, &pi)) { CloseHandle(outWritePipe); CloseHandle(outWritePipeDup); delete args; + free(envp); BOOST_THROW_EXCEPTION(win32_error() << boost::errinfo_api_function("CreateProcess") << errinfo_win32_error(GetLastError())); } delete args; + free(envp); CloseHandle(outWritePipe); CloseHandle(outWritePipeDup); -- 2.40.0