diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
index 983a30c2ebde4..0ad4501a9980c 100644
--- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
+++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
@@ -1790,7 +1790,7 @@
-
+
@@ -1818,8 +1818,11 @@
+
+
+
-
+
diff --git a/src/libraries/System.Private.CoreLib/src/System/Environment.Browser.cs b/src/libraries/System.Private.CoreLib/src/System/Environment.Browser.cs
new file mode 100644
index 0000000000000..9ef90da4762d6
--- /dev/null
+++ b/src/libraries/System.Private.CoreLib/src/System/Environment.Browser.cs
@@ -0,0 +1,26 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace System
+{
+ public static partial class Environment
+ {
+ // Emscripten VFS mounts at / and is the only drive
+ public static string[] GetLogicalDrives() => new string[] { "/" };
+
+ // In the mono runtime, this maps to gethostname, which returns 'emscripten'.
+ // Returning the value here allows us to exclude more of the runtime.
+ public static string MachineName => "localhost";
+
+ // Matching what we returned for an earlier release. There isn't an established equivalent
+ // on wasm.
+ public static long WorkingSet => 0;
+
+ public static string UserName => "Browser";
+
+ private static OperatingSystem GetOSVersion()
+ {
+ return new OperatingSystem(PlatformID.Other, new Version(1, 0, 0, 0));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/libraries/System.Private.CoreLib/src/System/Environment.OSVersion.Browser.cs b/src/libraries/System.Private.CoreLib/src/System/Environment.OSVersion.Browser.cs
deleted file mode 100644
index 9dd80cbbd579e..0000000000000
--- a/src/libraries/System.Private.CoreLib/src/System/Environment.OSVersion.Browser.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System
-{
- public static partial class Environment
- {
- private static OperatingSystem GetOSVersion()
- {
- return new OperatingSystem(PlatformID.Other, new Version(1, 0, 0, 0));
- }
- }
-}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Environment.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/Environment.Unix.cs
index 273d04bae8a18..87306e7b741af 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Environment.Unix.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Environment.Unix.cs
@@ -12,44 +12,8 @@ namespace System
{
public static partial class Environment
{
- public static bool UserInteractive => true;
-
- private static string CurrentDirectoryCore
- {
- get => Interop.Sys.GetCwd();
- set => Interop.CheckIo(Interop.Sys.ChDir(value), value, isDirectory: true);
- }
-
- private static string ExpandEnvironmentVariablesCore(string name)
- {
- var result = new ValueStringBuilder(stackalloc char[128]);
-
- int lastPos = 0, pos;
- while (lastPos < name.Length && (pos = name.IndexOf('%', lastPos + 1)) >= 0)
- {
- if (name[lastPos] == '%')
- {
- string key = name.Substring(lastPos + 1, pos - lastPos - 1);
- string? value = GetEnvironmentVariable(key);
- if (value != null)
- {
- result.Append(value);
- lastPos = pos + 1;
- continue;
- }
- }
- result.Append(name.AsSpan(lastPos, pos - lastPos));
- lastPos = pos;
- }
- result.Append(name.AsSpan(lastPos));
-
- return result.ToString();
- }
-
public static string[] GetLogicalDrives() => Interop.Sys.GetAllMountPoints();
- private static bool Is64BitOperatingSystemWhen32BitProcess => false;
-
public static string MachineName
{
get
@@ -60,13 +24,24 @@ public static string MachineName
}
}
- private static int GetCurrentProcessId() => Interop.Sys.GetPid();
-
- internal const string NewLineConst = "\n";
-
- public static string SystemDirectory => GetFolderPathCore(SpecialFolder.System, SpecialFolderOption.None);
+ public static long WorkingSet
+ {
+ get
+ {
+ Type? processType = Type.GetType("System.Diagnostics.Process, System.Diagnostics.Process, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", throwOnError: false);
+ if (processType?.GetMethod("GetCurrentProcess")?.Invoke(null, BindingFlags.DoNotWrapExceptions, null, null, null) is IDisposable currentProcess)
+ {
+ using (currentProcess)
+ {
+ if (processType!.GetMethod("get_WorkingSet64")?.Invoke(currentProcess, BindingFlags.DoNotWrapExceptions, null, null, null) is long result)
+ return result;
+ }
+ }
- public static int SystemPageSize => CheckedSysConf(Interop.Sys.SysConfName._SC_PAGESIZE);
+ // Could not get the current working set.
+ return 0;
+ }
+ }
public static unsafe string UserName
{
@@ -135,40 +110,5 @@ private static unsafe bool TryGetUserNameFromPasswd(byte* buf, int bufLen, out s
// Otherwise, fail.
throw new IOException(errorInfo.GetErrorMessage(), errorInfo.RawErrno);
}
-
- public static string UserDomainName => MachineName;
-
- /// Invoke , throwing if it fails.
- private static int CheckedSysConf(Interop.Sys.SysConfName name)
- {
- long result = Interop.Sys.SysConf(name);
- if (result == -1)
- {
- Interop.ErrorInfo errno = Interop.Sys.GetLastErrorInfo();
- throw errno.Error == Interop.Error.EINVAL ?
- new ArgumentOutOfRangeException(nameof(name), name, errno.GetErrorMessage()) :
- Interop.GetIOException(errno);
- }
- return (int)result;
- }
-
- public static long WorkingSet
- {
- get
- {
- Type? processType = Type.GetType("System.Diagnostics.Process, System.Diagnostics.Process, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", throwOnError: false);
- if (processType?.GetMethod("GetCurrentProcess")?.Invoke(null, BindingFlags.DoNotWrapExceptions, null, null, null) is IDisposable currentProcess)
- {
- using (currentProcess)
- {
- if (processType!.GetMethod("get_WorkingSet64")?.Invoke(currentProcess, BindingFlags.DoNotWrapExceptions, null, null, null) is long result)
- return result;
- }
- }
-
- // Could not get the current working set.
- return 0;
- }
- }
}
}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Environment.UnixOrBrowser.cs b/src/libraries/System.Private.CoreLib/src/System/Environment.UnixOrBrowser.cs
new file mode 100644
index 0000000000000..cddf1b929e63f
--- /dev/null
+++ b/src/libraries/System.Private.CoreLib/src/System/Environment.UnixOrBrowser.cs
@@ -0,0 +1,75 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Diagnostics;
+using System.IO;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading;
+
+namespace System
+{
+ public static partial class Environment
+ {
+ public static bool UserInteractive => true;
+
+ private static string CurrentDirectoryCore
+ {
+ get => Interop.Sys.GetCwd();
+ set => Interop.CheckIo(Interop.Sys.ChDir(value), value, isDirectory: true);
+ }
+
+ private static string ExpandEnvironmentVariablesCore(string name)
+ {
+ var result = new ValueStringBuilder(stackalloc char[128]);
+
+ int lastPos = 0, pos;
+ while (lastPos < name.Length && (pos = name.IndexOf('%', lastPos + 1)) >= 0)
+ {
+ if (name[lastPos] == '%')
+ {
+ string key = name.Substring(lastPos + 1, pos - lastPos - 1);
+ string? value = GetEnvironmentVariable(key);
+ if (value != null)
+ {
+ result.Append(value);
+ lastPos = pos + 1;
+ continue;
+ }
+ }
+ result.Append(name.AsSpan(lastPos, pos - lastPos));
+ lastPos = pos;
+ }
+ result.Append(name.AsSpan(lastPos));
+
+ return result.ToString();
+ }
+
+ private static bool Is64BitOperatingSystemWhen32BitProcess => false;
+
+ private static int GetCurrentProcessId() => Interop.Sys.GetPid();
+
+ internal const string NewLineConst = "\n";
+
+ public static string SystemDirectory => GetFolderPathCore(SpecialFolder.System, SpecialFolderOption.None);
+
+ public static int SystemPageSize => CheckedSysConf(Interop.Sys.SysConfName._SC_PAGESIZE);
+
+ public static string UserDomainName => MachineName;
+
+ /// Invoke , throwing if it fails.
+ private static int CheckedSysConf(Interop.Sys.SysConfName name)
+ {
+ long result = Interop.Sys.SysConf(name);
+ if (result == -1)
+ {
+ Interop.ErrorInfo errno = Interop.Sys.GetLastErrorInfo();
+ throw errno.Error == Interop.Error.EINVAL ?
+ new ArgumentOutOfRangeException(nameof(name), name, errno.GetErrorMessage()) :
+ Interop.GetIOException(errno);
+ }
+ return (int)result;
+ }
+ }
+}
diff --git a/src/libraries/System.Runtime.Extensions/tests/System/AppDomainTests.cs b/src/libraries/System.Runtime.Extensions/tests/System/AppDomainTests.cs
index b3d13e3d8776a..3fa95271ee2c5 100644
--- a/src/libraries/System.Runtime.Extensions/tests/System/AppDomainTests.cs
+++ b/src/libraries/System.Runtime.Extensions/tests/System/AppDomainTests.cs
@@ -44,6 +44,7 @@ public void RelativeSearchPath_Is_Null()
}
[Fact]
+ [PlatformSpecific(~TestPlatforms.Browser)] // throws pNSE
public void TargetFrameworkTest()
{
const int ExpectedExitCode = 0;
@@ -129,7 +130,7 @@ public void FriendlyName()
// GetEntryAssembly may be null (i.e. desktop)
if (expected == null)
- expected = Assembly.GetExecutingAssembly().GetName().Name;
+ expected = "DefaultDomain";
Assert.Equal(expected, s);
}
@@ -371,6 +372,7 @@ public void ReflectionOnlyGetAssemblies()
}
[Fact]
+ [PlatformSpecific(~TestPlatforms.Browser)] // Throws PNSE
public void MonitoringIsEnabled()
{
Assert.True(AppDomain.MonitoringIsEnabled);
diff --git a/src/libraries/System.Runtime.Extensions/tests/System/Environment.Exit.cs b/src/libraries/System.Runtime.Extensions/tests/System/Environment.Exit.cs
index 34fde94009cac..0ba249373cc7d 100644
--- a/src/libraries/System.Runtime.Extensions/tests/System/Environment.Exit.cs
+++ b/src/libraries/System.Runtime.Extensions/tests/System/Environment.Exit.cs
@@ -41,6 +41,7 @@ public static void ExitCode_Roundtrips(int exitCode)
[InlineData(1)] // setting ExitCode and exiting Main
[InlineData(2)] // setting ExitCode both from Main and from an Unloading event handler.
[InlineData(3)] // using Exit(exitCode)
+ [PlatformSpecific(~TestPlatforms.Browser)] // throws PNSE
public static void ExitCode_VoidMainAppReturnsSetValue(int mode)
{
int expectedExitCode = 123;
diff --git a/src/libraries/System.Runtime.Extensions/tests/System/Environment.MachineName.cs b/src/libraries/System.Runtime.Extensions/tests/System/Environment.MachineName.cs
index 1d12af5cbd53f..eac8bf18bb120 100644
--- a/src/libraries/System.Runtime.Extensions/tests/System/Environment.MachineName.cs
+++ b/src/libraries/System.Runtime.Extensions/tests/System/Environment.MachineName.cs
@@ -20,6 +20,8 @@ internal static string GetComputerName()
#if !Unix
return Environment.GetEnvironmentVariable("COMPUTERNAME");
#else
+ if (PlatformDetection.IsBrowser)
+ return "localhost";
string temp = Interop.Sys.GetNodeName();
int index = temp.IndexOf('.');
return index < 0 ? temp : temp.Substring(0, index);
diff --git a/src/libraries/System.Runtime.Extensions/tests/System/Environment.StackTrace.cs b/src/libraries/System.Runtime.Extensions/tests/System/Environment.StackTrace.cs
index e3fa2c36d28f7..d8505dd4e11c7 100644
--- a/src/libraries/System.Runtime.Extensions/tests/System/Environment.StackTrace.cs
+++ b/src/libraries/System.Runtime.Extensions/tests/System/Environment.StackTrace.cs
@@ -68,6 +68,7 @@ public TestClass()
}
[Fact]
+ [ActiveIssue("https://github.com/dotnet/runtime/issues/38995", TestPlatforms.Browser)]
public void StackTraceDoesNotStartWithInternalFrame()
{
string stackTrace = Environment.StackTrace;
diff --git a/src/libraries/System.Runtime.Extensions/tests/System/EnvironmentTests.cs b/src/libraries/System.Runtime.Extensions/tests/System/EnvironmentTests.cs
index 41e2dfdd946c4..a81a056575fba 100644
--- a/src/libraries/System.Runtime.Extensions/tests/System/EnvironmentTests.cs
+++ b/src/libraries/System.Runtime.Extensions/tests/System/EnvironmentTests.cs
@@ -221,7 +221,10 @@ public void Version_Valid()
[Fact]
public void WorkingSet_Valid()
{
- Assert.True(Environment.WorkingSet > 0, "Expected positive WorkingSet value");
+ if (PlatformDetection.IsBrowser)
+ Assert.Equal(0, Environment.WorkingSet);
+ else
+ Assert.True(Environment.WorkingSet > 0, "Expected positive WorkingSet value");
}
[Trait(XunitConstants.Category, XunitConstants.IgnoreForCI)] // fail fast crashes the process
diff --git a/src/libraries/System.Runtime.Extensions/tests/System/IO/PathTests.cs b/src/libraries/System.Runtime.Extensions/tests/System/IO/PathTests.cs
index 45023c0873fde..2ef46ada0d0b6 100644
--- a/src/libraries/System.Runtime.Extensions/tests/System/IO/PathTests.cs
+++ b/src/libraries/System.Runtime.Extensions/tests/System/IO/PathTests.cs
@@ -216,8 +216,6 @@ public static TheoryData GetFullPath_BasicExpansions
{ currentDirectory, currentDirectory },
// "." => current directory
{ ".", currentDirectory },
- // ".." => up a directory
- { "..", Path.GetDirectoryName(currentDirectory) },
// "dir/./././." => "dir"
{ Path.Combine(currentDirectory, ".", ".", ".", ".", "."), currentDirectory },
// "dir///." => "dir"
@@ -234,6 +232,12 @@ public static TheoryData GetFullPath_BasicExpansions
{ root + new string(Path.DirectorySeparatorChar, 3), root },
};
+ if (currentDirectory != Path.GetPathRoot(currentDirectory))
+ {
+ // ".." => up a directory
+ data.Add("..", Path.GetDirectoryName(currentDirectory));
+ }
+
// Path longer than MaxPath that normalizes down to less than MaxPath
const int Iters = 10000;
var longPath = new StringBuilder(currentDirectory, currentDirectory.Length + (Iters * 2));
diff --git a/src/libraries/System.Runtime.Extensions/tests/System/StringComparer.cs b/src/libraries/System.Runtime.Extensions/tests/System/StringComparer.cs
index b60edf9c26fbe..62edd56f51cb0 100644
--- a/src/libraries/System.Runtime.Extensions/tests/System/StringComparer.cs
+++ b/src/libraries/System.Runtime.Extensions/tests/System/StringComparer.cs
@@ -86,8 +86,12 @@ public static IEnumerable