diff --git a/lib/std/Io/Dispatch.zig b/lib/std/Io/Dispatch.zig index 8c1ba1c80559390bb39eb06dd1dccb054b80b9bf..851ed34156737103639d12f03170e74bd2500e79 100644 --- a/lib/std/Io/Dispatch.zig +++ b/lib/std/Io/Dispatch.zig @@ -4908,7 +4908,7 @@ fn netWriteFileUnavailable( _ = header; _ = file_reader; _ = limit; - return error.NetworkDown; + return error.Unimplemented; } fn netClose(userdata: ?*anyopaque, handles: []const net.Socket.Handle) void { diff --git a/lib/std/Io/Threaded.zig b/lib/std/Io/Threaded.zig index d4b202e12d0fa9087716209c24215bc179d71c1a..52b530c8eb11acb08083589ba865e0fa733b226c 100644 --- a/lib/std/Io/Threaded.zig +++ b/lib/std/Io/Threaded.zig @@ -11378,7 +11378,8 @@ fn netWriteFile( _ = header; _ = file_reader; _ = limit; - @panic("TODO implement netWriteFile"); + // TODO implement netWriteFile + return error.Unimplemented; } fn fileWriteFilePositional( diff --git a/lib/std/Io/Uring.zig b/lib/std/Io/Uring.zig index e560500a755281510f64954d12040b1b6c5504b4..436406174b5643ef3c50df54e8e65b12ba5bd597 100644 --- a/lib/std/Io/Uring.zig +++ b/lib/std/Io/Uring.zig @@ -5183,7 +5183,7 @@ fn netWriteFileUnavailable( _ = header; _ = file_reader; _ = limit; - return error.NetworkDown; + return error.Unimplemented; } fn netClose(userdata: ?*anyopaque, handles: []const net.Socket.Handle) void { diff --git a/lib/std/Io/net.zig b/lib/std/Io/net.zig index 6611502cc157238167445e516cb5ea5b6a0af832..a546552cb9c7bb24ced83e88fbae4946f21a7061 100644 --- a/lib/std/Io/net.zig +++ b/lib/std/Io/net.zig @@ -1350,9 +1350,17 @@ pub const Stream = struct { SocketNotBound, } || Io.UnexpectedError || Io.Cancelable; - pub const WriteFileError = error{ - NetworkDown, - } || Io.Cancelable || Io.UnexpectedError; + pub const WriteFileError = Error || error{ + /// The `Io` implementation cannot offer a more efficient + /// file-to-socket path; the caller should fall back to read-based + /// copying. See `Io.Writer.sendFile`. + Unimplemented, + /// Reached the end of the file being read. + EndOfStream, + /// The source `File.Reader` failed; detailed diagnostics are found + /// on that struct. + ReadFailed, + }; pub fn init(stream: Stream, io: Io, buffer: []u8) Writer { return .{ @@ -1381,10 +1389,25 @@ pub const Stream = struct { } fn sendFile(io_w: *Io.Writer, file_reader: *Io.File.Reader, limit: Io.Limit) Io.Writer.FileError!usize { - _ = io_w; - _ = file_reader; - _ = limit; - return error.Unimplemented; // TODO + const w: *Writer = @alignCast(@fieldParentPtr("interface", io_w)); + const io = w.io; + const header = io_w.buffered(); + const handle = w.stream.socket.handle; + const n = io.vtable.netWriteFile(io.userdata, handle, header, file_reader, limit) catch |err| switch (err) { + error.Canceled => { + w.err = error.Canceled; + return error.WriteFailed; + }, + error.EndOfStream, + error.Unimplemented, + error.ReadFailed, + => |e| return e, + else => |e| { + w.write_file_err = e; + return error.WriteFailed; + }, + }; + return io_w.consume(n); } };