std.Io.File: fix stat for Windows

This commit is contained in:
Andrew Kelley 2025-10-27 17:49:21 -07:00
parent 6b8972dd22
commit 135ec79f50
2 changed files with 17 additions and 21 deletions

View File

@ -395,10 +395,6 @@ pub const Reader = struct {
pub fn getSize(r: *Reader) SizeError!u64 { pub fn getSize(r: *Reader) SizeError!u64 {
return r.size orelse { return r.size orelse {
if (r.size_err) |err| return err; if (r.size_err) |err| return err;
if (std.posix.Stat == void) {
r.size_err = error.Streaming;
return error.Streaming;
}
if (stat(r.file, r.io)) |st| { if (stat(r.file, r.io)) |st| {
if (st.kind == .file) { if (st.kind == .file) {
r.size = st.size; r.size = st.size;

View File

@ -2557,19 +2557,21 @@ fn fileReadStreamingPosix(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io
fn fileReadStreamingWindows(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io.File.ReadStreamingError!usize { fn fileReadStreamingWindows(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io.File.ReadStreamingError!usize {
const t: *Threaded = @ptrCast(@alignCast(userdata)); const t: *Threaded = @ptrCast(@alignCast(userdata));
try t.checkCancel();
const DWORD = windows.DWORD; const DWORD = windows.DWORD;
var index: usize = 0; var index: usize = 0;
while (data[index].len == 0) index += 1; while (data[index].len == 0) index += 1;
const buffer = data[index]; const buffer = data[index];
const want_read_count: DWORD = @min(std.math.maxInt(DWORD), buffer.len); const want_read_count: DWORD = @min(std.math.maxInt(DWORD), buffer.len);
while (true) {
try t.checkCancel();
var n: DWORD = undefined; var n: DWORD = undefined;
if (windows.kernel32.ReadFile(file.handle, buffer.ptr, want_read_count, &n, null) == 0) { if (windows.kernel32.ReadFile(file.handle, buffer.ptr, want_read_count, &n, null) != 0)
return n;
switch (windows.GetLastError()) { switch (windows.GetLastError()) {
.IO_PENDING => |err| return windows.errorBug(err), .IO_PENDING => |err| return windows.errorBug(err),
.OPERATION_ABORTED => return error.Canceled, .OPERATION_ABORTED => continue,
.BROKEN_PIPE => return 0, .BROKEN_PIPE => return 0,
.HANDLE_EOF => return 0, .HANDLE_EOF => return 0,
.NETNAME_DELETED => return error.ConnectionResetByPeer, .NETNAME_DELETED => return error.ConnectionResetByPeer,
@ -2579,7 +2581,6 @@ fn fileReadStreamingWindows(userdata: ?*anyopaque, file: Io.File, data: [][]u8)
else => |err| return windows.unexpectedError(err), else => |err| return windows.unexpectedError(err),
} }
} }
return n;
} }
fn fileReadPositionalPosix(userdata: ?*anyopaque, file: Io.File, data: [][]u8, offset: u64) Io.File.ReadPositionalError!usize { fn fileReadPositionalPosix(userdata: ?*anyopaque, file: Io.File, data: [][]u8, offset: u64) Io.File.ReadPositionalError!usize {
@ -2661,33 +2662,34 @@ const fileReadPositional = switch (native_os) {
fn fileReadPositionalWindows(userdata: ?*anyopaque, file: Io.File, data: [][]u8, offset: u64) Io.File.ReadPositionalError!usize { fn fileReadPositionalWindows(userdata: ?*anyopaque, file: Io.File, data: [][]u8, offset: u64) Io.File.ReadPositionalError!usize {
const t: *Threaded = @ptrCast(@alignCast(userdata)); const t: *Threaded = @ptrCast(@alignCast(userdata));
try t.checkCancel();
const DWORD = windows.DWORD; const DWORD = windows.DWORD;
const OVERLAPPED = windows.OVERLAPPED;
var index: usize = 0; var index: usize = 0;
while (data[index].len == 0) index += 1; while (data[index].len == 0) index += 1;
const buffer = data[index]; const buffer = data[index];
const want_read_count: DWORD = @min(std.math.maxInt(DWORD), buffer.len); const want_read_count: DWORD = @min(std.math.maxInt(DWORD), buffer.len);
var n: DWORD = undefined;
var overlapped: OVERLAPPED = .{ var overlapped: windows.OVERLAPPED = .{
.Internal = 0, .Internal = 0,
.InternalHigh = 0, .InternalHigh = 0,
.DUMMYUNIONNAME = .{ .DUMMYUNIONNAME = .{
.DUMMYSTRUCTNAME = .{ .DUMMYSTRUCTNAME = .{
.Offset = @as(u32, @truncate(offset)), .Offset = @truncate(offset),
.OffsetHigh = @as(u32, @truncate(offset >> 32)), .OffsetHigh = @truncate(offset >> 32),
}, },
}, },
.hEvent = null, .hEvent = null,
}; };
if (windows.kernel32.ReadFile(file.handle, buffer.ptr, want_read_count, &n, &overlapped) == 0) { while (true) {
try t.checkCancel();
var n: DWORD = undefined;
if (windows.kernel32.ReadFile(file.handle, buffer.ptr, want_read_count, &n, &overlapped) != 0)
return n;
switch (windows.GetLastError()) { switch (windows.GetLastError()) {
.IO_PENDING => |err| return windows.errorBug(err), .IO_PENDING => |err| return windows.errorBug(err),
.OPERATION_ABORTED => return error.Canceled, .OPERATION_ABORTED => continue,
.BROKEN_PIPE => return 0, .BROKEN_PIPE => return 0,
.HANDLE_EOF => return 0, .HANDLE_EOF => return 0,
.NETNAME_DELETED => return error.ConnectionResetByPeer, .NETNAME_DELETED => return error.ConnectionResetByPeer,
@ -2697,8 +2699,6 @@ fn fileReadPositionalWindows(userdata: ?*anyopaque, file: Io.File, data: [][]u8,
else => |err| return windows.unexpectedError(err), else => |err| return windows.unexpectedError(err),
} }
} }
return n;
} }
fn fileSeekBy(userdata: ?*anyopaque, file: Io.File, offset: i64) Io.File.SeekError!void { fn fileSeekBy(userdata: ?*anyopaque, file: Io.File, offset: i64) Io.File.SeekError!void {