From b1189ab038ad1885f961562bf188f0bd3da12153 Mon Sep 17 00:00:00 2001 From: Josh GM Walker <56300765+Josh-Walker-GM@users.noreply.github.com> Date: Thu, 4 Sep 2025 05:43:47 +0100 Subject: [PATCH] fix: std.fs.File.Writer.seekTo does not flush (#25135) * add failing test case * perform flush and allow error * dont over constrain flush error * reset seek error during conversion --- lib/std/fs/File.zig | 9 ++++++--- lib/std/fs/test.zig | 25 +++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/lib/std/fs/File.zig b/lib/std/fs/File.zig index 36e90371ab..c3ee06958b 100644 --- a/lib/std/fs/File.zig +++ b/lib/std/fs/File.zig @@ -1505,7 +1505,7 @@ pub const Writer = struct { sendfile_err: ?SendfileError = null, copy_file_range_err: ?CopyFileRangeError = null, fcopyfile_err: ?FcopyfileError = null, - seek_err: ?SeekError = null, + seek_err: ?Writer.SeekError = null, interface: std.Io.Writer, pub const Mode = Reader.Mode; @@ -1527,6 +1527,8 @@ pub const Writer = struct { Unexpected, }; + pub const SeekError = File.SeekError || std.Io.Writer.Error; + /// Number of slices to store on the stack, when trying to send as many byte /// vectors through the underlying write calls as possible. const max_buffers_len = 16; @@ -1570,7 +1572,7 @@ pub const Writer = struct { .mode = w.mode, .pos = w.pos, .interface = Reader.initInterface(w.interface.buffer), - .seek_err = w.seek_err, + .seek_err = null, }; } @@ -2000,7 +2002,8 @@ pub const Writer = struct { return n; } - pub fn seekTo(w: *Writer, offset: u64) SeekError!void { + pub fn seekTo(w: *Writer, offset: u64) Writer.SeekError!void { + try w.interface.flush(); switch (w.mode) { .positional, .positional_reading => { w.pos = offset; diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index 7afe322686..65e86e4c2e 100644 --- a/lib/std/fs/test.zig +++ b/lib/std/fs/test.zig @@ -2155,3 +2155,28 @@ test "seekBy" { try testing.expectEqual(15, n); try testing.expectEqualStrings("t's test seekBy", buffer[0..15]); } + +test "seekTo flushes buffered data" { + var tmp = std.testing.tmpDir(.{}); + defer tmp.cleanup(); + + const contents = "data"; + + const file = try tmp.dir.createFile("seek.bin", .{ .read = true }); + defer file.close(); + { + var buf: [16]u8 = undefined; + var file_writer = std.fs.File.writer(file, &buf); + + try file_writer.interface.writeAll(contents); + try file_writer.seekTo(8); + try file_writer.interface.flush(); + } + + var read_buffer: [16]u8 = undefined; + var file_reader: std.fs.File.Reader = .init(file, &read_buffer); + + var buf: [4]u8 = undefined; + try file_reader.interface.readSliceAll(&buf); + try std.testing.expectEqualStrings(contents, &buf); +}