diff --git a/src/libraries/Common/src/Interop/Unix/System.Native/Interop.UnixFileSystemTypes.cs b/src/libraries/Common/src/Interop/Unix/System.Native/Interop.UnixFileSystemTypes.cs index 984ca44c35c023..ce0dffd7372f85 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Native/Interop.UnixFileSystemTypes.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Native/Interop.UnixFileSystemTypes.cs @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; +using System.Diagnostics; using System.Runtime.InteropServices; using Microsoft.Win32.SafeHandles; @@ -16,12 +18,13 @@ internal static partial class Sys /// where this enum must be a subset of the GetDriveType list, with the enum /// values here exactly matching a string there. /// - internal enum UnixFileSystemTypes : long + internal enum UnixFileSystemTypes : uint { adfs = 0xADF5, affs = 0xADFF, afs = 0x5346414F, anoninode = 0x09041934, + apfs = 0x1A, aufs = 0x61756673, autofs = 0x0187, autofs4 = 0x6D4A556D, @@ -146,13 +149,14 @@ internal enum UnixFileSystemTypes : long } [LibraryImport(Libraries.SystemNative, EntryPoint = "SystemNative_GetFileSystemType")] - private static partial long GetFileSystemType(SafeFileHandle fd); + private static partial uint GetFileSystemType(SafeFileHandle fd); internal static bool TryGetFileSystemType(SafeFileHandle fd, out UnixFileSystemTypes fileSystemType) { - long fstatfsResult = GetFileSystemType(fd); + uint fstatfsResult = GetFileSystemType(fd); fileSystemType = (UnixFileSystemTypes)fstatfsResult; - return fstatfsResult != -1; + Debug.Assert(Enum.IsDefined(fileSystemType) || fstatfsResult == 0 || !OperatingSystem.IsLinux(), $"GetFileSystemType returned {fstatfsResult}"); + return fstatfsResult != 0; } } } diff --git a/src/native/libs/System.Native/pal_io.c b/src/native/libs/System.Native/pal_io.c index d196cbf33970f1..a721025fe688f5 100644 --- a/src/native/libs/System.Native/pal_io.c +++ b/src/native/libs/System.Native/pal_io.c @@ -1472,7 +1472,7 @@ static int16_t ConvertLockType(int16_t managedLockType) } } -int64_t SystemNative_GetFileSystemType(intptr_t fd) +uint32_t SystemNative_GetFileSystemType(intptr_t fd) { #if HAVE_STATFS_VFS || HAVE_STATFS_MOUNT int statfsRes; @@ -1480,19 +1480,25 @@ int64_t SystemNative_GetFileSystemType(intptr_t fd) // for our needs (get file system type) statfs is always enough and there is no need to use statfs64 // which got deprecated in macOS 10.6, in favor of statfs while ((statfsRes = fstatfs(ToFileDescriptor(fd), &statfsArgs)) == -1 && errno == EINTR) ; - return statfsRes == -1 ? (int64_t)-1 : (int64_t)statfsArgs.f_type; + if (statfsRes == -1) return 0; + + // On Linux, f_type is signed. This causes some filesystem types to be represented as + // negative numbers on 32-bit platforms. We cast to uint32_t to make them positive. + uint32_t result = (uint32_t)statfsArgs.f_type; + return result; #elif !HAVE_NON_LEGACY_STATFS int statfsRes; struct statvfs statfsArgs; while ((statfsRes = fstatvfs(ToFileDescriptor(fd), &statfsArgs)) == -1 && errno == EINTR) ; - if (statfsRes == -1) return (int64_t)-1; + if (statfsRes == -1) return 0; - int64_t result = -1; + uint32_t result = 0; if (strcmp(statfsArgs.f_basetype, "adfs") == 0) result = 0xADF5; else if (strcmp(statfsArgs.f_basetype, "affs") == 0) result = 0xADFF; else if (strcmp(statfsArgs.f_basetype, "afs") == 0) result = 0x5346414F; else if (strcmp(statfsArgs.f_basetype, "anoninode") == 0) result = 0x09041934; + else if (strcmp(statfsArgs.f_basetype, "apfs") == 0) result = 0x1A; else if (strcmp(statfsArgs.f_basetype, "aufs") == 0) result = 0x61756673; else if (strcmp(statfsArgs.f_basetype, "autofs") == 0) result = 0x0187; else if (strcmp(statfsArgs.f_basetype, "autofs4") == 0) result = 0x6D4A556D; @@ -1613,7 +1619,7 @@ int64_t SystemNative_GetFileSystemType(intptr_t fd) else if (strcmp(statfsArgs.f_basetype, "udev") == 0) result = 0x01021994; else if (strcmp(statfsArgs.f_basetype, "zfs") == 0) result = 0x2FC12FC1; - assert(result != -1); + assert(result != 0); return result; #else #error "Platform doesn't support fstatfs or fstatvfs" diff --git a/src/native/libs/System.Native/pal_io.h b/src/native/libs/System.Native/pal_io.h index 720d7623fee79f..30dc534635c4f6 100644 --- a/src/native/libs/System.Native/pal_io.h +++ b/src/native/libs/System.Native/pal_io.h @@ -739,9 +739,9 @@ PALEXPORT char* SystemNative_RealPath(const char* path); PALEXPORT int32_t SystemNative_GetPeerID(intptr_t socket, uid_t* euid); /** -* Returns file system type on success, or -1 on error. +* Returns file system type on success, or 0 on error. */ -PALEXPORT int64_t SystemNative_GetFileSystemType(intptr_t fd); +PALEXPORT uint32_t SystemNative_GetFileSystemType(intptr_t fd); /** * Attempts to lock/unlock the region of the file "fd" specified by the offset and length. lockType