From 2a1db652654892ef4c9d8b3b5b4e2b5d4e48739a Mon Sep 17 00:00:00 2001 From: cirospaciari Date: Fri, 29 Mar 2024 19:25:00 -0300 Subject: [PATCH] report continue errors and fix closing --- src/io/PipeReader.zig | 32 ++++++++++++++++++++++++-------- src/io/source.zig | 1 + 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/io/PipeReader.zig b/src/io/PipeReader.zig index 0d52722aff..5d9b7dd1cf 100644 --- a/src/io/PipeReader.zig +++ b/src/io/PipeReader.zig @@ -376,24 +376,38 @@ pub fn WindowsPipeReader( var this: *This = bun.cast(*This, fs.data); bun.sys.syslog("onFileRead({}) = {d}", .{ bun.toFD(fs.file.fd), nread_int }); - this.flags.is_paused = true; switch (nread_int) { // 0 actually means EOF too 0, uv.UV_EOF => { + this.flags.is_paused = true; this.onRead(.{ .result = 0 }, "", .eof); }, + // UV_ECANCELED needs to be on the top so we avoid UAF uv.UV_ECANCELED => unreachable, else => { if (fs.result.toError(.read)) |err| { + this.flags.is_paused = true; this.onRead(.{ .err = err }, "", .progress); return; } - // continue reading defer { - // we check if someone unpaused after the onRead callback + // if we are not paused we keep reading until EOF or err if (!this.flags.is_paused) { - _ = this.startReading(); + if (this.source) |source| { + if (source == .file) { + const file = source.file; + file.fs.deinit(); + source.setData(this); + const buf = this.getReadBufferWithStableMemoryAddress(64 * 1024); + file.iov = uv.uv_buf_t.init(buf); + if (uv.uv_fs_read(uv.Loop.get(), &file.fs, file.file, @ptrCast(&file.iov), 1, -1, onFileRead).toError(.write)) |err| { + this.flags.is_paused = true; + // we should inform the error if we are unable to keep reading + this.onRead(.{ .err = err }, "", .progress); + } + } + } } } @@ -458,9 +472,11 @@ pub fn WindowsPipeReader( if (this.source) |source| { switch (source) { .sync_file, .file => |file| { - file.fs.deinit(); - file.fs.data = file; - _ = uv.uv_fs_close(uv.Loop.get(), &source.file.fs, source.file.file, @ptrCast(&onFileClose)); + // we need a new fs_t to close the file + // the current one is used for reading/canceling + // we dont wanna to free any data that is being used in uv loop + file.close_fs.data = file; + _ = uv.uv_fs_close(uv.Loop.get(), &file.close_fs, file.file, @ptrCast(&onFileClose)); }, .pipe => |pipe| { pipe.data = pipe; @@ -490,7 +506,7 @@ pub fn WindowsPipeReader( fn onFileClose(handle: *uv.fs_t) callconv(.C) void { const file = bun.cast(*Source.File, handle.data); - file.fs.deinit(); + handle.deinit(); bun.default_allocator.destroy(file); } diff --git a/src/io/source.zig b/src/io/source.zig index b001c32780..18cc83aeef 100644 --- a/src/io/source.zig +++ b/src/io/source.zig @@ -15,6 +15,7 @@ pub const Source = union(enum) { pub const File = struct { fs: uv.fs_t, + close_fs: uv.fs_t, iov: uv.uv_buf_t, file: uv.uv_file, };