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
This commit is contained in:
Josh GM Walker 2025-09-04 05:43:47 +01:00 committed by GitHub
parent 32a34b64ca
commit b1189ab038
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 31 additions and 3 deletions

View file

@ -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;

View file

@ -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);
}