@@ -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,29 +884,36 @@ 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-
900- result [ . posixPermissions] = NSNumber ( value: UInt64 ( s. st_mode & ~ S_IFMT ) )
893+
894+ result [ . posixPermissions] = NSNumber ( value: _filePermissionsMask ( mode : UInt32 ( s. st_mode) ) )
901895 result [ . referenceCount] = NSNumber ( value: UInt64 ( s. st_nlink) )
902896 result [ . systemNumber] = NSNumber ( value: UInt64 ( s. st_dev) )
903897 result [ . systemFileNumber] = NSNumber ( value: UInt64 ( s. st_ino) )
904-
898+
899+ #if os(Windows)
900+ result [ . deviceIdentifier] = NSNumber ( value: UInt64 ( s. st_rdev) )
901+ let type = FileAttributeType ( attributes: try windowsFileAttributes ( atPath: path) )
902+ #else
905903 if let pwd = getpwuid ( s. st_uid) , pwd. pointee. pw_name != nil {
906904 let name = String ( cString: pwd. pointee. pw_name)
907905 result [ . ownerAccountName] = name
908906 }
909-
907+
910908 if let grd = getgrgid ( s. st_gid) , grd. pointee. gr_name != nil {
911909 let name = String ( cString: grd. pointee. gr_name)
912910 result [ . groupOwnerAccountName] = name
913911 }
914912
915913 let type = FileAttributeType ( statMode: s. st_mode)
914+ #endif
916915 result [ . type] = type
917-
916+
918917 if type == . typeBlockSpecial || type == . typeCharacterSpecial {
919918 result [ . deviceIdentifier] = NSNumber ( value: UInt64 ( s. st_rdev) )
920919 }
@@ -929,11 +928,10 @@ open class FileManager : NSObject {
929928#endif
930929 result [ . ownerAccountID] = NSNumber ( value: UInt64 ( s. st_uid) )
931930 result [ . groupOwnerAccountID] = NSNumber ( value: UInt64 ( s. st_gid) )
932- #endif
933931
934932 return result
935933 }
936-
934+
937935 /* 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.
938936
939937 This method replaces fileSystemAttributesAtPath:.
@@ -1870,15 +1868,21 @@ open class FileManager : NSObject {
18701868 return statInfo
18711869 }
18721870
1873- internal func _permissionsOfItem( atPath path: String ) throws -> Int {
1874- let fileInfo = try _lstatFile ( atPath: path)
1871+ internal func _filePermissionsMask( mode : UInt32 ) -> Int {
18751872#if os(Windows)
1876- return Int ( fileInfo. st_mode & ~ UInt16( ucrt. S_IFMT) )
1873+ return Int ( mode & ~ UInt32( ucrt. S_IFMT) )
1874+ #elseif canImport(Darwin)
1875+ return Int ( mode & ~ UInt32( S_IFMT) )
18771876#else
1878- return Int ( fileInfo . st_mode & ~ S_IFMT)
1877+ return Int ( mode & ~ S_IFMT)
18791878#endif
18801879 }
18811880
1881+ internal func _permissionsOfItem( atPath path: String ) throws -> Int {
1882+ let fileInfo = try _lstatFile ( atPath: path)
1883+ return _filePermissionsMask ( mode: UInt32 ( fileInfo. st_mode) )
1884+ }
1885+
18821886
18831887#if os(Linux)
18841888 // statx() is only supported by Linux kernels >= 4.11.0
0 commit comments