diff --git a/src/libraries/Common/src/Interop/OSX/System.Native/Interop.SearchPath.cs b/src/libraries/Common/src/Interop/OSX/System.Native/Interop.SearchPath.cs
index 89681a69c5ed89..ccb15a00227595 100644
--- a/src/libraries/Common/src/Interop/OSX/System.Native/Interop.SearchPath.cs
+++ b/src/libraries/Common/src/Interop/OSX/System.Native/Interop.SearchPath.cs
@@ -19,6 +19,7 @@ internal enum NSSearchPathDirectory
NSDocumentDirectory = 9,
NSDesktopDirectory = 12,
NSCachesDirectory = 13,
+ NSApplicationSupportDirectory = 14,
NSMoviesDirectory = 17,
NSMusicDirectory = 18,
NSPicturesDirectory = 19
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 b12227e70d57b2..a3e339de38b52b 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
@@ -2292,7 +2292,7 @@
-
+
Common\Interop\OSX\Interop.SearchPath.cs
diff --git a/src/libraries/System.Private.CoreLib/src/System/Environment.GetFolderPathCore.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/Environment.GetFolderPathCore.Unix.cs
index 7990febb5a11bb..1ec8fd1af28cb1 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Environment.GetFolderPathCore.Unix.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Environment.GetFolderPathCore.Unix.cs
@@ -9,6 +9,9 @@
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
+#if TARGET_OSX
+using NSSearchPathDirectory = Interop.Sys.NSSearchPathDirectory;
+#endif
namespace System
{
@@ -17,7 +20,7 @@ public static partial class Environment
private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOption option)
{
// Get the path for the SpecialFolder
- string path = GetFolderPathCoreWithoutValidation(folder);
+ string path = GetFolderPathCoreWithoutValidation(folder) ?? string.Empty;
Debug.Assert(path != null);
// If we didn't get one, or if we got one but we're not supposed to verify it,
@@ -43,7 +46,7 @@ private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOptio
return path;
}
- private static string GetFolderPathCoreWithoutValidation(SpecialFolder folder)
+ private static string? GetFolderPathCoreWithoutValidation(SpecialFolder folder)
{
// First handle any paths that involve only static paths, avoiding the overheads of getting user-local paths.
// https://www.freedesktop.org/software/systemd/man/file-hierarchy.html
@@ -85,42 +88,54 @@ private static string GetFolderPathCoreWithoutValidation(SpecialFolder folder)
switch (folder)
{
case SpecialFolder.UserProfile:
- case SpecialFolder.MyDocuments: // same value as Personal
return home;
- case SpecialFolder.ApplicationData:
- return GetXdgConfig(home);
- case SpecialFolder.LocalApplicationData:
- // "$XDG_DATA_HOME defines the base directory relative to which user specific data files should be stored."
- // "If $XDG_DATA_HOME is either not set or empty, a default equal to $HOME/.local/share should be used."
- string? data = GetEnvironmentVariable("XDG_DATA_HOME");
- if (data is null || !data.StartsWith('/'))
- {
- data = Path.Combine(home, ".local", "share");
- }
- return data;
- case SpecialFolder.Desktop:
- case SpecialFolder.DesktopDirectory:
- return ReadXdgDirectory(home, "XDG_DESKTOP_DIR", "Desktop");
case SpecialFolder.Templates:
return ReadXdgDirectory(home, "XDG_TEMPLATES_DIR", "Templates");
- case SpecialFolder.MyVideos:
- return ReadXdgDirectory(home, "XDG_VIDEOS_DIR", "Videos");
-
+ // TODO: Consider merging the OSX path with the rest of the Apple systems here:
+ // https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Environment.iOS.cs
#if TARGET_OSX
+ case SpecialFolder.Desktop:
+ case SpecialFolder.DesktopDirectory:
+ return Interop.Sys.SearchPath(NSSearchPathDirectory.NSDesktopDirectory);
+ case SpecialFolder.ApplicationData:
+ case SpecialFolder.LocalApplicationData:
+ return Interop.Sys.SearchPath(NSSearchPathDirectory.NSApplicationSupportDirectory);
+ case SpecialFolder.MyDocuments: // same value as Personal
+ return Interop.Sys.SearchPath(NSSearchPathDirectory.NSDocumentDirectory);
case SpecialFolder.MyMusic:
- return Path.Combine(home, "Music");
+ return Interop.Sys.SearchPath(NSSearchPathDirectory.NSMusicDirectory);
+ case SpecialFolder.MyVideos:
+ return Interop.Sys.SearchPath(NSSearchPathDirectory.NSMoviesDirectory);
case SpecialFolder.MyPictures:
- return Path.Combine(home, "Pictures");
+ return Interop.Sys.SearchPath(NSSearchPathDirectory.NSPicturesDirectory);
case SpecialFolder.Fonts:
return Path.Combine(home, "Library", "Fonts");
case SpecialFolder.Favorites:
return Path.Combine(home, "Library", "Favorites");
case SpecialFolder.InternetCache:
- return Path.Combine(home, "Library", "Caches");
+ return Interop.Sys.SearchPath(NSSearchPathDirectory.NSCachesDirectory);
#else
+ case SpecialFolder.Desktop:
+ case SpecialFolder.DesktopDirectory:
+ return ReadXdgDirectory(home, "XDG_DESKTOP_DIR", "Desktop");
+ case SpecialFolder.ApplicationData:
+ return GetXdgConfig(home);
+ case SpecialFolder.LocalApplicationData:
+ // "$XDG_DATA_HOME defines the base directory relative to which user specific data files should be stored."
+ // "If $XDG_DATA_HOME is either not set or empty, a default equal to $HOME/.local/share should be used."
+ string? data = GetEnvironmentVariable("XDG_DATA_HOME");
+ if (data is null || !data.StartsWith('/'))
+ {
+ data = Path.Combine(home, ".local", "share");
+ }
+ return data;
+ case SpecialFolder.MyDocuments: // same value as Personal
+ return ReadXdgDirectory(home, "XDG_DOCUMENTS_DIR", "Documents");
case SpecialFolder.MyMusic:
return ReadXdgDirectory(home, "XDG_MUSIC_DIR", "Music");
+ case SpecialFolder.MyVideos:
+ return ReadXdgDirectory(home, "XDG_VIDEOS_DIR", "Videos");
case SpecialFolder.MyPictures:
return ReadXdgDirectory(home, "XDG_PICTURES_DIR", "Pictures");
case SpecialFolder.Fonts:
diff --git a/src/libraries/System.Runtime.Extensions/tests/System/EnvironmentTests.cs b/src/libraries/System.Runtime.Extensions/tests/System/EnvironmentTests.cs
index 416c58590016dd..3c82cfe0032833 100644
--- a/src/libraries/System.Runtime.Extensions/tests/System/EnvironmentTests.cs
+++ b/src/libraries/System.Runtime.Extensions/tests/System/EnvironmentTests.cs
@@ -332,19 +332,21 @@ public void FailFast_ExceptionStackTrace_InnerException()
[Fact]
[PlatformSpecific(TestPlatforms.AnyUnix | TestPlatforms.Browser)]
- public void GetFolderPath_Unix_PersonalExists()
+ public void GetFolderPath_Unix_UserProfileExists()
{
- Assert.True(Directory.Exists(Environment.GetFolderPath(Environment.SpecialFolder.Personal)));
+ Assert.True(Directory.Exists(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)));
}
[Fact]
[PlatformSpecific(TestPlatforms.AnyUnix | TestPlatforms.Browser)] // Tests OS-specific environment
- public void GetFolderPath_Unix_PersonalIsHomeAndUserProfile()
+ public void GetFolderPath_Unix_PersonalIsDocumentsAndUserProfile()
{
if (!PlatformDetection.IsiOS && !PlatformDetection.IstvOS && !PlatformDetection.IsMacCatalyst)
{
- Assert.Equal(Environment.GetEnvironmentVariable("HOME"), Environment.GetFolderPath(Environment.SpecialFolder.Personal));
- Assert.Equal(Environment.GetEnvironmentVariable("HOME"), Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments));
+ Assert.Equal(Path.Combine(Environment.GetEnvironmentVariable("HOME"), "Documents"),
+ Environment.GetFolderPath(Environment.SpecialFolder.Personal, Environment.SpecialFolderOption.DoNotVerify));
+ Assert.Equal(Path.Combine(Environment.GetEnvironmentVariable("HOME"), "Documents"),
+ Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments, Environment.SpecialFolderOption.DoNotVerify));
}
Assert.Equal(Environment.GetEnvironmentVariable("HOME"), Environment.GetFolderPath(Environment.SpecialFolder.UserProfile));
@@ -357,6 +359,7 @@ public void GetFolderPath_Unix_PersonalIsHomeAndUserProfile()
[InlineData(Environment.SpecialFolder.Desktop)]
[InlineData(Environment.SpecialFolder.DesktopDirectory)]
[InlineData(Environment.SpecialFolder.Fonts)]
+ [InlineData(Environment.SpecialFolder.MyDocuments)]
[InlineData(Environment.SpecialFolder.MyMusic)]
[InlineData(Environment.SpecialFolder.MyPictures)]
[InlineData(Environment.SpecialFolder.MyVideos)]
@@ -391,7 +394,7 @@ public void GetSystemDirectory()
[Theory]
[PlatformSpecific(TestPlatforms.AnyUnix)] // Tests OS-specific environment
[InlineData(Environment.SpecialFolder.UserProfile, Environment.SpecialFolderOption.None)]
- [InlineData(Environment.SpecialFolder.MyDocuments, Environment.SpecialFolderOption.None)] // MyDocuments == Personal
+ [InlineData(Environment.SpecialFolder.MyDocuments, Environment.SpecialFolderOption.DoNotVerify)] // MyDocuments == Personal
[InlineData(Environment.SpecialFolder.CommonApplicationData, Environment.SpecialFolderOption.None)]
[InlineData(Environment.SpecialFolder.CommonTemplates, Environment.SpecialFolderOption.DoNotVerify)]
[InlineData(Environment.SpecialFolder.ApplicationData, Environment.SpecialFolderOption.DoNotVerify)]
diff --git a/src/native/libs/System.Native/CMakeLists.txt b/src/native/libs/System.Native/CMakeLists.txt
index b4d97039824319..a6358bafed498c 100644
--- a/src/native/libs/System.Native/CMakeLists.txt
+++ b/src/native/libs/System.Native/CMakeLists.txt
@@ -59,6 +59,11 @@ if (CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVO
set(NATIVE_SOURCES ${NATIVE_SOURCES}
pal_log.m
pal_searchpath.m)
+elseif (CLR_CMAKE_TARGET_OSX)
+ list (APPEND NATIVE_SOURCES
+ pal_searchpath.m
+ pal_console.c
+ pal_log.c)
else ()
list (APPEND NATIVE_SOURCES
pal_searchpath.c