From cf266ec2a73e48dcd67961a0e0cff87bf12d78f2 Mon Sep 17 00:00:00 2001 From: Jarred Sumner Date: Thu, 20 Feb 2025 13:14:56 -0800 Subject: [PATCH] fix --- src/fs.zig | 2 +- src/sys.zig | 8 ++++++++ src/windows_c.zig | 26 ++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/fs.zig b/src/fs.zig index aeb824680a..37f0002b10 100644 --- a/src/fs.zig +++ b/src/fs.zig @@ -1246,7 +1246,7 @@ pub const FileSystem = struct { const read_buf = try file.preadAll(buf, 0).unwrap(); const prev_file_pos = if (comptime Environment.isWindows) try file.getPos().unwrap() else 0; - if (comptime Environment.isWindows) try file.seekTo(prev_file_pos); + if (comptime Environment.isWindows) try file.seekTo(@intCast(prev_file_pos)); file_contents = buf[0..read_buf]; if (strings.BOM.detect(file_contents)) |bom| { diff --git a/src/sys.zig b/src/sys.zig index 684e5ad3bf..23512974ce 100644 --- a/src/sys.zig +++ b/src/sys.zig @@ -2101,6 +2101,14 @@ pub fn pread(fd: bun.FileDescriptor, buf: []u8, offset: i64) Maybe(usize) { } } + if (comptime Environment.isWindows) { + if (bun.FDImpl.decode(fd).kind == .uv) { + return sys_uv.pread(fd, buf, offset); + } + + return bun.C.readFile(fd, buf, @as(u64, @intCast(offset))); + } + const ioffset = @as(i64, @bitCast(offset)); // the OS treats this as unsigned while (true) { const rc = pread_sym(fd.cast(), buf.ptr, adjusted_len, ioffset); diff --git a/src/windows_c.zig b/src/windows_c.zig index 21a91e741f..520c76804b 100644 --- a/src/windows_c.zig +++ b/src/windows_c.zig @@ -1330,6 +1330,32 @@ pub fn moveOpenedFileAt( Maybe(void).errno(rc, .NtSetInformationFile); } +/// If buffer's length exceeds what a Windows DWORD integer can hold, it will be broken into +/// multiple non-atomic reads. +pub fn readFile(in_hFile: bun.FileDescriptor, buffer: []u8, offset: ?u64) Maybe(usize) { + const want_read_count: w.DWORD = @min(@as(w.DWORD, std.math.maxInt(w.DWORD)), buffer.len); + var amt_read: w.DWORD = undefined; + var overlapped_data: w.OVERLAPPED = undefined; + const overlapped: ?*w.OVERLAPPED = if (offset) |off| blk: { + overlapped_data = .{ + .Internal = 0, + .InternalHigh = 0, + .DUMMYUNIONNAME = .{ + .DUMMYSTRUCTNAME = .{ + .Offset = @as(u32, @truncate(off)), + .OffsetHigh = @as(u32, @truncate(off >> 32)), + }, + }, + .hEvent = null, + }; + break :blk &overlapped_data; + } else null; + if (w.kernel32.ReadFile(in_hFile.cast(), buffer.ptr, want_read_count, &amt_read, overlapped) == 0) { + return .{ .err = bun.sys.Error.fromCode(bun.windows.getLastErrno(), .read) }; + } + return .{ .result = amt_read }; +} + /// Same as moveOpenedFileAt but allows new_path to be a path relative to new_dir_fd. /// /// Aka: moveOpenedFileAtLoose(fd, dir, ".\\a\\relative\\not-normalized-path.txt", false);