| author | |
| committer | |
| log | 8a80b5464022a9fb4320e37f9dfc2aa83539ff07 |
| tree | 0fd5f5d40f3e9d1f600622f1c3554e95c7129aed |
| parent | fdf1ee973e9f3cb01f6fec9e460950622cdf92e4 |
and make reading file streaming allowed to return 0 byte reads.
According to Microsoft documentation, on Windows it is possible to get
0-byte reads from pipes when 0-byte writes are made.8 files changed, 82 insertions(+), 96 deletions(-)
lib/std/Io.zig+4-4| ... | @@ -187,7 +187,7 @@ pub const VTable = struct { | ... | @@ -187,7 +187,7 @@ pub const VTable = struct { |
| 187 | fileWritePositional: *const fn (?*anyopaque, File, header: []const u8, data: []const []const u8, splat: usize, offset: u64) File.WritePositionalError!usize, | 187 | fileWritePositional: *const fn (?*anyopaque, File, header: []const u8, data: []const []const u8, splat: usize, offset: u64) File.WritePositionalError!usize, |
| 188 | fileWriteFileStreaming: *const fn (?*anyopaque, File, header: []const u8, *Io.File.Reader, Io.Limit) File.Writer.WriteFileError!usize, | 188 | fileWriteFileStreaming: *const fn (?*anyopaque, File, header: []const u8, *Io.File.Reader, Io.Limit) File.Writer.WriteFileError!usize, |
| 189 | fileWriteFilePositional: *const fn (?*anyopaque, File, header: []const u8, *Io.File.Reader, Io.Limit, offset: u64) File.WriteFilePositionalError!usize, | 189 | fileWriteFilePositional: *const fn (?*anyopaque, File, header: []const u8, *Io.File.Reader, Io.Limit, offset: u64) File.WriteFilePositionalError!usize, |
| 190 | /// Returns 0 on end of stream. | 190 | /// Returns 0 if reading at or past the end. |
| 191 | fileReadPositional: *const fn (?*anyopaque, File, data: []const []u8, offset: u64) File.ReadPositionalError!usize, | 191 | fileReadPositional: *const fn (?*anyopaque, File, data: []const []u8, offset: u64) File.ReadPositionalError!usize, |
| 192 | fileSeekBy: *const fn (?*anyopaque, File, relative_offset: i64) File.SeekError!void, | 192 | fileSeekBy: *const fn (?*anyopaque, File, relative_offset: i64) File.SeekError!void, |
| 193 | fileSeekTo: *const fn (?*anyopaque, File, absolute_offset: u64) File.SeekError!void, | 193 | fileSeekTo: *const fn (?*anyopaque, File, absolute_offset: u64) File.SeekError!void, |
| ... | @@ -263,18 +263,18 @@ pub const Operation = union(enum) { | ... | @@ -263,18 +263,18 @@ pub const Operation = union(enum) { |
| 263 | status: Status(void) = .{ .unstarted = {} }, | 263 | status: Status(void) = .{ .unstarted = {} }, |
| 264 | }; | 264 | }; |
| 265 | 265 | ||
| 266 | /// Returns 0 on end of stream. | 266 | /// May return 0 reads which is different than `error.EndOfStream`. |
| 267 | pub const FileReadStreaming = struct { | 267 | pub const FileReadStreaming = struct { |
| 268 | file: File, | 268 | file: File, |
| 269 | data: []const []u8, | 269 | data: []const []u8, |
| 270 | status: Status(Error!usize) = .{ .unstarted = {} }, | 270 | status: Status(Error!usize) = .{ .unstarted = {} }, |
| 271 | 271 | ||
| 272 | pub const Error = error{ | 272 | pub const Error = UnendingError || error{EndOfStream}; |
| 273 | pub const UnendingError = error{ | ||
| 273 | InputOutput, | 274 | InputOutput, |
| 274 | SystemResources, | 275 | SystemResources, |
| 275 | /// Trying to read a directory file descriptor as if it were a file. | 276 | /// Trying to read a directory file descriptor as if it were a file. |
| 276 | IsDir, | 277 | IsDir, |
| 277 | BrokenPipe, | ||
| 278 | ConnectionResetByPeer, | 278 | ConnectionResetByPeer, |
| 279 | /// File was not opened with read capability. | 279 | /// File was not opened with read capability. |
| 280 | NotOpenForReading, | 280 | NotOpenForReading, |
lib/std/Io/File.zig+3-2| ... | @@ -552,11 +552,13 @@ pub fn setTimestampsNow(file: File, io: Io) SetTimestampsError!void { | ... | @@ -552,11 +552,13 @@ pub fn setTimestampsNow(file: File, io: Io) SetTimestampsError!void { |
| 552 | }); | 552 | }); |
| 553 | } | 553 | } |
| 554 | 554 | ||
| 555 | pub const ReadStreamingError = error{EndOfStream} || Reader.Error; | ||
| 556 | |||
| 555 | /// Returns 0 on stream end or if `buffer` has no space available for data. | 557 | /// Returns 0 on stream end or if `buffer` has no space available for data. |
| 556 | /// | 558 | /// |
| 557 | /// See also: | 559 | /// See also: |
| 558 | /// * `reader` | 560 | /// * `reader` |
| 559 | pub fn readStreaming(file: File, io: Io, buffer: []const []u8) Reader.Error!usize { | 561 | pub fn readStreaming(file: File, io: Io, buffer: []const []u8) ReadStreamingError!usize { |
| 560 | var operation: Io.Operation = .{ .file_read_streaming = .{ | 562 | var operation: Io.Operation = .{ .file_read_streaming = .{ |
| 561 | .file = file, | 563 | .file = file, |
| 562 | .data = buffer, | 564 | .data = buffer, |
| ... | @@ -570,7 +572,6 @@ pub const ReadPositionalError = error{ | ... | @@ -570,7 +572,6 @@ pub const ReadPositionalError = error{ |
| 570 | SystemResources, | 572 | SystemResources, |
| 571 | /// Trying to read a directory file descriptor as if it were a file. | 573 | /// Trying to read a directory file descriptor as if it were a file. |
| 572 | IsDir, | 574 | IsDir, |
| 573 | BrokenPipe, | ||
| 574 | /// Non-blocking has been enabled, and reading from the file descriptor | 575 | /// Non-blocking has been enabled, and reading from the file descriptor |
| 575 | /// would block. | 576 | /// would block. |
| 576 | WouldBlock, | 577 | WouldBlock, |
lib/std/Io/File/MultiReader.zig+5-9| ... | @@ -15,10 +15,9 @@ pub const Context = struct { | ... | @@ -15,10 +15,9 @@ pub const Context = struct { |
| 15 | fr: File.Reader, | 15 | fr: File.Reader, |
| 16 | vec: [1][]u8, | 16 | vec: [1][]u8, |
| 17 | err: ?Error, | 17 | err: ?Error, |
| 18 | eos: bool, | ||
| 19 | }; | 18 | }; |
| 20 | 19 | ||
| 21 | pub const Error = Allocator.Error || File.Reader.Error || Io.ConcurrentError; | 20 | pub const Error = Allocator.Error || File.ReadStreamingError || Io.ConcurrentError; |
| 22 | 21 | ||
| 23 | /// Trailing: | 22 | /// Trailing: |
| 24 | /// * `contexts: [len]Context` | 23 | /// * `contexts: [len]Context` |
| ... | @@ -85,7 +84,6 @@ pub fn init(mr: *MultiReader, gpa: Allocator, io: Io, streams: *Streams, files: | ... | @@ -85,7 +84,6 @@ pub fn init(mr: *MultiReader, gpa: Allocator, io: Io, streams: *Streams, files: |
| 85 | }, | 84 | }, |
| 86 | .vec = .{&.{}}, | 85 | .vec = .{&.{}}, |
| 87 | .err = null, | 86 | .err = null, |
| 88 | .eos = false, | ||
| 89 | }; | 87 | }; |
| 90 | const operations = streams.operations(); | 88 | const operations = streams.operations(); |
| 91 | const ring = streams.ring(); | 89 | const ring = streams.ring(); |
| ... | @@ -198,8 +196,10 @@ fn fillUntimed(context: *Context, capacity: usize) Io.Reader.Error!void { | ... | @@ -198,8 +196,10 @@ fn fillUntimed(context: *Context, capacity: usize) Io.Reader.Error!void { |
| 198 | }, | 196 | }, |
| 199 | error.EndOfStream => |e| return e, | 197 | error.EndOfStream => |e| return e, |
| 200 | }; | 198 | }; |
| 201 | if (context.err != null) return error.ReadFailed; | 199 | if (context.err) |err| switch (err) { |
| 202 | if (context.eos) return error.EndOfStream; | 200 | error.EndOfStream => |e| return e, |
| 201 | else => return error.ReadFailed, | ||
| 202 | }; | ||
| 203 | } | 203 | } |
| 204 | 204 | ||
| 205 | pub const FillError = Io.Batch.WaitError || error{ | 205 | pub const FillError = Io.Batch.WaitError || error{ |
| ... | @@ -225,10 +225,6 @@ pub fn fill(mr: *MultiReader, unused_capacity: usize, timeout: Io.Timeout) FillE | ... | @@ -225,10 +225,6 @@ pub fn fill(mr: *MultiReader, unused_capacity: usize, timeout: Io.Timeout) FillE |
| 225 | context.err = err; | 225 | context.err = err; |
| 226 | continue; | 226 | continue; |
| 227 | }; | 227 | }; |
| 228 | if (n == 0) { | ||
| 229 | context.eos = true; | ||
| 230 | continue; | ||
| 231 | } | ||
| 232 | const r = &context.fr.interface; | 228 | const r = &context.fr.interface; |
| 233 | r.end += n; | 229 | r.end += n; |
| 234 | if (r.buffer.len - r.end < unused_capacity) { | 230 | if (r.buffer.len - r.end < unused_capacity) { |
lib/std/Io/File/Reader.zig+19-15| ... | @@ -26,7 +26,7 @@ size_err: ?SizeError = null, | ... | @@ -26,7 +26,7 @@ size_err: ?SizeError = null, |
| 26 | seek_err: ?SeekError = null, | 26 | seek_err: ?SeekError = null, |
| 27 | interface: Io.Reader, | 27 | interface: Io.Reader, |
| 28 | 28 | ||
| 29 | pub const Error = Io.Operation.FileReadStreaming.Error || Io.Cancelable; | 29 | pub const Error = Io.Operation.FileReadStreaming.UnendingError || Io.Cancelable; |
| 30 | 30 | ||
| 31 | pub const SizeError = File.StatError || error{ | 31 | pub const SizeError = File.StatError || error{ |
| 32 | /// Occurs if, for example, the file handle is a network socket and therefore does not have a size. | 32 | /// Occurs if, for example, the file handle is a network socket and therefore does not have a size. |
| ... | @@ -280,14 +280,16 @@ fn readVecStreaming(r: *Reader, data: [][]u8) Io.Reader.Error!usize { | ... | @@ -280,14 +280,16 @@ fn readVecStreaming(r: *Reader, data: [][]u8) Io.Reader.Error!usize { |
| 280 | const dest_n, const data_size = try r.interface.writableVector(&iovecs_buffer, data); | 280 | const dest_n, const data_size = try r.interface.writableVector(&iovecs_buffer, data); |
| 281 | const dest = iovecs_buffer[0..dest_n]; | 281 | const dest = iovecs_buffer[0..dest_n]; |
| 282 | assert(dest[0].len > 0); | 282 | assert(dest[0].len > 0); |
| 283 | const n = r.file.readStreaming(io, dest) catch |err| { | 283 | const n = r.file.readStreaming(io, dest) catch |err| switch (err) { |
| 284 | r.err = err; | 284 | error.EndOfStream => { |
| 285 | return error.ReadFailed; | 285 | r.size = r.pos; |
| 286 | return error.EndOfStream; | ||
| 287 | }, | ||
| 288 | else => |e| { | ||
| 289 | r.err = e; | ||
| 290 | return error.ReadFailed; | ||
| 291 | }, | ||
| 286 | }; | 292 | }; |
| 287 | if (n == 0) { | ||
| 288 | r.size = r.pos; | ||
| 289 | return error.EndOfStream; | ||
| 290 | } | ||
| 291 | r.pos += n; | 293 | r.pos += n; |
| 292 | if (n > data_size) { | 294 | if (n > data_size) { |
| 293 | r.interface.end += n - data_size; | 295 | r.interface.end += n - data_size; |
| ... | @@ -335,14 +337,16 @@ fn discard(io_reader: *Io.Reader, limit: Io.Limit) Io.Reader.Error!usize { | ... | @@ -335,14 +337,16 @@ fn discard(io_reader: *Io.Reader, limit: Io.Limit) Io.Reader.Error!usize { |
| 335 | const dest_n, const data_size = try r.interface.writableVector(&iovecs_buffer, &data); | 337 | const dest_n, const data_size = try r.interface.writableVector(&iovecs_buffer, &data); |
| 336 | const dest = iovecs_buffer[0..dest_n]; | 338 | const dest = iovecs_buffer[0..dest_n]; |
| 337 | assert(dest[0].len > 0); | 339 | assert(dest[0].len > 0); |
| 338 | const n = file.readStreaming(io, dest) catch |err| { | 340 | const n = file.readStreaming(io, dest) catch |err| switch (err) { |
| 339 | r.err = err; | 341 | error.EndOfStream => { |
| 340 | return error.ReadFailed; | 342 | r.size = r.pos; |
| 343 | return error.EndOfStream; | ||
| 344 | }, | ||
| 345 | else => |e| { | ||
| 346 | r.err = e; | ||
| 347 | return error.ReadFailed; | ||
| 348 | }, | ||
| 341 | }; | 349 | }; |
| 342 | if (n == 0) { | ||
| 343 | r.size = r.pos; | ||
| 344 | return error.EndOfStream; | ||
| 345 | } | ||
| 346 | r.pos += n; | 350 | r.pos += n; |
| 347 | if (n > data_size) { | 351 | if (n > data_size) { |
| 348 | r.interface.end += n - data_size; | 352 | r.interface.end += n - data_size; |
lib/std/Io/Threaded.zig+35-50| ... | @@ -8583,14 +8583,14 @@ fn fileClose(userdata: ?*anyopaque, files: []const File) void { | ... | @@ -8583,14 +8583,14 @@ fn fileClose(userdata: ?*anyopaque, files: []const File) void { |
| 8583 | for (files) |file| posix.close(file.handle); | 8583 | for (files) |file| posix.close(file.handle); |
| 8584 | } | 8584 | } |
| 8585 | 8585 | ||
| 8586 | fn fileReadStreaming(userdata: ?*anyopaque, file: File, data: []const []u8) File.Reader.Error!usize { | 8586 | fn fileReadStreaming(userdata: ?*anyopaque, file: File, data: []const []u8) File.ReadStreamingError!usize { |
| 8587 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | 8587 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 8588 | _ = t; | 8588 | _ = t; |
| 8589 | if (is_windows) return fileReadStreamingWindows(file, data); | 8589 | if (is_windows) return fileReadStreamingWindows(file, data); |
| 8590 | return fileReadStreamingPosix(file, data); | 8590 | return fileReadStreamingPosix(file, data); |
| 8591 | } | 8591 | } |
| 8592 | 8592 | ||
| 8593 | fn fileReadStreamingPosix(file: File, data: []const []u8) File.Reader.Error!usize { | 8593 | fn fileReadStreamingPosix(file: File, data: []const []u8) File.ReadStreamingError!usize { |
| 8594 | var iovecs_buffer: [max_iovecs_len]posix.iovec = undefined; | 8594 | var iovecs_buffer: [max_iovecs_len]posix.iovec = undefined; |
| 8595 | var i: usize = 0; | 8595 | var i: usize = 0; |
| 8596 | for (data) |buf| { | 8596 | for (data) |buf| { |
| ... | @@ -8611,28 +8611,24 @@ fn fileReadStreamingPosix(file: File, data: []const []u8) File.Reader.Error!usiz | ... | @@ -8611,28 +8611,24 @@ fn fileReadStreamingPosix(file: File, data: []const []u8) File.Reader.Error!usiz |
| 8611 | switch (std.os.wasi.fd_read(file.handle, dest.ptr, dest.len, &nread)) { | 8611 | switch (std.os.wasi.fd_read(file.handle, dest.ptr, dest.len, &nread)) { |
| 8612 | .SUCCESS => { | 8612 | .SUCCESS => { |
| 8613 | syscall.finish(); | 8613 | syscall.finish(); |
| 8614 | if (nread == 0) return error.EndOfStream; | ||
| 8614 | return nread; | 8615 | return nread; |
| 8615 | }, | 8616 | }, |
| 8616 | .INTR, .TIMEDOUT => { | 8617 | .INTR, .TIMEDOUT => { |
| 8617 | try syscall.checkCancel(); | 8618 | try syscall.checkCancel(); |
| 8618 | continue; | 8619 | continue; |
| 8619 | }, | 8620 | }, |
| 8620 | else => |e| { | 8621 | .BADF => return syscall.fail(error.IsDir), // File operation on directory. |
| 8621 | syscall.finish(); | 8622 | .IO => return syscall.fail(error.InputOutput), |
| 8622 | switch (e) { | 8623 | .ISDIR => return syscall.fail(error.IsDir), |
| 8623 | .INVAL => |err| return errnoBug(err), | 8624 | .NOBUFS => return syscall.fail(error.SystemResources), |
| 8624 | .FAULT => |err| return errnoBug(err), | 8625 | .NOMEM => return syscall.fail(error.SystemResources), |
| 8625 | .BADF => return error.IsDir, // File operation on directory. | 8626 | .NOTCONN => return syscall.fail(error.SocketUnconnected), |
| 8626 | .IO => return error.InputOutput, | 8627 | .CONNRESET => return syscall.fail(error.ConnectionResetByPeer), |
| 8627 | .ISDIR => return error.IsDir, | 8628 | .NOTCAPABLE => return syscall.fail(error.AccessDenied), |
| 8628 | .NOBUFS => return error.SystemResources, | 8629 | .INVAL => |err| return syscall.errnoBug(err), |
| 8629 | .NOMEM => return error.SystemResources, | 8630 | .FAULT => |err| return syscall.errnoBug(err), |
| 8630 | .NOTCONN => return error.SocketUnconnected, | 8631 | else => |err| return syscall.unexpectedErrno(err), |
| 8631 | .CONNRESET => return error.ConnectionResetByPeer, | ||
| 8632 | .NOTCAPABLE => return error.AccessDenied, | ||
| 8633 | else => |err| return posix.unexpectedErrno(err), | ||
| 8634 | } | ||
| 8635 | }, | ||
| 8636 | } | 8632 | } |
| 8637 | } | 8633 | } |
| 8638 | } | 8634 | } |
| ... | @@ -8643,36 +8639,33 @@ fn fileReadStreamingPosix(file: File, data: []const []u8) File.Reader.Error!usiz | ... | @@ -8643,36 +8639,33 @@ fn fileReadStreamingPosix(file: File, data: []const []u8) File.Reader.Error!usiz |
| 8643 | switch (posix.errno(rc)) { | 8639 | switch (posix.errno(rc)) { |
| 8644 | .SUCCESS => { | 8640 | .SUCCESS => { |
| 8645 | syscall.finish(); | 8641 | syscall.finish(); |
| 8642 | if (rc == 0) return error.EndOfStream; | ||
| 8646 | return @intCast(rc); | 8643 | return @intCast(rc); |
| 8647 | }, | 8644 | }, |
| 8648 | .INTR, .TIMEDOUT => { | 8645 | .INTR, .TIMEDOUT => { |
| 8649 | try syscall.checkCancel(); | 8646 | try syscall.checkCancel(); |
| 8650 | continue; | 8647 | continue; |
| 8651 | }, | 8648 | }, |
| 8652 | else => |e| { | 8649 | .BADF => { |
| 8653 | syscall.finish(); | 8650 | syscall.finish(); |
| 8654 | switch (e) { | 8651 | if (native_os == .wasi) return error.IsDir; // File operation on directory. |
| 8655 | .INVAL => |err| return errnoBug(err), | 8652 | return error.NotOpenForReading; |
| 8656 | .FAULT => |err| return errnoBug(err), | ||
| 8657 | .AGAIN => return error.WouldBlock, | ||
| 8658 | .BADF => { | ||
| 8659 | if (native_os == .wasi) return error.IsDir; // File operation on directory. | ||
| 8660 | return error.NotOpenForReading; | ||
| 8661 | }, | ||
| 8662 | .IO => return error.InputOutput, | ||
| 8663 | .ISDIR => return error.IsDir, | ||
| 8664 | .NOBUFS => return error.SystemResources, | ||
| 8665 | .NOMEM => return error.SystemResources, | ||
| 8666 | .NOTCONN => return error.SocketUnconnected, | ||
| 8667 | .CONNRESET => return error.ConnectionResetByPeer, | ||
| 8668 | else => |err| return posix.unexpectedErrno(err), | ||
| 8669 | } | ||
| 8670 | }, | 8653 | }, |
| 8654 | .AGAIN => return syscall.fail(error.WouldBlock), | ||
| 8655 | .IO => return syscall.fail(error.InputOutput), | ||
| 8656 | .ISDIR => return syscall.fail(error.IsDir), | ||
| 8657 | .NOBUFS => return syscall.fail(error.SystemResources), | ||
| 8658 | .NOMEM => return syscall.fail(error.SystemResources), | ||
| 8659 | .NOTCONN => return syscall.fail(error.SocketUnconnected), | ||
| 8660 | .CONNRESET => return syscall.fail(error.ConnectionResetByPeer), | ||
| 8661 | .INVAL => |err| return syscall.errnoBug(err), | ||
| 8662 | .FAULT => |err| return syscall.errnoBug(err), | ||
| 8663 | else => |err| return syscall.unexpectedErrno(err), | ||
| 8671 | } | 8664 | } |
| 8672 | } | 8665 | } |
| 8673 | } | 8666 | } |
| 8674 | 8667 | ||
| 8675 | fn fileReadStreamingWindows(file: File, data: []const []u8) File.Reader.Error!usize { | 8668 | fn fileReadStreamingWindows(file: File, data: []const []u8) File.ReadStreamingError!usize { |
| 8676 | var io_status_block: windows.IO_STATUS_BLOCK = undefined; | 8669 | var io_status_block: windows.IO_STATUS_BLOCK = undefined; |
| 8677 | if (ntReadFile(file.handle, data, &io_status_block)) |result| switch (result) { | 8670 | if (ntReadFile(file.handle, data, &io_status_block)) |result| switch (result) { |
| 8678 | .status => return ntReadFileResult(&io_status_block), | 8671 | .status => return ntReadFileResult(&io_status_block), |
| ... | @@ -8707,11 +8700,9 @@ fn fileReadStreamingWindows(file: File, data: []const []u8) File.Reader.Error!us | ... | @@ -8707,11 +8700,9 @@ fn fileReadStreamingWindows(file: File, data: []const []u8) File.Reader.Error!us |
| 8707 | 8700 | ||
| 8708 | fn ntReadFileResult(io_status_block: *windows.IO_STATUS_BLOCK) !usize { | 8701 | fn ntReadFileResult(io_status_block: *windows.IO_STATUS_BLOCK) !usize { |
| 8709 | switch (io_status_block.u.Status) { | 8702 | switch (io_status_block.u.Status) { |
| 8710 | .SUCCESS => { | 8703 | .SUCCESS => return io_status_block.Information, |
| 8711 | assert(io_status_block.Information != 0); | 8704 | .END_OF_FILE => return error.EndOfStream, |
| 8712 | return io_status_block.Information; | 8705 | .PIPE_BROKEN => return error.EndOfStream, |
| 8713 | }, | ||
| 8714 | .END_OF_FILE, .PIPE_BROKEN => return 0, | ||
| 8715 | .PENDING => unreachable, | 8706 | .PENDING => unreachable, |
| 8716 | .INVALID_DEVICE_REQUEST => return error.IsDir, | 8707 | .INVALID_DEVICE_REQUEST => return error.IsDir, |
| 8717 | .LOCK_NOT_GRANTED => return error.LockViolation, | 8708 | .LOCK_NOT_GRANTED => return error.LockViolation, |
| ... | @@ -8749,15 +8740,9 @@ fn ntReadFile(handle: windows.HANDLE, data: []const []u8, iosb: *windows.IO_STAT | ... | @@ -8749,15 +8740,9 @@ fn ntReadFile(handle: windows.HANDLE, data: []const []u8, iosb: *windows.IO_STAT |
| 8749 | return .pending; | 8740 | return .pending; |
| 8750 | }, | 8741 | }, |
| 8751 | .SUCCESS => { | 8742 | .SUCCESS => { |
| 8752 | // Only END_OF_FILE is the true end. | 8743 | syscall.finish(); |
| 8753 | if (iosb.Information == 0) { | 8744 | iosb.u.Status = .SUCCESS; |
| 8754 | try syscall.checkCancel(); | 8745 | return .status; |
| 8755 | continue; | ||
| 8756 | } else { | ||
| 8757 | syscall.finish(); | ||
| 8758 | iosb.u.Status = .SUCCESS; | ||
| 8759 | return .status; | ||
| 8760 | } | ||
| 8761 | }, | 8746 | }, |
| 8762 | .CANCELLED => { | 8747 | .CANCELLED => { |
| 8763 | try syscall.checkCancel(); | 8748 | try syscall.checkCancel(); |
lib/std/Progress.zig+1-2| ... | @@ -984,7 +984,7 @@ fn serializeIpc(start_serialized_len: usize, serialized_buffer: *Serialized.Buff | ... | @@ -984,7 +984,7 @@ fn serializeIpc(start_serialized_len: usize, serialized_buffer: *Serialized.Buff |
| 984 | var bytes_read: usize = 0; | 984 | var bytes_read: usize = 0; |
| 985 | while (true) { | 985 | while (true) { |
| 986 | const n = file.readStreaming(io, &.{pipe_buf[bytes_read..]}) catch |err| switch (err) { | 986 | const n = file.readStreaming(io, &.{pipe_buf[bytes_read..]}) catch |err| switch (err) { |
| 987 | error.WouldBlock => break, | 987 | error.WouldBlock, error.EndOfStream => break, |
| 988 | else => |e| { | 988 | else => |e| { |
| 989 | std.log.debug("failed to read child progress data: {t}", .{e}); | 989 | std.log.debug("failed to read child progress data: {t}", .{e}); |
| 990 | main_storage.completed_count = 0; | 990 | main_storage.completed_count = 0; |
| ... | @@ -992,7 +992,6 @@ fn serializeIpc(start_serialized_len: usize, serialized_buffer: *Serialized.Buff | ... | @@ -992,7 +992,6 @@ fn serializeIpc(start_serialized_len: usize, serialized_buffer: *Serialized.Buff |
| 992 | continue :main_loop; | 992 | continue :main_loop; |
| 993 | }, | 993 | }, |
| 994 | }; | 994 | }; |
| 995 | if (n == 0) break; | ||
| 996 | if (opt_saved_metadata) |m| { | 995 | if (opt_saved_metadata) |m| { |
| 997 | if (m.remaining_read_trash_bytes > 0) { | 996 | if (m.remaining_read_trash_bytes > 0) { |
| 998 | assert(bytes_read == 0); | 997 | assert(bytes_read == 0); |
lib/std/process/Child.zig+15-13| ... | @@ -176,19 +176,21 @@ pub fn collectOutput(child: *const Child, io: Io, options: CollectOutputOptions) | ... | @@ -176,19 +176,21 @@ pub fn collectOutput(child: *const Child, io: Io, options: CollectOutputOptions) |
| 176 | while (remaining > 0) { | 176 | while (remaining > 0) { |
| 177 | try batch.wait(io, options.timeout); | 177 | try batch.wait(io, options.timeout); |
| 178 | while (batch.next()) |op| { | 178 | while (batch.next()) |op| { |
| 179 | const n = try reads[op].file_read_streaming.status.result; | 179 | const n = reads[op].file_read_streaming.status.result catch |err| switch (err) { |
| 180 | if (n == 0) { | 180 | error.EndOfStream => { |
| 181 | remaining -= 1; | 181 | remaining -= 1; |
| 182 | } else { | 182 | continue; |
| 183 | lists[op].items.len += n; | 183 | }, |
| 184 | if (lists[op].items.len > @intFromEnum(limits[op])) return error.StreamTooLong; | 184 | else => |e| return e, |
| 185 | if (options.allocator) |gpa| try lists[op].ensureUnusedCapacity(gpa, 1); | 185 | }; |
| 186 | const cap = lists[op].unusedCapacitySlice(); | 186 | lists[op].items.len += n; |
| 187 | if (cap.len == 0) return error.StreamTooLong; | 187 | if (lists[op].items.len > @intFromEnum(limits[op])) return error.StreamTooLong; |
| 188 | vecs[op][0] = cap; | 188 | if (options.allocator) |gpa| try lists[op].ensureUnusedCapacity(gpa, 1); |
| 189 | reads[op].file_read_streaming.status = .{ .unstarted = {} }; | 189 | const cap = lists[op].unusedCapacitySlice(); |
| 190 | batch.add(op); | 190 | if (cap.len == 0) return error.StreamTooLong; |
| 191 | } | 191 | vecs[op][0] = cap; |
| 192 | reads[op].file_read_streaming.status = .{ .unstarted = {} }; | ||
| 193 | batch.add(op); | ||
| 192 | } | 194 | } |
| 193 | } | 195 | } |
| 194 | } | 196 | } |
lib/std/zig/system.zig-1| ... | @@ -420,7 +420,6 @@ pub fn resolveTargetQuery(io: Io, query: Target.Query) DetectError!Target { | ... | @@ -420,7 +420,6 @@ pub fn resolveTargetQuery(io: Io, query: Target.Query) DetectError!Target { |
| 420 | error.Canceled => |e| return e, | 420 | error.Canceled => |e| return e, |
| 421 | error.Unexpected => |e| return e, | 421 | error.Unexpected => |e| return e, |
| 422 | error.WouldBlock => return error.Unexpected, | 422 | error.WouldBlock => return error.Unexpected, |
| 423 | error.BrokenPipe => return error.Unexpected, | ||
| 424 | error.ConnectionResetByPeer => return error.Unexpected, | 423 | error.ConnectionResetByPeer => return error.Unexpected, |
| 425 | error.NotOpenForReading => return error.Unexpected, | 424 | error.NotOpenForReading => return error.Unexpected, |
| 426 | error.SocketUnconnected => return error.Unexpected, | 425 | error.SocketUnconnected => return error.Unexpected, |