You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by jo...@apache.org on 2016/08/27 01:20:03 UTC
[4/6] mesos git commit: Windows: Corrected subprocess environment
variables.
Windows: Corrected subprocess environment variables.
Windows processes have a minimum set of environment variables required
to load prerequisites, such as shared libraries. These environment
variables are generally found in the system's environment.
Review: https://reviews.apache.org/r/51233/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/9d378635
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/9d378635
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/9d378635
Branch: refs/heads/master
Commit: 9d3786353b4a4c357f9196d9659bac4582dd0176
Parents: ec30c1f
Author: Daniel Pravat <dp...@outlook.com>
Authored: Fri Aug 26 17:23:22 2016 -0700
Committer: Joseph Wu <jo...@apache.org>
Committed: Fri Aug 26 18:19:03 2016 -0700
----------------------------------------------------------------------
.../include/process/windows/subprocess.hpp | 70 +++++++++++++++++++-
1 file changed, 69 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/9d378635/3rdparty/libprocess/include/process/windows/subprocess.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/windows/subprocess.hpp b/3rdparty/libprocess/include/process/windows/subprocess.hpp
index 6bb54c8..f452f67 100644
--- a/3rdparty/libprocess/include/process/windows/subprocess.hpp
+++ b/3rdparty/libprocess/include/process/windows/subprocess.hpp
@@ -30,6 +30,8 @@
#include <stout/os/close.hpp>
#include <stout/os/environment.hpp>
+#include <userEnv.h>
+
using std::map;
using std::string;
using std::vector;
@@ -62,6 +64,56 @@ inline void close(
}
}
+// Retrieves system environment in a `std::map`, ignoring
+// the current process's environment variables.
+inline Option<map<string, string>> getSystemEnvironment()
+{
+ std::wstring_convert<std::codecvt<wchar_t, char, mbstate_t>,
+ wchar_t> converter;
+
+ map<string, string> systemEnvironment;
+ wchar_t* environmentEntry = nullptr;
+
+ // Get the system environment.
+ // The third parameter (bool) tells the function *not* to inherit
+ // variables from the current process.
+ if (!CreateEnvironmentBlock((LPVOID*)&environmentEntry, nullptr, FALSE)) {
+ return None();
+ }
+
+ // Save the environment block in order to destroy it later.
+ wchar_t* environmentBlock = environmentEntry;
+
+ while (*environmentEntry != L'\0') {
+ // Each environment block contains the environment variables as follows:
+ // Var1=Value1\0
+ // Var2=Value2\0
+ // Var3=Value3\0
+ // ...
+ // VarN=ValueN\0\0
+ // The name of an environment variable cannot include an equal sign (=).
+
+ wchar_t * separator = wcschr(environmentEntry, L'=');
+ std::wstring varName = std::wstring(environmentEntry, separator);
+ std::wstring varVal = std::wstring(separator + 1);
+
+ // Mesos variables are upper case. Convert system variables to
+ // match the name provided by the scheduler in case of a collision.
+ std::transform(varName.begin(), varName.end(), varName.begin(), ::towupper);
+
+ // The system environment has priority. Force `ANSI` usage until the code
+ // is converted to UNICODE.
+ systemEnvironment.insert_or_assign(
+ converter.to_bytes(varName.c_str()),
+ converter.to_bytes(varVal.c_str()));
+
+ environmentEntry += varName.length() + varVal.length() + 2;
+ }
+
+ DestroyEnvironmentBlock(environmentBlock);
+
+ return systemEnvironment;
+}
// Creates a null-terminated array of null-terminated strings that will be
// passed to `CreateProcess` as the `lpEnvironment` argument, as described by
@@ -70,6 +122,10 @@ inline void close(
// environments, so it should not be used in conjunction with the
// `CREATE_UNICODE_ENVIRONMENT` flag.
//
+// NOTE: This function will add the system's environment variables into
+// the returned string. These variables take precedence over the provided
+// `env` and are generally necessary in order to launch things on Windows.
+//
// [1] https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx
inline Option<string> createProcessEnvironment(
const Option<map<string, string>>& env)
@@ -78,8 +134,20 @@ inline Option<string> createProcessEnvironment(
return None();
}
+ Option<map<string, string>> systemEnvironment = getSystemEnvironment();
+
+ // The system environment must be non-empty.
+ // No subprocesses will be able to launch if the system environment is blank.
+ CHECK(systemEnvironment.isSome() && systemEnvironment.get().size() > 0);
+
+ map<string, string> combinedEnvironment = env.get();
+
+ foreachpair(const string& key, const string& value, systemEnvironment.get()) {
+ combinedEnvironment[key] = value;
+ }
+
string environmentString;
- foreachpair (const string& key, const string& value, env.get()) {
+ foreachpair (const string& key, const string& value, combinedEnvironment) {
environmentString += key + '=' + value + '\0';
}