authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-10-17 00:09:25-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-10-29 06:20:50-07:00
loge87ceb76c242cf991f85c9aa6619f5faf4059af3
tree10ad0dc4c5f56c74d5a387cfab9c311c41274873
parentcf6fa219fd05b9f2c01e85557bcd140e72802459

std.Io.net.Server: refine AcceptError set


3 files changed, 60 insertions(+), 76 deletions(-)

lib/std/Io/Threaded.zig+39-37
......@@ -898,7 +898,7 @@ fn dirMakePosix(userdata: ?*anyopaque, dir: Io.Dir, sub_path: []const u8, mode:
898898 .CANCELED => return error.Canceled,
899899
900900 .ACCES => return error.AccessDenied,
901 .BADF => |err| return errnoBug(err),
901 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
902902 .PERM => return error.PermissionDenied,
903903 .DQUOT => return error.DiskQuota,
904904 .EXIST => return error.PathAlreadyExists,
......@@ -930,7 +930,7 @@ fn dirMakeWasi(userdata: ?*anyopaque, dir: Io.Dir, sub_path: []const u8, mode: I
930930 .CANCELED => return error.Canceled,
931931
932932 .ACCES => return error.AccessDenied,
933 .BADF => |err| return errnoBug(err),
933 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
934934 .PERM => return error.PermissionDenied,
935935 .DQUOT => return error.DiskQuota,
936936 .EXIST => return error.PathAlreadyExists,
......@@ -989,7 +989,7 @@ fn dirStatPathLinux(
989989 .CANCELED => return error.Canceled,
990990
991991 .ACCES => return error.AccessDenied,
992 .BADF => |err| return errnoBug(err),
992 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
993993 .FAULT => |err| return errnoBug(err),
994994 .INVAL => |err| return errnoBug(err),
995995 .LOOP => return error.SymLinkLoop,
......@@ -1024,7 +1024,7 @@ fn dirStatPathPosix(
10241024 .CANCELED => return error.Canceled,
10251025
10261026 .INVAL => |err| return errnoBug(err),
1027 .BADF => |err| return errnoBug(err), // Always a race condition.
1027 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
10281028 .NOMEM => return error.SystemResources,
10291029 .ACCES => return error.AccessDenied,
10301030 .PERM => return error.PermissionDenied,
......@@ -1060,7 +1060,7 @@ fn dirStatPathWasi(
10601060 .CANCELED => return error.Canceled,
10611061
10621062 .INVAL => |err| return errnoBug(err),
1063 .BADF => |err| return errnoBug(err), // Always a race condition.
1063 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
10641064 .NOMEM => return error.SystemResources,
10651065 .ACCES => return error.AccessDenied,
10661066 .FAULT => |err| return errnoBug(err),
......@@ -1088,7 +1088,7 @@ fn fileStatPosix(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File
10881088 .CANCELED => return error.Canceled,
10891089
10901090 .INVAL => |err| return errnoBug(err),
1091 .BADF => |err| return errnoBug(err),
1091 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
10921092 .NOMEM => return error.SystemResources,
10931093 .ACCES => return error.AccessDenied,
10941094 else => |err| return posix.unexpectedErrno(err),
......@@ -1115,7 +1115,7 @@ fn fileStatLinux(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File
11151115 .CANCELED => return error.Canceled,
11161116
11171117 .ACCES => |err| return errnoBug(err),
1118 .BADF => |err| return errnoBug(err),
1118 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
11191119 .FAULT => |err| return errnoBug(err),
11201120 .INVAL => |err| return errnoBug(err),
11211121 .LOOP => |err| return errnoBug(err),
......@@ -1147,7 +1147,7 @@ fn fileStatWasi(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File.
11471147 .CANCELED => return error.Canceled,
11481148
11491149 .INVAL => |err| return errnoBug(err),
1150 .BADF => |err| return errnoBug(err),
1150 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
11511151 .NOMEM => return error.SystemResources,
11521152 .ACCES => return error.AccessDenied,
11531153 .NOTCAPABLE => return error.AccessDenied,
......@@ -1220,7 +1220,7 @@ fn dirAccessWasi(
12201220 .CANCELED => return error.Canceled,
12211221
12221222 .INVAL => |err| return errnoBug(err),
1223 .BADF => |err| return errnoBug(err), // Always a race condition.
1223 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
12241224 .NOMEM => return error.SystemResources,
12251225 .ACCES => return error.AccessDenied,
12261226 .FAULT => |err| return errnoBug(err),
......@@ -1305,7 +1305,7 @@ fn dirCreateFilePosix(
13051305
13061306 .FAULT => |err| return errnoBug(err),
13071307 .INVAL => return error.BadPathName,
1308 .BADF => |err| return errnoBug(err),
1308 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
13091309 .ACCES => return error.AccessDenied,
13101310 .FBIG => return error.FileTooBig,
13111311 .OVERFLOW => return error.FileTooBig,
......@@ -1347,7 +1347,7 @@ fn dirCreateFilePosix(
13471347 .INTR => continue,
13481348 .CANCELED => return error.Canceled,
13491349
1350 .BADF => |err| return errnoBug(err),
1350 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
13511351 .INVAL => |err| return errnoBug(err), // invalid parameters
13521352 .NOLCK => return error.SystemResources,
13531353 .AGAIN => return error.WouldBlock,
......@@ -1427,7 +1427,7 @@ fn dirCreateFileWasi(
14271427 .FAULT => |err| return errnoBug(err),
14281428 // Provides INVAL with a linux host on a bad path name, but NOENT on Windows
14291429 .INVAL => return error.BadPathName,
1430 .BADF => |err| return errnoBug(err),
1430 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
14311431 .ACCES => return error.AccessDenied,
14321432 .FBIG => return error.FileTooBig,
14331433 .OVERFLOW => return error.FileTooBig,
......@@ -1506,7 +1506,7 @@ fn dirOpenFile(
15061506
15071507 .FAULT => |err| return errnoBug(err),
15081508 .INVAL => return error.BadPathName,
1509 .BADF => |err| return errnoBug(err),
1509 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
15101510 .ACCES => return error.AccessDenied,
15111511 .FBIG => return error.FileTooBig,
15121512 .OVERFLOW => return error.FileTooBig,
......@@ -1548,7 +1548,7 @@ fn dirOpenFile(
15481548 .INTR => continue,
15491549 .CANCELED => return error.Canceled,
15501550
1551 .BADF => |err| return errnoBug(err),
1551 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
15521552 .INVAL => |err| return errnoBug(err), // invalid parameters
15531553 .NOLCK => return error.SystemResources,
15541554 .AGAIN => return error.WouldBlock,
......@@ -1653,7 +1653,7 @@ fn fileReadStreaming(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io.File
16531653
16541654 .INVAL => |err| return errnoBug(err),
16551655 .FAULT => |err| return errnoBug(err),
1656 .BADF => |err| return errnoBug(err),
1656 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
16571657 .IO => return error.InputOutput,
16581658 .ISDIR => return error.IsDir,
16591659 .NOBUFS => return error.SystemResources,
......@@ -1678,7 +1678,7 @@ fn fileReadStreaming(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io.File
16781678 .FAULT => |err| return errnoBug(err),
16791679 .SRCH => return error.ProcessNotFound,
16801680 .AGAIN => return error.WouldBlock,
1681 .BADF => return error.NotOpenForReading, // can be a race condition
1681 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
16821682 .IO => return error.InputOutput,
16831683 .ISDIR => return error.IsDir,
16841684 .NOBUFS => return error.SystemResources,
......@@ -1779,7 +1779,7 @@ fn fileReadPositional(userdata: ?*anyopaque, file: Io.File, data: [][]u8, offset
17791779 .INVAL => |err| return errnoBug(err),
17801780 .FAULT => |err| return errnoBug(err),
17811781 .AGAIN => |err| return errnoBug(err),
1782 .BADF => return error.NotOpenForReading, // can be a race condition
1782 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
17831783 .IO => return error.InputOutput,
17841784 .ISDIR => return error.IsDir,
17851785 .NOBUFS => return error.SystemResources,
......@@ -1807,7 +1807,7 @@ fn fileReadPositional(userdata: ?*anyopaque, file: Io.File, data: [][]u8, offset
18071807 .FAULT => |err| return errnoBug(err),
18081808 .SRCH => return error.ProcessNotFound,
18091809 .AGAIN => return error.WouldBlock,
1810 .BADF => return error.NotOpenForReading, // can be a race condition
1810 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
18111811 .IO => return error.InputOutput,
18121812 .ISDIR => return error.IsDir,
18131813 .NOBUFS => return error.SystemResources,
......@@ -1844,7 +1844,7 @@ fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekErr
18441844 .INTR => continue,
18451845 .CANCELED => return error.Canceled,
18461846
1847 .BADF => |err| return errnoBug(err), // Always a race condition.
1847 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
18481848 .INVAL => return error.Unseekable,
18491849 .OVERFLOW => return error.Unseekable,
18501850 .SPIPE => return error.Unseekable,
......@@ -1866,7 +1866,7 @@ fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekErr
18661866 .INTR => continue,
18671867 .CANCELED => return error.Canceled,
18681868
1869 .BADF => |err| return errnoBug(err), // Always a race condition.
1869 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
18701870 .INVAL => return error.Unseekable,
18711871 .OVERFLOW => return error.Unseekable,
18721872 .SPIPE => return error.Unseekable,
......@@ -1885,7 +1885,7 @@ fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekErr
18851885 .INTR => continue,
18861886 .CANCELED => return error.Canceled,
18871887
1888 .BADF => |err| return errnoBug(err), // Always a race condition.
1888 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
18891889 .INVAL => return error.Unseekable,
18901890 .OVERFLOW => return error.Unseekable,
18911891 .SPIPE => return error.Unseekable,
......@@ -2111,7 +2111,7 @@ fn netListenIpPosix(
21112111 switch (posix.errno(posix.system.listen(socket_fd, options.kernel_backlog))) {
21122112 .SUCCESS => break,
21132113 .ADDRINUSE => return error.AddressInUse,
2114 .BADF => |err| return errnoBug(err),
2114 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
21152115 else => |err| return posix.unexpectedErrno(err),
21162116 }
21172117 }
......@@ -2150,7 +2150,7 @@ fn netListenUnix(
21502150 switch (posix.errno(posix.system.listen(socket_fd, options.kernel_backlog))) {
21512151 .SUCCESS => break,
21522152 .ADDRINUSE => return error.AddressInUse,
2153 .BADF => |err| return errnoBug(err),
2153 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
21542154 else => |err| return posix.unexpectedErrno(err),
21552155 }
21562156 }
......@@ -2178,7 +2178,7 @@ fn posixBindUnix(t: *Threaded, fd: posix.socket_t, addr: *const posix.sockaddr,
21782178 .ROFS => return error.ReadOnlyFileSystem,
21792179 .PERM => return error.PermissionDenied,
21802180
2181 .BADF => |err| return errnoBug(err), // always a race condition if this error is returned
2181 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
21822182 .INVAL => |err| return errnoBug(err), // invalid parameters
21832183 .NOTSOCK => |err| return errnoBug(err), // invalid `sockfd`
21842184 .FAULT => |err| return errnoBug(err), // invalid `addr` pointer
......@@ -2197,7 +2197,7 @@ fn posixBind(t: *Threaded, socket_fd: posix.socket_t, addr: *const posix.sockadd
21972197 .CANCELED => return error.Canceled,
21982198
21992199 .ADDRINUSE => return error.AddressInUse,
2200 .BADF => |err| return errnoBug(err), // always a race condition if this error is returned
2200 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
22012201 .INVAL => |err| return errnoBug(err), // invalid parameters
22022202 .NOTSOCK => |err| return errnoBug(err), // invalid `sockfd`
22032203 .AFNOSUPPORT => return error.AddressFamilyUnsupported,
......@@ -2221,7 +2221,7 @@ fn posixConnect(t: *Threaded, socket_fd: posix.socket_t, addr: *const posix.sock
22212221 .AFNOSUPPORT => return error.AddressFamilyUnsupported,
22222222 .AGAIN, .INPROGRESS => return error.WouldBlock,
22232223 .ALREADY => return error.ConnectionPending,
2224 .BADF => |err| return errnoBug(err),
2224 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
22252225 .CONNREFUSED => return error.ConnectionRefused,
22262226 .CONNRESET => return error.ConnectionResetByPeer,
22272227 .FAULT => |err| return errnoBug(err),
......@@ -2260,7 +2260,7 @@ fn posixConnectUnix(t: *Threaded, fd: posix.socket_t, addr: *const posix.sockadd
22602260 .ROFS => return error.ReadOnlyFileSystem,
22612261 .PERM => return error.PermissionDenied,
22622262
2263 .BADF => |err| return errnoBug(err),
2263 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
22642264 .CONNABORTED => |err| return errnoBug(err),
22652265 .FAULT => |err| return errnoBug(err),
22662266 .ISCONN => |err| return errnoBug(err),
......@@ -2279,7 +2279,7 @@ fn posixGetSockName(t: *Threaded, socket_fd: posix.fd_t, addr: *posix.sockaddr,
22792279 .INTR => continue,
22802280 .CANCELED => return error.Canceled,
22812281
2282 .BADF => |err| return errnoBug(err), // always a race condition
2282 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
22832283 .FAULT => |err| return errnoBug(err),
22842284 .INVAL => |err| return errnoBug(err), // invalid parameters
22852285 .NOTSOCK => |err| return errnoBug(err), // always a race condition
......@@ -2298,7 +2298,7 @@ fn setSocketOption(t: *Threaded, fd: posix.fd_t, level: i32, opt_name: u32, opti
22982298 .INTR => continue,
22992299 .CANCELED => return error.Canceled,
23002300
2301 .BADF => |err| return errnoBug(err), // always a race condition
2301 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
23022302 .NOTSOCK => |err| return errnoBug(err), // always a race condition
23032303 .INVAL => |err| return errnoBug(err),
23042304 .FAULT => |err| return errnoBug(err),
......@@ -2430,6 +2430,7 @@ fn openSocketPosix(
24302430}
24312431
24322432fn netAcceptPosix(userdata: ?*anyopaque, listen_fd: net.Socket.Handle) net.Server.AcceptError!net.Stream {
2433 if (!have_networking) return error.NetworkDown;
24332434 const t: *Threaded = @ptrCast(@alignCast(userdata));
24342435 var storage: PosixAddress = undefined;
24352436 var addr_len: posix.socklen_t = @sizeOf(PosixAddress);
......@@ -2456,11 +2457,12 @@ fn netAcceptPosix(userdata: ?*anyopaque, listen_fd: net.Socket.Handle) net.Serve
24562457 },
24572458 .INTR => continue,
24582459 .CANCELED => return error.Canceled,
2460
24592461 .AGAIN => |err| return errnoBug(err),
2460 .BADF => |err| return errnoBug(err), // always a race condition
2462 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
24612463 .CONNABORTED => return error.ConnectionAborted,
24622464 .FAULT => |err| return errnoBug(err),
2463 .INVAL => return error.SocketNotListening,
2465 .INVAL => |err| return errnoBug(err),
24642466 .NOTSOCK => |err| return errnoBug(err),
24652467 .MFILE => return error.ProcessFdQuotaExceeded,
24662468 .NFILE => return error.SystemFdQuotaExceeded,
......@@ -2504,7 +2506,7 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.
25042506 .INVAL => |err| return errnoBug(err),
25052507 .FAULT => |err| return errnoBug(err),
25062508 .AGAIN => |err| return errnoBug(err),
2507 .BADF => |err| return errnoBug(err),
2509 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
25082510 .NOBUFS => return error.SystemResources,
25092511 .NOMEM => return error.SystemResources,
25102512 .NOTCONN => return error.SocketUnconnected,
......@@ -2526,7 +2528,7 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.
25262528 .INVAL => |err| return errnoBug(err),
25272529 .FAULT => |err| return errnoBug(err),
25282530 .AGAIN => |err| return errnoBug(err),
2529 .BADF => |err| return errnoBug(err), // Always a race condition.
2531 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
25302532 .NOBUFS => return error.SystemResources,
25312533 .NOMEM => return error.SystemResources,
25322534 .NOTCONN => return error.SocketUnconnected,
......@@ -2625,7 +2627,7 @@ fn netSendOne(
26252627
26262628 .ACCES => return error.AccessDenied,
26272629 .ALREADY => return error.FastOpenAlreadyInProgress,
2628 .BADF => |err| return errnoBug(err),
2630 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
26292631 .CONNRESET => return error.ConnectionResetByPeer,
26302632 .DESTADDRREQ => |err| return errnoBug(err),
26312633 .FAULT => |err| return errnoBug(err),
......@@ -2694,7 +2696,7 @@ fn netSendMany(
26942696
26952697 .AGAIN => |err| return errnoBug(err),
26962698 .ALREADY => return error.FastOpenAlreadyInProgress,
2697 .BADF => |err| return errnoBug(err), // Always a race condition.
2699 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
26982700 .CONNRESET => return error.ConnectionResetByPeer,
26992701 .DESTADDRREQ => |err| return errnoBug(err), // The socket is not connection-mode, and no peer address is set.
27002702 .FAULT => |err| return errnoBug(err), // An invalid user space address was specified for an argument.
......@@ -2905,7 +2907,7 @@ fn netWritePosix(
29052907 .ACCES => |err| return errnoBug(err),
29062908 .AGAIN => |err| return errnoBug(err),
29072909 .ALREADY => return error.FastOpenAlreadyInProgress,
2908 .BADF => |err| return errnoBug(err), // always a race condition
2910 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
29092911 .CONNRESET => return error.ConnectionResetByPeer,
29102912 .DESTADDRREQ => |err| return errnoBug(err), // The socket is not connection-mode, and no peer address is set.
29112913 .FAULT => |err| return errnoBug(err), // An invalid user space address was specified for an argument.
......@@ -2979,7 +2981,7 @@ fn netInterfaceNameResolve(
29792981 .INVAL => |err| return errnoBug(err), // Bad parameters.
29802982 .NOTTY => |err| return errnoBug(err),
29812983 .NXIO => |err| return errnoBug(err),
2982 .BADF => |err| return errnoBug(err), // Always a race condition.
2984 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
29832985 .FAULT => |err| return errnoBug(err), // Bad pointer parameter.
29842986 .IO => |err| return errnoBug(err), // sock_fd is not a file descriptor
29852987 .NODEV => return error.InterfaceNotFound,
lib/std/Io/net.zig+20-1
......@@ -1312,7 +1312,26 @@ pub const Server = struct {
13121312 s.* = undefined;
13131313 }
13141314
1315 pub const AcceptError = std.posix.AcceptError || Io.Cancelable;
1315 pub const AcceptError = error{
1316 /// The per-process limit on the number of open file descriptors has been reached.
1317 ProcessFdQuotaExceeded,
1318 /// The system-wide limit on the total number of open files has been reached.
1319 SystemFdQuotaExceeded,
1320 /// Not enough free memory. This often means that the memory allocation is limited
1321 /// by the socket buffer limits, not by the system memory.
1322 SystemResources,
1323 /// The network subsystem has failed.
1324 NetworkDown,
1325 /// No connection is already queued and ready to be accepted, and
1326 /// the socket is configured as non-blocking.
1327 WouldBlock,
1328 /// An incoming connection was indicated, but was subsequently terminated by the
1329 /// remote peer prior to accepting the call.
1330 ConnectionAborted,
1331 /// Firewall rules forbid connection.
1332 BlockedByFirewall,
1333 ProtocolFailure,
1334 } || Io.UnexpectedError || Io.Cancelable;
13161335
13171336 /// Blocks until a client connects to the server.
13181337 pub fn accept(s: *Server, io: Io) AcceptError!Stream {
lib/std/posix.zig+1-38
......@@ -3622,44 +3622,7 @@ pub fn listen(sock: socket_t, backlog: u31) ListenError!void {
36223622 }
36233623}
36243624
3625pub const AcceptError = error{
3626 ConnectionAborted,
3627
3628 /// The file descriptor sockfd does not refer to a socket.
3629 FileDescriptorNotASocket,
3630
3631 /// The per-process limit on the number of open file descriptors has been reached.
3632 ProcessFdQuotaExceeded,
3633
3634 /// The system-wide limit on the total number of open files has been reached.
3635 SystemFdQuotaExceeded,
3636
3637 /// Not enough free memory. This often means that the memory allocation is limited
3638 /// by the socket buffer limits, not by the system memory.
3639 SystemResources,
3640
3641 /// Socket is not listening for new connections.
3642 SocketNotListening,
3643
3644 ProtocolFailure,
3645
3646 /// Firewall rules forbid connection.
3647 BlockedByFirewall,
3648
3649 /// This error occurs when no global event loop is configured,
3650 /// and accepting from the socket would block.
3651 WouldBlock,
3652
3653 /// An incoming connection was indicated, but was subsequently terminated by the
3654 /// remote peer prior to accepting the call.
3655 ConnectionResetByPeer,
3656
3657 /// The network subsystem has failed.
3658 NetworkDown,
3659
3660 /// The referenced socket is not a type that supports connection-oriented service.
3661 OperationNotSupported,
3662} || UnexpectedError;
3625pub const AcceptError = std.Io.net.Server.AcceptError;
36633626
36643627/// Accept a connection on a socket.
36653628/// If `sockfd` is opened in non blocking mode, the function will