Skip to content

Commit b556b46

Browse files
committed
Windows: Implement attributesOfItem with _lstat
1 parent a733b6b commit b556b46

File tree

1 file changed

+16
-14
lines changed

1 file changed

+16
-14
lines changed

Foundation/FileManager.swift

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -871,14 +871,6 @@ open class FileManager : NSObject {
871871
open func attributesOfItem(atPath path: String) throws -> [FileAttributeKey : Any] {
872872
var result: [FileAttributeKey:Any] = [:]
873873

874-
#if os(Windows)
875-
let faAttributes: WIN32_FILE_ATTRIBUTE_DATA = try windowsFileAttributes(atPath: path)
876-
877-
result[.size] = NSNumber(value: (faAttributes.nFileSizeHigh << 32) | faAttributes.nFileSizeLow)
878-
result[.modificationDate] = Date(timeIntervalSinceReferenceDate: TimeInterval(faAttributes.ftLastWriteTime))
879-
// FIXME(compnerd) what about .posixPermissions, .referenceCount, .systemNumber, .systemFileNumber, .ownerAccountName, .groupOwnerAccountName, .type, .immuatable, .appendOnly, .ownerAccountID, .groupOwnerAccountID
880-
#else
881-
882874
#if os(Linux)
883875
let (s, creationDate) = try _statxFile(atPath: path)
884876
result[.creationDate] = creationDate
@@ -892,32 +884,43 @@ open class FileManager : NSObject {
892884
let ti = (TimeInterval(s.st_mtimespec.tv_sec) - kCFAbsoluteTimeIntervalSince1970) + (1.0e-9 * TimeInterval(s.st_mtimespec.tv_nsec))
893885
#elseif os(Android)
894886
let ti = (TimeInterval(s.st_mtime) - kCFAbsoluteTimeIntervalSince1970) + (1.0e-9 * TimeInterval(s.st_mtime_nsec))
887+
#elseif os(Windows)
888+
let ti = (TimeInterval(s.st_mtime) - kCFAbsoluteTimeIntervalSince1970)
895889
#else
896890
let ti = (TimeInterval(s.st_mtim.tv_sec) - kCFAbsoluteTimeIntervalSince1970) + (1.0e-9 * TimeInterval(s.st_mtim.tv_nsec))
897891
#endif
898892
result[.modificationDate] = Date(timeIntervalSinceReferenceDate: ti)
899-
893+
894+
#if os(Windows)
895+
result[.posixPermissions] = NSNumber(value: UInt64(s.st_mode & ~UInt16(ucrt.S_IFMT)))
896+
#else
900897
result[.posixPermissions] = NSNumber(value: UInt64(s.st_mode & ~S_IFMT))
898+
#endif
901899
result[.referenceCount] = NSNumber(value: UInt64(s.st_nlink))
902900
result[.systemNumber] = NSNumber(value: UInt64(s.st_dev))
903901
result[.systemFileNumber] = NSNumber(value: UInt64(s.st_ino))
904-
902+
903+
#if os(Windows)
904+
result[.type] = s.st_mode
905+
result[.deviceIdentifier] = NSNumber(value: UInt64(s.st_rdev))
906+
#else
905907
if let pwd = getpwuid(s.st_uid), pwd.pointee.pw_name != nil {
906908
let name = String(cString: pwd.pointee.pw_name)
907909
result[.ownerAccountName] = name
908910
}
909-
911+
910912
if let grd = getgrgid(s.st_gid), grd.pointee.gr_name != nil {
911913
let name = String(cString: grd.pointee.gr_name)
912914
result[.groupOwnerAccountName] = name
913915
}
914916

915917
let type = FileAttributeType(statMode: s.st_mode)
916918
result[.type] = type
917-
919+
918920
if type == .typeBlockSpecial || type == .typeCharacterSpecial {
919921
result[.deviceIdentifier] = NSNumber(value: UInt64(s.st_rdev))
920922
}
923+
#endif
921924

922925
#if os(macOS) || os(iOS)
923926
if (s.st_flags & UInt32(UF_IMMUTABLE | SF_IMMUTABLE)) != 0 {
@@ -929,11 +932,10 @@ open class FileManager : NSObject {
929932
#endif
930933
result[.ownerAccountID] = NSNumber(value: UInt64(s.st_uid))
931934
result[.groupOwnerAccountID] = NSNumber(value: UInt64(s.st_gid))
932-
#endif
933935

934936
return result
935937
}
936-
938+
937939
/* attributesOfFileSystemForPath:error: returns an NSDictionary of key/value pairs containing the attributes of the filesystem containing the provided path. If this method returns 'nil', an NSError will be returned by reference in the 'error' parameter. This method does not traverse a terminal symlink.
938940

939941
This method replaces fileSystemAttributesAtPath:.

0 commit comments

Comments
 (0)