Skip to content

Commit 62c50ad

Browse files
authored
Merge pull request #3005 from millenomi/pr/sr-14823
2 parents 08979ae + cbfe077 commit 62c50ad

File tree

2 files changed

+33
-23
lines changed

2 files changed

+33
-23
lines changed

Sources/Foundation/NSPathUtilities.swift

+25-19
Original file line numberDiff line numberDiff line change
@@ -735,7 +735,6 @@ public func NSFullUserName() -> String {
735735
}
736736

737737
internal func _NSCreateTemporaryFile(_ filePath: String) throws -> (Int32, String) {
738-
let template = filePath + ".tmp.XXXXXX"
739738
#if os(Windows)
740739
let maxLength: Int = Int(MAX_PATH + 1)
741740
var buf: [UInt16] = Array<UInt16>(repeating: 0, count: maxLength)
@@ -760,26 +759,32 @@ internal func _NSCreateTemporaryFile(_ filePath: String) throws -> (Int32, Strin
760759
// Don't close h, fd is transferred ownership
761760
let fd = _open_osfhandle(intptr_t(bitPattern: h), 0)
762761
#else
763-
var filename = template.utf8CString
762+
var template = URL(fileURLWithPath: filePath)
763+
764+
let filename = template.lastPathComponent
765+
let hashed = String(format: "%llx", Int64(filename.hashValue))
766+
template.deleteLastPathComponent()
767+
template.appendPathComponent("SCF.\(hashed).tmp.XXXXXX")
764768

765-
let result = filename.withUnsafeMutableBufferPointer { (ptr: inout UnsafeMutableBufferPointer<CChar>) -> (Int32, String)? in
766-
// filename is updated with the temp file name on success.
767-
let fd = mkstemp(ptr.baseAddress!)
768-
if fd == -1 {
769-
return nil
770-
} else {
771-
guard let fname = String(utf8String: ptr.baseAddress!) else {
772-
// Couldnt convert buffer back to filename.
773-
close(fd)
774-
errno = ENOENT
775-
return nil
776-
}
777-
return (fd, fname)
778-
}
769+
770+
let (fd, errorCode, pathResult) = template.withUnsafeFileSystemRepresentation { ptr -> (Int32, Int32, String) in
771+
let length = strlen(ptr!)
772+
773+
// buffer is updated with the temp file name on success.
774+
let buffer = UnsafeMutableBufferPointer<CChar>.allocate(capacity: length + 1 /* the null character */)
775+
UnsafeRawBufferPointer(start: ptr!, count: length + 1 /* the null character */)
776+
.copyBytes(to: UnsafeMutableRawBufferPointer(buffer))
777+
defer { buffer.deallocate() }
778+
779+
let fd = mkstemp(buffer.baseAddress!)
780+
let errorCode = errno
781+
return (fd,
782+
errorCode,
783+
FileManager.default.string(withFileSystemRepresentation: buffer.baseAddress!, length: strlen(buffer.baseAddress!)))
779784
}
780785

781-
guard let (fd, pathResult) = result else {
782-
throw _NSErrorWithErrno(errno, reading: false, path: template)
786+
if fd == -1 {
787+
throw _NSErrorWithErrno(errorCode, reading: false, path: pathResult)
783788
}
784789

785790
// Set the file mode to match macOS
@@ -802,8 +807,9 @@ internal func _NSCleanupTemporaryFile(_ auxFilePath: String, _ filePath: String)
802807
}
803808
#else
804809
if rename($0, $1) != 0 {
810+
let errorCode = errno
805811
try? FileManager.default.removeItem(atPath: auxFilePath)
806-
throw _NSErrorWithErrno(errno, reading: false, path: filePath)
812+
throw _NSErrorWithErrno(errorCode, reading: false, path: filePath)
807813
}
808814
#endif
809815
})

Tests/Foundation/Tests/TestFileManager.swift

+8-4
Original file line numberDiff line numberDiff line change
@@ -489,11 +489,15 @@ class TestFileManager : XCTestCase {
489489
try fm.createDirectory(atPath: basePath, withIntermediateDirectories: false, attributes: nil)
490490
try fm.createDirectory(atPath: basePath2, withIntermediateDirectories: false, attributes: nil)
491491

492-
let _ = fm.createFile(atPath: itemPath, contents: Data(count: 123), attributes: nil)
493-
let _ = fm.createFile(atPath: itemPath2, contents: Data(count: 456), attributes: nil)
494-
492+
if !fm.createFile(atPath: itemPath, contents: Data(count: 123), attributes: nil) {
493+
throw CocoaError(.fileWriteUnknown)
494+
}
495+
if !fm.createFile(atPath: itemPath2, contents: Data(count: 456), attributes: nil) {
496+
throw CocoaError(.fileWriteUnknown)
497+
}
495498
} catch {
496-
XCTFail()
499+
XCTFail("Failed with error while creating temporary files: \(error)")
500+
return
497501
}
498502

499503
var item1FileAttributes: [FileAttributeKey: Any]!

0 commit comments

Comments
 (0)