Skip to content

Commit 80bbe98

Browse files
authored
Merge pull request #2029 from karthikkeyan/karthik/SR-9979-comaprefile-filehandle
[SR-9979] FileHandle class used to implement FileManager._compareFiles
2 parents 72e4427 + e33eb72 commit 80bbe98

File tree

2 files changed

+38
-17
lines changed

2 files changed

+38
-17
lines changed

Foundation/FileHandle.swift

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,23 @@ open class FileHandle : NSObject, NSSecureCoding {
342342
}
343343
#endif
344344
}
345+
346+
internal func _readBytes(into buffer: UnsafeMutablePointer<UInt8>, length: Int) throws -> Int {
347+
#if os(Windows)
348+
var BytesRead: DWORD = 0
349+
let BytesToRead: DWORD = DWORD(length)
350+
if ReadFile(_handle, buffer, BytesToRead, &BytesRead, nil) == FALSE {
351+
throw _NSErrorWithWindowsError(GetLastError(), reading: true)
352+
}
353+
return Int(BytesRead)
354+
#else
355+
let amtRead = _read(_fd, buffer, length)
356+
if amtRead < 0 {
357+
throw _NSErrorWithErrno(errno, reading: true)
358+
}
359+
return amtRead
360+
#endif
361+
}
345362

346363
internal func _writeBytes(buf: UnsafeRawPointer, length: Int) throws {
347364
#if os(Windows)
@@ -426,6 +443,19 @@ open class FileHandle : NSObject, NSSecureCoding {
426443
}
427444
#endif
428445

446+
internal convenience init?(fileSystemRepresentation: UnsafePointer<Int8>, flags: Int32, createMode: Int) {
447+
#if os(Windows)
448+
var fd: Int = -1
449+
if let path = String(cString: fileSystemRepresentation).cString(using: .utf16) {
450+
fd = _CFOpenFileWithMode(path, flags, mode_t(createMode))
451+
}
452+
#else
453+
let fd = _CFOpenFileWithMode(fileSystemRepresentation, flags, mode_t(createMode))
454+
#endif
455+
guard fd > 0 else { return nil }
456+
self.init(fileDescriptor: fd, closeOnDealloc: true)
457+
}
458+
429459
deinit {
430460
// .close() tries to wait after operations in flight on the handle queue, if one exists, and then close. It does so by sending .sync { … } work to it.
431461
// if we try to do that here, we may end up in a situation where:

Foundation/FileManager.swift

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1720,32 +1720,23 @@ open class FileManager : NSObject {
17201720
#if os(Windows)
17211721
NSUnimplemented()
17221722
#else
1723-
let fd1 = open(file1Rep, O_RDONLY)
1724-
guard fd1 >= 0 else {
1725-
return false
1726-
}
1727-
defer { close(fd1) }
1728-
1729-
let fd2 = open(file2Rep, O_RDONLY)
1730-
guard fd2 >= 0 else {
1731-
return false
1732-
}
1733-
defer { close(fd2) }
1734-
1735-
let buffer1 = UnsafeMutablePointer<UInt8>.allocate(capacity: bufSize)
1736-
let buffer2 = UnsafeMutablePointer<UInt8>.allocate(capacity: bufSize)
1723+
guard let file1 = FileHandle(fileSystemRepresentation: file1Rep, flags: O_RDONLY, createMode: 0) else { return false }
1724+
guard let file2 = FileHandle(fileSystemRepresentation: file2Rep, flags: O_RDONLY, createMode: 0) else { return false }
1725+
1726+
var buffer1 = UnsafeMutablePointer<UInt8>.allocate(capacity: bufSize)
1727+
var buffer2 = UnsafeMutablePointer<UInt8>.allocate(capacity: bufSize)
17371728
defer {
17381729
buffer1.deallocate()
17391730
buffer2.deallocate()
17401731
}
1741-
17421732
var bytesLeft = size
17431733
while bytesLeft > 0 {
17441734
let bytesToRead = Int(min(Int64(bufSize), bytesLeft))
1745-
guard read(fd1, buffer1, bytesToRead) == bytesToRead else {
1735+
1736+
guard let file1BytesRead = try? file1._readBytes(into: buffer1, length: bytesToRead), file1BytesRead == bytesToRead else {
17461737
return false
17471738
}
1748-
guard read(fd2, buffer2, bytesToRead) == bytesToRead else {
1739+
guard let file2BytesRead = try? file2._readBytes(into: buffer2, length: bytesToRead), file2BytesRead == bytesToRead else {
17491740
return false
17501741
}
17511742
guard memcmp(buffer1, buffer2, bytesToRead) == 0 else {

0 commit comments

Comments
 (0)