Skip to content

Commit a5660a5

Browse files
authored
Merge pull request #1898 from spevans/pr_truncate_file_fix_42
[4.2] FileHandle.truncateFile should reposition on truncate
2 parents d34a1d8 + c151322 commit a5660a5

File tree

2 files changed

+30
-5
lines changed

2 files changed

+30
-5
lines changed

Foundation/FileHandle.swift

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,14 +143,13 @@ open class FileHandle : NSObject, NSSecureCoding {
143143
precondition(_fd >= 0, "Bad file descriptor")
144144
lseek(_fd, off_t(offset), SEEK_SET)
145145
}
146-
146+
147147
open func truncateFile(atOffset offset: UInt64) {
148148
precondition(_fd >= 0, "Bad file descriptor")
149-
if lseek(_fd, off_t(offset), SEEK_SET) == 0 {
150-
ftruncate(_fd, off_t(offset))
151-
}
149+
if lseek(_fd, off_t(offset), SEEK_SET) < 0 { fatalError("lseek() failed.") }
150+
if ftruncate(_fd, off_t(offset)) < 0 { fatalError("ftruncate() failed.") }
152151
}
153-
152+
154153
open func synchronizeFile() {
155154
precondition(_fd >= 0, "Bad file descriptor")
156155
fsync(_fd)

TestFoundation/TestFileHandle.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class TestFileHandle : XCTestCase {
1212
return [
1313
("test_constants", test_constants),
1414
("test_nullDevice", test_nullDevice),
15+
("test_truncate", test_truncate),
1516
]
1617
}
1718

@@ -38,4 +39,29 @@ class TestFileHandle : XCTestCase {
3839
fh.seek(toFileOffset: 0)
3940
XCTAssertEqual(fh.readDataToEndOfFile().count, 0)
4041
}
42+
43+
func test_truncate() throws {
44+
let fm = FileManager.default
45+
let tempDir = fm.temporaryDirectory
46+
let filePath = tempDir.appendingPathComponent("temp_file")
47+
guard fm.createFile(atPath: filePath.path, contents: nil, attributes: nil) else {
48+
XCTAssertTrue(false, "Unable to create temporary file");
49+
return
50+
}
51+
guard let fh = FileHandle(forWritingAtPath: filePath.path) else {
52+
XCTAssertTrue(false, "Unable to open temporary file")
53+
return
54+
}
55+
defer { try? fm.removeItem(atPath: filePath.path) }
56+
57+
for newSize: UInt64 in [0, 100, 5, 1] {
58+
fh.truncateFile(atOffset: newSize)
59+
guard let size = (try fm.attributesOfItem(atPath: filePath.path))[.size] as? NSNumber else {
60+
XCTFail("Cant get size")
61+
continue
62+
}
63+
XCTAssertEqual(newSize, size.uint64Value)
64+
XCTAssertEqual(newSize, fh.offsetInFile)
65+
}
66+
}
4167
}

0 commit comments

Comments
 (0)