Skip to content

Commit 9383d7a

Browse files
authored
Merge pull request #1935 from spevans/pr_sr_6531_50
2 parents 16a2779 + 7716988 commit 9383d7a

File tree

2 files changed

+54
-2
lines changed

2 files changed

+54
-2
lines changed

Foundation/FileManager.swift

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// This source file is part of the Swift.org open source project
22
//
3-
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
3+
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
44
// Licensed under Apache License v2.0 with Runtime Library Exception
55
//
66
// See https://swift.org/LICENSE.txt for license information
@@ -664,7 +664,7 @@ open class FileManager : NSObject {
664664
#endif
665665
result[.modificationDate] = Date(timeIntervalSinceReferenceDate: ti)
666666

667-
result[.posixPermissions] = NSNumber(value: UInt64(s.st_mode & 0o7777))
667+
result[.posixPermissions] = NSNumber(value: UInt64(s.st_mode & ~S_IFMT))
668668
result[.referenceCount] = NSNumber(value: UInt64(s.st_nlink))
669669
result[.systemNumber] = NSNumber(value: UInt64(s.st_dev))
670670
result[.systemFileNumber] = NSNumber(value: UInt64(s.st_ino))
@@ -836,6 +836,13 @@ open class FileManager : NSObject {
836836
}
837837
defer { close(dstfd) }
838838

839+
// Set the file permissions using fchmod() instead of when open()ing to avoid umask() issues
840+
let permissions = fileInfo.st_mode & ~S_IFMT
841+
guard fchmod(dstfd, permissions) == 0 else {
842+
throw _NSErrorWithErrno(errno, reading: false, path: dstPath,
843+
extraUserInfo: extraErrorInfo(srcPath: srcPath, dstPath: dstPath, userVariant: variant))
844+
}
845+
839846
if fileInfo.st_size == 0 {
840847
// no copying required
841848
return

TestFoundation/TestFileManager.swift

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class TestFileManager : XCTestCase {
4141
("test_temporaryDirectoryForUser", test_temporaryDirectoryForUser),
4242
("test_creatingDirectoryWithShortIntermediatePath", test_creatingDirectoryWithShortIntermediatePath),
4343
("test_mountedVolumeURLs", test_mountedVolumeURLs),
44+
("test_copyItemsPermissions", test_copyItemsPermissions),
4445
]
4546

4647
#if !DEPLOYMENT_RUNTIME_OBJC && NS_FOUNDATION_ALLOWS_TESTABLE_IMPORT
@@ -1067,6 +1068,50 @@ class TestFileManager : XCTestCase {
10671068
XCTAssertFalse(fm.contentsEqual(atPath: dataFile1.path, andPath: dataFile2.path))
10681069
XCTAssertFalse(fm.contentsEqual(atPath: testDir1.path, andPath: testDir2.path))
10691070
}
1071+
1072+
func test_copyItemsPermissions() throws {
1073+
let fm = FileManager.default
1074+
let tmpDir = fm.temporaryDirectory.appendingPathComponent("test_copyItemsPermissions")
1075+
try fm.createDirectory(at: tmpDir, withIntermediateDirectories: true)
1076+
defer { try? fm.removeItem(atPath: tmpDir.path) }
1077+
1078+
let srcFile = tmpDir.appendingPathComponent("file1.txt")
1079+
let destFile = tmpDir.appendingPathComponent("file2.txt")
1080+
1081+
let source = "This is the source file"
1082+
try? fm.removeItem(at: srcFile)
1083+
try source.write(toFile: srcFile.path, atomically: false, encoding: .utf8)
1084+
1085+
func testCopy() throws {
1086+
try? fm.removeItem(at: destFile)
1087+
try fm.copyItem(at: srcFile, to: destFile)
1088+
let copy = try String(contentsOf: destFile)
1089+
XCTAssertEqual(source, copy)
1090+
if let srcPerms = (try fm.attributesOfItem(atPath: srcFile.path)[.posixPermissions] as? NSNumber)?.intValue,
1091+
let destPerms = (try fm.attributesOfItem(atPath: destFile.path)[.posixPermissions] as? NSNumber)?.intValue {
1092+
XCTAssertEqual(srcPerms, destPerms)
1093+
} else {
1094+
XCTFail("Cant get file permissions")
1095+
}
1096+
}
1097+
1098+
try testCopy()
1099+
1100+
try fm.setAttributes([ .posixPermissions: 0o417], ofItemAtPath: srcFile.path)
1101+
try testCopy()
1102+
1103+
try fm.setAttributes([ .posixPermissions: 0o400], ofItemAtPath: srcFile.path)
1104+
try testCopy()
1105+
1106+
try fm.setAttributes([ .posixPermissions: 0o700], ofItemAtPath: srcFile.path)
1107+
try testCopy()
1108+
1109+
try fm.setAttributes([ .posixPermissions: 0o707], ofItemAtPath: srcFile.path)
1110+
try testCopy()
1111+
1112+
try fm.setAttributes([ .posixPermissions: 0o411], ofItemAtPath: srcFile.path)
1113+
try testCopy()
1114+
}
10701115

10711116
#if !DEPLOYMENT_RUNTIME_OBJC // XDG tests require swift-corelibs-foundation
10721117

0 commit comments

Comments
 (0)