authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-04-18 19:50:04-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-01 16:35:27-07:00
logcdd05df532511be471adb2006d89175335c0b980
tree11db4d94d72d24afaaab1a6d443c98e18b3f5147
parent00afaa4b1822e9d2c096830e546e96ab4e87f25b

std.io.BufferedReader: don't use a BufferedWriter field

this is way better with readVec and the ability to call `std.io.Reader.buffered`.

7 files changed, 70 insertions(+), 110 deletions(-)

lib/compiler/std-docs.zig+1-2
...@@ -92,10 +92,9 @@ fn accept(context: *Context, connection: std.net.Server.Connection) void {...@@ -92,10 +92,9 @@ fn accept(context: *Context, connection: std.net.Server.Connection) void {
9292
93 var recv_buffer: [8000]u8 = undefined;93 var recv_buffer: [8000]u8 = undefined;
94 var send_buffer: [4000]u8 = undefined;94 var send_buffer: [4000]u8 = undefined;
95 var connection_br: std.io.BufferedReader = undefined;
96 var stream_reader = connection.stream.reader();95 var stream_reader = connection.stream.reader();
97 connection_br.init(stream_reader.interface(), &recv_buffer);
98 var stream_writer = connection.stream.writer();96 var stream_writer = connection.stream.writer();
97 var connection_br = stream_reader.interface().buffered(&recv_buffer);
99 var connection_bw = stream_writer.interface().buffered(&send_buffer);98 var connection_bw = stream_writer.interface().buffered(&send_buffer);
100 var server = std.http.Server.init(&connection_br, &connection_bw);99 var server = std.http.Server.init(&connection_br, &connection_bw);
101100
lib/compiler/test_runner.zig+1-2
...@@ -71,8 +71,7 @@ fn mainServer() !void {...@@ -71,8 +71,7 @@ fn mainServer() !void {
71 @disableInstrumentation();71 @disableInstrumentation();
72 var stdin_reader = std.fs.File.stdin().reader();72 var stdin_reader = std.fs.File.stdin().reader();
73 var stdout_writer = std.fs.File.stdout().writer();73 var stdout_writer = std.fs.File.stdout().writer();
74 var stdin_buffered_reader: std.io.BufferedReader = undefined;74 var stdin_buffered_reader = stdin_reader.interface().buffered(&stdin_buffer);
75 stdin_buffered_reader.init(stdin_reader.interface(), &stdin_buffer);
76 var stdout_buffered_writer = stdout_writer.interface().buffered(&stdout_buffer);75 var stdout_buffered_writer = stdout_writer.interface().buffered(&stdout_buffer);
77 var server = try std.zig.Server.init(.{76 var server = try std.zig.Server.init(.{
78 .in = &stdin_buffered_reader,77 .in = &stdin_buffered_reader,
lib/std/debug/SelfInfo.zig+1-1
...@@ -2031,7 +2031,7 @@ pub const VirtualMachine = struct {...@@ -2031,7 +2031,7 @@ pub const VirtualMachine = struct {
20312031
2032 var prev_row: Row = self.current_row;2032 var prev_row: Row = self.current_row;
2033 for (&readers, [2]bool{ true, false }) |*reader, is_initial| {2033 for (&readers, [2]bool{ true, false }) |*reader, is_initial| {
2034 while (reader.seek < reader.storageBuffer().len) {2034 while (reader.seek < reader.buffer.len) {
2035 const instruction = try std.debug.Dwarf.call_frame.Instruction.read(reader, addr_size_bytes, endian);2035 const instruction = try std.debug.Dwarf.call_frame.Instruction.read(reader, addr_size_bytes, endian);
2036 prev_row = try self.step(allocator, cie, is_initial, instruction);2036 prev_row = try self.step(allocator, cie, is_initial, instruction);
2037 if (pc < fde.pc_begin + self.current_row.offset) return prev_row;2037 if (pc < fde.pc_begin + self.current_row.offset) return prev_row;
lib/std/io/BufferedReader.zig+52-101
...@@ -9,19 +9,12 @@ const Reader = std.io.Reader;...@@ -9,19 +9,12 @@ const Reader = std.io.Reader;
99
10const BufferedReader = @This();10const BufferedReader = @This();
1111
12/// Number of bytes which have been consumed from `storage`.
13seek: usize,
14storage: BufferedWriter,
15unbuffered_reader: Reader,12unbuffered_reader: Reader,
1613buffer: []u8,
17pub fn init(br: *BufferedReader, r: Reader, buffer: []u8) void {14/// In `buffer` before this are buffered bytes, after this is `undefined`.
18 br.* = .{15end: usize,
19 .seek = 0,16/// Number of bytes which have been consumed from `buffer`.
20 .storage = undefined,17seek: usize,
21 .unbuffered_reader = r,
22 };
23 br.storage.initFixed(buffer);
24}
2518
26/// Constructs `br` such that it will read from `buffer` and then end.19/// Constructs `br` such that it will read from `buffer` and then end.
27///20///
...@@ -29,25 +22,15 @@ pub fn init(br: *BufferedReader, r: Reader, buffer: []u8) void {...@@ -29,25 +22,15 @@ pub fn init(br: *BufferedReader, r: Reader, buffer: []u8) void {
29/// and if they are avoided then `buffer` can be safely used with `@constCast`.22/// and if they are avoided then `buffer` can be safely used with `@constCast`.
30pub fn initFixed(br: *BufferedReader, buffer: []u8) void {23pub fn initFixed(br: *BufferedReader, buffer: []u8) void {
31 br.* = .{24 br.* = .{
32 .seek = 0,
33 .storage = .{
34 .buffer = buffer,
35 .unbuffered_writer = .failing,
36 },
37 .unbuffered_reader = .ending,25 .unbuffered_reader = .ending,
26 .buffer = buffer,
27 .end = buffer.len,
28 .seek = 0,
38 };29 };
39}30}
4031
41pub fn storageBuffer(br: *BufferedReader) []u8 {
42 const storage = &br.storage;
43 assert(storage.unbuffered_writer.vtable == std.io.Writer.failing.vtable);
44 assert(br.unbuffered_reader.vtable == Reader.ending.vtable);
45 return storage.buffer;
46}
47
48pub fn bufferContents(br: *BufferedReader) []u8 {32pub fn bufferContents(br: *BufferedReader) []u8 {
49 const storage = &br.storage;33 return br.buffer[br.seek..br.end];
50 return storage.buffer[br.seek..storage.end];
51}34}
5235
53/// Although `BufferedReader` can easily satisfy the `Reader` interface, it's36/// Although `BufferedReader` can easily satisfy the `Reader` interface, it's
...@@ -65,8 +48,7 @@ pub fn reader(br: *BufferedReader) Reader {...@@ -65,8 +48,7 @@ pub fn reader(br: *BufferedReader) Reader {
6548
66fn passthruRead(ctx: ?*anyopaque, bw: *BufferedWriter, limit: Reader.Limit) Reader.RwError!usize {49fn passthruRead(ctx: ?*anyopaque, bw: *BufferedWriter, limit: Reader.Limit) Reader.RwError!usize {
67 const br: *BufferedReader = @alignCast(@ptrCast(ctx));50 const br: *BufferedReader = @alignCast(@ptrCast(ctx));
68 const storage = &br.storage;51 const buffer = br.buffer[0..br.end];
69 const buffer = storage.buffer[0..storage.end];
70 const buffered = buffer[br.seek..];52 const buffered = buffer[br.seek..];
71 const limited = buffered[0..limit.min(buffered.len)];53 const limited = buffered[0..limit.min(buffered.len)];
72 if (limited.len > 0) {54 if (limited.len > 0) {
...@@ -89,7 +71,7 @@ pub fn seekBy(br: *BufferedReader, seek_by: i64) !void {...@@ -89,7 +71,7 @@ pub fn seekBy(br: *BufferedReader, seek_by: i64) !void {
89}71}
9072
91pub fn seekBackwardBy(br: *BufferedReader, seek_by: u64) !void {73pub fn seekBackwardBy(br: *BufferedReader, seek_by: u64) !void {
92 if (seek_by > br.storage.end - br.seek) return error.Unseekable; // TODO74 if (seek_by > br.end - br.seek) return error.Unseekable; // TODO
93 br.seek += @abs(seek_by);75 br.seek += @abs(seek_by);
94}76}
9577
...@@ -115,10 +97,9 @@ pub fn seekForwardBy(br: *BufferedReader, seek_by: u64) !void {...@@ -115,10 +97,9 @@ pub fn seekForwardBy(br: *BufferedReader, seek_by: u64) !void {
115/// * `tryPeekArray`97/// * `tryPeekArray`
116/// * `toss`98/// * `toss`
117pub fn peek(br: *BufferedReader, n: usize) Reader.Error![]u8 {99pub fn peek(br: *BufferedReader, n: usize) Reader.Error![]u8 {
118 const storage = &br.storage;100 assert(n <= br.buffer.len);
119 assert(n <= storage.buffer.len);
120 try br.fill(n);101 try br.fill(n);
121 return storage.buffer[br.seek..][0..n];102 return br.buffer[br.seek..][0..n];
122}103}
123104
124/// Returns all the next buffered bytes from `unbuffered_reader`, after filling105/// Returns all the next buffered bytes from `unbuffered_reader`, after filling
...@@ -137,10 +118,9 @@ pub fn peek(br: *BufferedReader, n: usize) Reader.Error![]u8 {...@@ -137,10 +118,9 @@ pub fn peek(br: *BufferedReader, n: usize) Reader.Error![]u8 {
137/// * `tryPeekGreedy`118/// * `tryPeekGreedy`
138/// * `toss`119/// * `toss`
139pub fn peekGreedy(br: *BufferedReader, n: usize) Reader.Error![]u8 {120pub fn peekGreedy(br: *BufferedReader, n: usize) Reader.Error![]u8 {
140 const storage = &br.storage;121 assert(n <= br.buffer.len);
141 assert(n <= storage.buffer.len);
142 try br.fill(n);122 try br.fill(n);
143 return storage.buffer[br.seek..storage.end];123 return br.buffer[br.seek..br.end];
144}124}
145125
146/// Skips the next `n` bytes from the stream, advancing the seek position. This126/// Skips the next `n` bytes from the stream, advancing the seek position. This
...@@ -153,7 +133,7 @@ pub fn peekGreedy(br: *BufferedReader, n: usize) Reader.Error![]u8 {...@@ -153,7 +133,7 @@ pub fn peekGreedy(br: *BufferedReader, n: usize) Reader.Error![]u8 {
153/// * `discard`.133/// * `discard`.
154pub fn toss(br: *BufferedReader, n: usize) void {134pub fn toss(br: *BufferedReader, n: usize) void {
155 br.seek += n;135 br.seek += n;
156 assert(br.seek <= br.storage.end);136 assert(br.seek <= br.end);
157}137}
158138
159/// Equivalent to `peek` followed by `toss`.139/// Equivalent to `peek` followed by `toss`.
...@@ -207,15 +187,14 @@ pub fn discard(br: *BufferedReader, n: usize) Reader.Error!void {...@@ -207,15 +187,14 @@ pub fn discard(br: *BufferedReader, n: usize) Reader.Error!void {
207/// * `toss`187/// * `toss`
208/// * `discardRemaining`188/// * `discardRemaining`
209pub fn discardShort(br: *BufferedReader, n: usize) Reader.ShortError!usize {189pub fn discardShort(br: *BufferedReader, n: usize) Reader.ShortError!usize {
210 const storage = &br.storage;
211 const proposed_seek = br.seek + n;190 const proposed_seek = br.seek + n;
212 if (proposed_seek <= storage.end) {191 if (proposed_seek <= br.end) {
213 @branchHint(.likely);192 @branchHint(.likely);
214 br.seek = proposed_seek;193 br.seek = proposed_seek;
215 return n;194 return n;
216 }195 }
217 var remaining = n - (storage.end - br.seek);196 var remaining = n - (br.end - br.seek);
218 storage.end = 0;197 br.end = 0;
219 br.seek = 0;198 br.seek = 0;
220 while (true) {199 while (true) {
221 const discard_len = br.unbuffered_reader.discard(.limited(remaining)) catch |err| switch (err) {200 const discard_len = br.unbuffered_reader.discard(.limited(remaining)) catch |err| switch (err) {
...@@ -230,9 +209,8 @@ pub fn discardShort(br: *BufferedReader, n: usize) Reader.ShortError!usize {...@@ -230,9 +209,8 @@ pub fn discardShort(br: *BufferedReader, n: usize) Reader.ShortError!usize {
230/// Reads the stream until the end, ignoring all the data.209/// Reads the stream until the end, ignoring all the data.
231/// Returns the number of bytes discarded.210/// Returns the number of bytes discarded.
232pub fn discardRemaining(br: *BufferedReader) Reader.ShortError!usize {211pub fn discardRemaining(br: *BufferedReader) Reader.ShortError!usize {
233 const storage = &br.storage;212 const buffered_len = br.end;
234 const buffered_len = storage.end;213 br.end = 0;
235 storage.end = 0;
236 return buffered_len + try br.unbuffered_reader.discardRemaining();214 return buffered_len + try br.unbuffered_reader.discardRemaining();
237}215}
238216
...@@ -247,36 +225,25 @@ pub fn discardRemaining(br: *BufferedReader) Reader.ShortError!usize {...@@ -247,36 +225,25 @@ pub fn discardRemaining(br: *BufferedReader) Reader.ShortError!usize {
247/// See also:225/// See also:
248/// * `peek`226/// * `peek`
249pub fn read(br: *BufferedReader, buffer: []u8) Reader.Error!void {227pub fn read(br: *BufferedReader, buffer: []u8) Reader.Error!void {
250 const storage = &br.storage;228 const in_buffer = br.buffer[br.seek..br.end];
251 const in_buffer = storage.buffer[0..storage.end];229 const copy_len = @min(buffer.len, in_buffer.len);
252 const seek = br.seek;230 @memcpy(buffer[0..copy_len], in_buffer[0..copy_len]);
253 const proposed_seek = seek + in_buffer.len;231 if (copy_len == buffer.len) {
254 if (proposed_seek <= in_buffer.len) {232 br.seek += copy_len;
255 @memcpy(buffer, in_buffer[seek..proposed_seek]);
256 br.seek = proposed_seek;
257 return;233 return;
258 }234 }
259 @memcpy(buffer[0..in_buffer.len], in_buffer);235 var i: usize = copy_len;
260 storage.end = 0;236 br.end = 0;
261 br.seek = 0;237 br.seek = 0;
262 var i: usize = in_buffer.len;
263 while (true) {238 while (true) {
264 // TODO if remaining buffer len is greater than storage len, read directly into buffer239 const remaining = buffer[i..];
265 const read_len = br.unbuffered_reader.read(storage, .unlimited) catch |err| switch (err) {240 const n = try br.unbuffered_reader.readVec(&.{ remaining, br.buffer });
266 error.WriteFailed => storage.end,241 if (n < remaining.len) {
267 else => |e| return e,242 i += n;
268 };243 continue;
269 assert(read_len == storage.end);
270 const next_i = i + storage.end;
271 if (next_i >= buffer.len) {
272 const remaining = buffer[i..];
273 @memcpy(remaining, storage.buffer[0..remaining.len]);
274 br.seek = remaining.len;
275 return;
276 }244 }
277 @memcpy(buffer[i..next_i], storage.buffer[0..storage.end]);245 br.end = n - remaining.len;
278 storage.end = 0;246 return;
279 i = next_i;
280 }247 }
281}248}
282249
...@@ -365,8 +332,8 @@ pub const DelimiterExclusiveError = error{...@@ -365,8 +332,8 @@ pub const DelimiterExclusiveError = error{
365pub fn takeDelimiterExclusive(br: *BufferedReader, delimiter: u8) DelimiterExclusiveError![]u8 {332pub fn takeDelimiterExclusive(br: *BufferedReader, delimiter: u8) DelimiterExclusiveError![]u8 {
366 const result = br.peekDelimiterInclusiveUnlessEnd(delimiter) catch |err| switch (err) {333 const result = br.peekDelimiterInclusiveUnlessEnd(delimiter) catch |err| switch (err) {
367 error.EndOfStream => {334 error.EndOfStream => {
368 br.toss(br.storage.end);335 br.toss(br.end);
369 return br.storage.buffer[0..br.storage.end];336 return br.buffer[0..br.end];
370 },337 },
371 else => |e| return e,338 else => |e| return e,
372 };339 };
...@@ -376,15 +343,14 @@ pub fn takeDelimiterExclusive(br: *BufferedReader, delimiter: u8) DelimiterExclu...@@ -376,15 +343,14 @@ pub fn takeDelimiterExclusive(br: *BufferedReader, delimiter: u8) DelimiterExclu
376343
377pub fn peekDelimiterExclusive(br: *BufferedReader, delimiter: u8) DelimiterExclusiveError![]u8 {344pub fn peekDelimiterExclusive(br: *BufferedReader, delimiter: u8) DelimiterExclusiveError![]u8 {
378 const result = br.peekDelimiterInclusiveUnlessEnd(delimiter) catch |err| switch (err) {345 const result = br.peekDelimiterInclusiveUnlessEnd(delimiter) catch |err| switch (err) {
379 error.EndOfStream => return br.storage.buffer[0..br.storage.end],346 error.EndOfStream => return br.buffer[0..br.end],
380 else => |e| return e,347 else => |e| return e,
381 };348 };
382 return result[0 .. result.len - 1];349 return result[0 .. result.len - 1];
383}350}
384351
385fn peekDelimiterInclusiveUnlessEnd(br: *BufferedReader, delimiter: u8) DelimiterInclusiveError!?[]u8 {352fn peekDelimiterInclusiveUnlessEnd(br: *BufferedReader, delimiter: u8) DelimiterInclusiveError!?[]u8 {
386 const storage = &br.storage;353 const buffer = br.buffer[0..br.end];
387 const buffer = storage.buffer[0..storage.end];
388 const seek = br.seek;354 const seek = br.seek;
389 if (std.mem.indexOfScalarPos(u8, buffer, seek, delimiter)) |end| {355 if (std.mem.indexOfScalarPos(u8, buffer, seek, delimiter)) |end| {
390 @branchHint(.likely);356 @branchHint(.likely);
...@@ -392,24 +358,15 @@ fn peekDelimiterInclusiveUnlessEnd(br: *BufferedReader, delimiter: u8) Delimiter...@@ -392,24 +358,15 @@ fn peekDelimiterInclusiveUnlessEnd(br: *BufferedReader, delimiter: u8) Delimiter
392 }358 }
393 const remainder = buffer[seek..];359 const remainder = buffer[seek..];
394 std.mem.copyForwards(u8, buffer[0..remainder.len], remainder);360 std.mem.copyForwards(u8, buffer[0..remainder.len], remainder);
395 var i = remainder.len;361 br.end = remainder.len;
396 storage.end = i;
397 br.seek = 0;362 br.seek = 0;
398 while (i < storage.buffer.len) {363 while (br.end < br.buffer.len) {
399 const eos = eos: {364 const n = try br.unbuffered_reader.readVec(&.{br.buffer[br.end..]});
400 const read_len = br.unbuffered_reader.read(storage, .unlimited) catch |err| switch (err) {365 const prev_end = br.end;
401 error.WriteFailed => storage.end - i,366 br.end = prev_end + n;
402 error.ReadFailed => return error.ReadFailed,367 if (std.mem.indexOfScalarPos(u8, br.buffer[0..br.end], prev_end, delimiter)) |end| {
403 error.EndOfStream => break :eos true,368 return br.buffer[0 .. end + 1];
404 };
405 assert(read_len == storage.end - i);
406 break :eos false;
407 };
408 if (std.mem.indexOfScalarPos(u8, storage.buffer[0..storage.end], i, delimiter)) |end| {
409 return storage.buffer[0 .. end + 1];
410 }369 }
411 if (eos) return error.EndOfStream;
412 i = storage.end;
413 }370 }
414 return error.StreamTooLong;371 return error.StreamTooLong;
415}372}
...@@ -494,9 +451,8 @@ pub fn discardDelimiterExclusive(br: *BufferedReader, delimiter: u8) Reader.Shor...@@ -494,9 +451,8 @@ pub fn discardDelimiterExclusive(br: *BufferedReader, delimiter: u8) Reader.Shor
494///451///
495/// Asserts buffer capacity is at least `n`.452/// Asserts buffer capacity is at least `n`.
496pub fn fill(br: *BufferedReader, n: usize) Reader.Error!void {453pub fn fill(br: *BufferedReader, n: usize) Reader.Error!void {
497 const storage = &br.storage;454 assert(n <= br.buffer.len);
498 assert(n <= storage.buffer.len);455 const buffer = br.buffer[0..br.end];
499 const buffer = storage.buffer[0..storage.end];
500 const seek = br.seek;456 const seek = br.seek;
501 if (seek + n <= buffer.len) {457 if (seek + n <= buffer.len) {
502 @branchHint(.likely);458 @branchHint(.likely);
...@@ -504,22 +460,17 @@ pub fn fill(br: *BufferedReader, n: usize) Reader.Error!void {...@@ -504,22 +460,17 @@ pub fn fill(br: *BufferedReader, n: usize) Reader.Error!void {
504 }460 }
505 const remainder = buffer[seek..];461 const remainder = buffer[seek..];
506 std.mem.copyForwards(u8, buffer[0..remainder.len], remainder);462 std.mem.copyForwards(u8, buffer[0..remainder.len], remainder);
507 storage.end = remainder.len;463 br.end = remainder.len;
508 br.seek = 0;464 br.seek = 0;
509 while (true) {465 while (true) {
510 const read_len = br.unbuffered_reader.read(storage, .unlimited) catch |err| switch (err) {466 br.end += try br.unbuffered_reader.readVec(&.{br.buffer[br.end..]});
511 error.WriteFailed => storage.end - remainder.len,467 if (n <= br.end) return;
512 else => |e| return e,
513 };
514 assert(storage.end == remainder.len + read_len);
515 if (n <= storage.end) return;
516 }468 }
517}469}
518470
519/// Reads 1 byte from the stream or returns `error.EndOfStream`.471/// Reads 1 byte from the stream or returns `error.EndOfStream`.
520pub fn takeByte(br: *BufferedReader) Reader.Error!u8 {472pub fn takeByte(br: *BufferedReader) Reader.Error!u8 {
521 const storage = &br.storage;473 const buffer = br.buffer[0..br.end];
522 const buffer = storage.buffer[0..storage.end];
523 const seek = br.seek;474 const seek = br.seek;
524 if (seek >= buffer.len) {475 if (seek >= buffer.len) {
525 @branchHint(.unlikely);476 @branchHint(.unlikely);
lib/std/io/BufferedWriter.zig+1-2
...@@ -17,8 +17,7 @@ const testing = std.testing;...@@ -17,8 +17,7 @@ const testing = std.testing;
17unbuffered_writer: Writer,17unbuffered_writer: Writer,
18/// If this has length zero, the writer is unbuffered, and `flush` is a no-op.18/// If this has length zero, the writer is unbuffered, and `flush` is a no-op.
19buffer: []u8,19buffer: []u8,
20/// Marks the end of `buffer` - before this are buffered bytes, after this is20/// In `buffer` before this are buffered bytes, after this is `undefined`.
21/// undefined.
22end: usize = 0,21end: usize = 0,
23/// Tracks total number of bytes written to this `BufferedWriter`. This value22/// Tracks total number of bytes written to this `BufferedWriter`. This value
24/// only increases. In the case of fixed mode, this value always equals `end`.23/// only increases. In the case of fixed mode, this value always equals `end`.
lib/std/io/Reader.zig+13
...@@ -197,6 +197,19 @@ pub const ending: Reader = .{...@@ -197,6 +197,19 @@ pub const ending: Reader = .{
197 },197 },
198};198};
199199
200pub fn unbuffered(r: Reader) std.io.BufferedReader {
201 return buffered(r, &.{});
202}
203
204pub fn buffered(r: Reader, buffer: []u8) std.io.BufferedReader {
205 return .{
206 .unbuffered_reader = r,
207 .seek = 0,
208 .buffer = buffer,
209 .end = 0,
210 };
211}
212
200fn endingRead(context: ?*anyopaque, bw: *BufferedWriter, limit: Limit) RwError!usize {213fn endingRead(context: ?*anyopaque, bw: *BufferedWriter, limit: Limit) RwError!usize {
201 _ = context;214 _ = context;
202 _ = bw;215 _ = bw;
lib/std/process/Child.zig+1-2
...@@ -1012,8 +1012,7 @@ fn writeIntFd(fd: i32, value: ErrInt) !void {...@@ -1012,8 +1012,7 @@ fn writeIntFd(fd: i32, value: ErrInt) !void {
1012fn readIntFd(fd: i32) !ErrInt {1012fn readIntFd(fd: i32) !ErrInt {
1013 var fr = std.fs.File.reader(.{ .handle = fd });1013 var fr = std.fs.File.reader(.{ .handle = fd });
1014 var buffer: [8]u8 = undefined;1014 var buffer: [8]u8 = undefined;
1015 var br: std.io.BufferedReader = undefined;1015 var br = fr.interface().buffered(&buffer);
1016 br.init(fr.interface(), &buffer);
1017 return @intCast(br.takeInt(u64, .little) catch return error.SystemResources);1016 return @intCast(br.takeInt(u64, .little) catch return error.SystemResources);
1018}1017}
10191018