HANDLES(ENV_1a, "FailFast", ves_icall_System_Environment_FailFast, void, 3, (MonoString, MonoException, MonoString))
HANDLES(ENV_2, "GetCommandLineArgs", ves_icall_System_Environment_GetCommandLineArgs, MonoArray, 0, ())
HANDLES(ENV_3, "GetEnvironmentVariableNames", ves_icall_System_Environment_GetEnvironmentVariableNames, MonoArray, 0, ())
-HANDLES(ENV_8, "InternalSetEnvironmentVariable", ves_icall_System_Environment_InternalSetEnvironmentVariable, void, 4, (const_gunichar2_ptr, gint32, const_gunichar2_ptr, gint32))
NOHANDLES(ICALL(ENV_9, "get_ExitCode", mono_environment_exitcode_get))
NOHANDLES(ICALL(ENV_10, "get_HasShutdownStarted", ves_icall_System_Environment_get_HasShutdownStarted))
HANDLES(ENV_11, "get_MachineName", ves_icall_System_Environment_get_MachineName, MonoString, 0, ())
// See the LICENSE file in the project root for more information.
using System.Collections;
-using System.Globalization;
+using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading;
{
partial class Environment
{
+ private static Dictionary<string, string> s_environment;
+
static string GetEnvironmentVariableCore (string variable)
{
- using (var h = RuntimeMarshal.MarshalString (variable)) {
- return internalGetEnvironmentVariable_native (h.Value);
+ Debug.Assert(variable != null);
+
+ if (s_environment == null) {
+ using (var h = RuntimeMarshal.MarshalString (variable)) {
+ return internalGetEnvironmentVariable_native (h.Value);
+ }
+ }
+
+ variable = TrimStringOnFirstZero (variable);
+ lock (s_environment) {
+ s_environment.TryGetValue (variable, out string value);
+ return value;
}
}
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- extern static string internalGetEnvironmentVariable_native (IntPtr variable);
+ static unsafe void SetEnvironmentVariableCore (string variable, string? value)
+ {
+ Debug.Assert(variable != null);
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- private extern static string [] GetEnvironmentVariableNames ();
+ EnsureEnvironmentCached ();
+ lock (s_environment) {
+ variable = TrimStringOnFirstZero (variable);
+ value = value == null ? null : TrimStringOnFirstZero (value);
+ if (string.IsNullOrEmpty (value)) {
+ s_environment.Remove (variable);
+ } else {
+ s_environment[variable] = value;
+ }
+ }
+ }
public static IDictionary GetEnvironmentVariables ()
{
- Hashtable vars = new Hashtable ();
- foreach (string name in GetEnvironmentVariableNames ()) {
- vars [name] = GetEnvironmentVariableCore (name);
+ var results = new Hashtable();
+
+ EnsureEnvironmentCached();
+ lock (s_environment) {
+ foreach (var keyValuePair in s_environment) {
+ results.Add(keyValuePair.Key, keyValuePair.Value);
+ }
}
- return vars;
+
+ return results;
}
- static unsafe void SetEnvironmentVariableCore (string variable, string value)
+ private static string TrimStringOnFirstZero (string value)
{
- fixed (char *fixed_variable = variable)
- fixed (char *fixed_value = value)
- InternalSetEnvironmentVariable (fixed_variable, variable.Length, fixed_value, value?.Length ?? 0);
+ int index = value.IndexOf ('\0');
+ if (index >= 0) {
+ return value.Substring (0, index);
+ }
+ return value;
}
+ private static void EnsureEnvironmentCached ()
+ {
+ if (s_environment == null) {
+ Interlocked.CompareExchange (ref s_environment, GetSystemEnvironmentVariables (), null);
+ }
+ }
+
+ private static Dictionary<string, string> GetSystemEnvironmentVariables ()
+ {
+ var results = new Dictionary<string, string>();
+
+ foreach (string name in GetEnvironmentVariableNames ()) {
+ if (name != null) {
+ using (var h = RuntimeMarshal.MarshalString (name)) {
+ results.Add (name, internalGetEnvironmentVariable_native (h.Value));
+ }
+ }
+ }
+
+ return results;
+ }
+
+
[MethodImplAttribute (MethodImplOptions.InternalCall)]
- static extern unsafe void InternalSetEnvironmentVariable (char *variable, int variable_length, char *value, int value_length);
+ extern static string internalGetEnvironmentVariable_native (IntPtr variable);
+
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ private extern static string [] GetEnvironmentVariableNames ();
}
}