zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 3bb2f7b84ed8b1ee09b6077f66e28ab7291a7bd4 (tree)
parent f306a9f84a006a6429f485a6c99ac26723f1e1e4
Author: Matthew Lugg <mlugg@mlugg.co.uk>
Date:   Wed, 31 Dec 2025 13:11:05 +0000

std.Io.net: don't swallow 'error.Canceled'

This was missed when updating to the new group cancelation API, and
caused illegal behavior in many cases (the condition was simply that a
DNS query returned a second result before a connection was successfully
established).

Diffstat:
Mlib/std/Io/net/HostName.zig | 22+++++++++-------------
1 file changed, 9 insertions(+), 13 deletions(-)

diff --git a/lib/std/Io/net/HostName.zig b/lib/std/Io/net/HostName.zig @@ -233,11 +233,12 @@ pub fn connect( if (result) |stream| { return stream; } else |err| switch (err) { + error.Canceled => unreachable, + error.SystemResources, error.OptionUnsupported, error.ProcessFdQuotaExceeded, error.SystemFdQuotaExceeded, - error.Canceled, => |e| return e, error.WouldBlock => return error.Unexpected, @@ -259,6 +260,8 @@ pub fn connect( /// Asynchronously establishes a connection to all IP addresses associated with /// a host name, adding them to a results queue upon completion. /// +/// `error.Canceled` will never be added to the queue, but other errors may be. +/// /// Closes `results` before return, even on error. /// /// Asserts `results` is not closed until this call returns. @@ -299,22 +302,15 @@ fn enqueueConnection( io: Io, queue: *Io.Queue(IpAddress.ConnectError!Stream), options: IpAddress.ConnectOptions, -) void { - enqueueConnectionFallible(address, io, queue, options) catch |err| switch (err) { - error.Canceled => {}, - }; -} -fn enqueueConnectionFallible( - address: IpAddress, - io: Io, - queue: *Io.Queue(IpAddress.ConnectError!Stream), - options: IpAddress.ConnectOptions, ) Io.Cancelable!void { - const result = address.connect(io, options); + const result = address.connect(io, options) catch |err| switch (err) { + error.Canceled => |e| return e, + else => |e| e, // other errors go in the result queue + }; errdefer if (result) |s| s.close(io) else |_| {}; queue.putOne(io, result) catch |err| switch (err) { - error.Closed => unreachable, // `queue` must not be closed error.Canceled => |e| return e, + error.Closed => unreachable, // `queue` must not be closed }; }