authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-11-16 10:37:23+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-11-16 14:35:28-07:00
log9e1e91dafc9857b41a513c6c6506150f1a2f3f7f
tree6554bf3976f30175494c6655937193b380396de8
parent6624f9cd5c2d747224990fb9ba3e2b830a68f3e4

std: Make windows.ReadFile allow short reads

Make it behave like the read() wrapper for unix systems. Reading the whole buffer breaks some use-cases like buffered readers over sockets. Closes #7121

1 files changed, 8 insertions(+), 11 deletions(-)

lib/std/os/windows.zig+8-11
...@@ -442,33 +442,30 @@ pub fn ReadFile(in_hFile: HANDLE, buffer: []u8, offset: ?u64, io_mode: std.io.Mo...@@ -442,33 +442,30 @@ pub fn ReadFile(in_hFile: HANDLE, buffer: []u8, offset: ?u64, io_mode: std.io.Mo
442 }442 }
443 return @as(usize, bytes_transferred);443 return @as(usize, bytes_transferred);
444 } else {444 } else {
445 var index: usize = 0;445 while (true) {
446 while (index < buffer.len) {446 const want_read_count = @intCast(DWORD, math.min(@as(DWORD, maxInt(DWORD)), buffer.len));
447 const want_read_count = @intCast(DWORD, math.min(@as(DWORD, maxInt(DWORD)), buffer.len - index));
448 var amt_read: DWORD = undefined;447 var amt_read: DWORD = undefined;
449 var overlapped_data: OVERLAPPED = undefined;448 var overlapped_data: OVERLAPPED = undefined;
450 const overlapped: ?*OVERLAPPED = if (offset) |off| blk: {449 const overlapped: ?*OVERLAPPED = if (offset) |off| blk: {
451 overlapped_data = .{450 overlapped_data = .{
452 .Internal = 0,451 .Internal = 0,
453 .InternalHigh = 0,452 .InternalHigh = 0,
454 .Offset = @truncate(u32, off + index),453 .Offset = @truncate(u32, off),
455 .OffsetHigh = @truncate(u32, (off + index) >> 32),454 .OffsetHigh = @truncate(u32, off >> 32),
456 .hEvent = null,455 .hEvent = null,
457 };456 };
458 break :blk &overlapped_data;457 break :blk &overlapped_data;
459 } else null;458 } else null;
460 if (kernel32.ReadFile(in_hFile, buffer.ptr + index, want_read_count, &amt_read, overlapped) == 0) {459 if (kernel32.ReadFile(in_hFile, buffer.ptr, want_read_count, &amt_read, overlapped) == 0) {
461 switch (kernel32.GetLastError()) {460 switch (kernel32.GetLastError()) {
462 .OPERATION_ABORTED => continue,461 .OPERATION_ABORTED => continue,
463 .BROKEN_PIPE => return index,462 .BROKEN_PIPE => return 0,
464 .HANDLE_EOF => return index,463 .HANDLE_EOF => return 0,
465 else => |err| return unexpectedError(err),464 else => |err| return unexpectedError(err),
466 }465 }
467 }466 }
468 if (amt_read == 0) return index;467 return amt_read;
469 index += amt_read;
470 }468 }
471 return index;
472 }469 }
473}470}
474471