Hi folks, I’m finding a confusing behaviour with the new IO reader API, during my zig development. Let me know if I’m missing something.
I’m trying to read the headers of a kernel file using a buffer instead of a file reader:
var gpa = std.heap.DebugAllocator(.{}){};
defer _ = gpa.deinit();
const alloc = gpa.allocator();
var file = try std.Io.Dir.cwd().openFile(
io,
kernel_file_path,
.{.allow_directory = true}
);
defer file.close(io);
var read_buf: [4096]u8 = undefined;
var reader = file.reader(io, &read_buf);
const kernel_buf = try reader.interface.readAlloc(alloc, kernel_stats.size);
defer alloc.free(kernel_buf);
std.debug.print(\\
\\seek: {d}
\\end: {d}
\\kernel size: {d}
\\
, .{reader.interface.seek, reader.interface.end, kernel_stats.size});
const header = try std.elf.Header.read(&reader.interface);
std.debug.print(
\\seek: {d}
\\end: {d}
\\kernel size: {d}
\\
, .{reader.interface.seek, reader.interface.end, kernel_stats.size});
var iter = std.elf.Header.iterateProgramHeadersBuffer(
&header,
kernel_buf
);
When I run it, I reach an EOS but the r.interface.seek and r.interface.end are not modified.
error: 'test.test.read-parse-kernel' failed:
HELLOOO
.{ .handle = -100 }
seek: 0
end: 0
kernel size: 2663757
/snap/zig/16117/lib/std/Io/File/Reader.zig:267:9: 0x1057889 in readVecPositional (test)
return error.EndOfStream;
^
However std.elf.Header.read(&reader.interface) actually modifies seek/end possitions, if I do it before reading the entire file with readAlloc
error: 'test.test.read-parse-kernel' failed:
HELLOOO
.{ .handle = -100 }
seek: 64
end: 4096
kernel size: 2663757
Diving into the source code I saw std.elf.Header.read uses r.peek and readAlloc uses readSliceAll, which ends up using defaultReadVec providing it the allocated buffer.
If my understanding is correct, defaultReadVec, writes to the reader buffer or the provided one, depending whichone is bigger.
In my case the allocated (kernel size) buffer will be bigger so problem may be there?
Anyways I find it confusing when I’m trying to debug it. I expected to see an updated seek/end variable of the reader before reaching EOS.
Any thoughts on it?