Commit e87ceb76c2
Changed files (3)
lib
lib/std/Io/net.zig
@@ -1312,7 +1312,26 @@ pub const Server = struct {
s.* = undefined;
}
- pub const AcceptError = std.posix.AcceptError || Io.Cancelable;
+ pub const AcceptError = error{
+ /// The per-process limit on the number of open file descriptors has been reached.
+ ProcessFdQuotaExceeded,
+ /// The system-wide limit on the total number of open files has been reached.
+ SystemFdQuotaExceeded,
+ /// Not enough free memory. This often means that the memory allocation is limited
+ /// by the socket buffer limits, not by the system memory.
+ SystemResources,
+ /// The network subsystem has failed.
+ NetworkDown,
+ /// No connection is already queued and ready to be accepted, and
+ /// the socket is configured as non-blocking.
+ WouldBlock,
+ /// An incoming connection was indicated, but was subsequently terminated by the
+ /// remote peer prior to accepting the call.
+ ConnectionAborted,
+ /// Firewall rules forbid connection.
+ BlockedByFirewall,
+ ProtocolFailure,
+ } || Io.UnexpectedError || Io.Cancelable;
/// Blocks until a client connects to the server.
pub fn accept(s: *Server, io: Io) AcceptError!Stream {
lib/std/Io/Threaded.zig
@@ -898,7 +898,7 @@ fn dirMakePosix(userdata: ?*anyopaque, dir: Io.Dir, sub_path: []const u8, mode:
.CANCELED => return error.Canceled,
.ACCES => return error.AccessDenied,
- .BADF => |err| return errnoBug(err),
+ .BADF => |err| return errnoBug(err), // File descriptor used after closed.
.PERM => return error.PermissionDenied,
.DQUOT => return error.DiskQuota,
.EXIST => return error.PathAlreadyExists,
@@ -930,7 +930,7 @@ fn dirMakeWasi(userdata: ?*anyopaque, dir: Io.Dir, sub_path: []const u8, mode: I
.CANCELED => return error.Canceled,
.ACCES => return error.AccessDenied,
- .BADF => |err| return errnoBug(err),
+ .BADF => |err| return errnoBug(err), // File descriptor used after closed.
.PERM => return error.PermissionDenied,
.DQUOT => return error.DiskQuota,
.EXIST => return error.PathAlreadyExists,
@@ -989,7 +989,7 @@ fn dirStatPathLinux(
.CANCELED => return error.Canceled,
.ACCES => return error.AccessDenied,
- .BADF => |err| return errnoBug(err),
+ .BADF => |err| return errnoBug(err), // File descriptor used after closed.
.FAULT => |err| return errnoBug(err),
.INVAL => |err| return errnoBug(err),
.LOOP => return error.SymLinkLoop,
@@ -1024,7 +1024,7 @@ fn dirStatPathPosix(
.CANCELED => return error.Canceled,
.INVAL => |err| return errnoBug(err),
- .BADF => |err| return errnoBug(err), // Always a race condition.
+ .BADF => |err| return errnoBug(err), // File descriptor used after closed.
.NOMEM => return error.SystemResources,
.ACCES => return error.AccessDenied,
.PERM => return error.PermissionDenied,
@@ -1060,7 +1060,7 @@ fn dirStatPathWasi(
.CANCELED => return error.Canceled,
.INVAL => |err| return errnoBug(err),
- .BADF => |err| return errnoBug(err), // Always a race condition.
+ .BADF => |err| return errnoBug(err), // File descriptor used after closed.
.NOMEM => return error.SystemResources,
.ACCES => return error.AccessDenied,
.FAULT => |err| return errnoBug(err),
@@ -1088,7 +1088,7 @@ fn fileStatPosix(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File
.CANCELED => return error.Canceled,
.INVAL => |err| return errnoBug(err),
- .BADF => |err| return errnoBug(err),
+ .BADF => |err| return errnoBug(err), // File descriptor used after closed.
.NOMEM => return error.SystemResources,
.ACCES => return error.AccessDenied,
else => |err| return posix.unexpectedErrno(err),
@@ -1115,7 +1115,7 @@ fn fileStatLinux(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File
.CANCELED => return error.Canceled,
.ACCES => |err| return errnoBug(err),
- .BADF => |err| return errnoBug(err),
+ .BADF => |err| return errnoBug(err), // File descriptor used after closed.
.FAULT => |err| return errnoBug(err),
.INVAL => |err| return errnoBug(err),
.LOOP => |err| return errnoBug(err),
@@ -1147,7 +1147,7 @@ fn fileStatWasi(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File.
.CANCELED => return error.Canceled,
.INVAL => |err| return errnoBug(err),
- .BADF => |err| return errnoBug(err),
+ .BADF => |err| return errnoBug(err), // File descriptor used after closed.
.NOMEM => return error.SystemResources,
.ACCES => return error.AccessDenied,
.NOTCAPABLE => return error.AccessDenied,
@@ -1220,7 +1220,7 @@ fn dirAccessWasi(
.CANCELED => return error.Canceled,
.INVAL => |err| return errnoBug(err),
- .BADF => |err| return errnoBug(err), // Always a race condition.
+ .BADF => |err| return errnoBug(err), // File descriptor used after closed.
.NOMEM => return error.SystemResources,
.ACCES => return error.AccessDenied,
.FAULT => |err| return errnoBug(err),
@@ -1305,7 +1305,7 @@ fn dirCreateFilePosix(
.FAULT => |err| return errnoBug(err),
.INVAL => return error.BadPathName,
- .BADF => |err| return errnoBug(err),
+ .BADF => |err| return errnoBug(err), // File descriptor used after closed.
.ACCES => return error.AccessDenied,
.FBIG => return error.FileTooBig,
.OVERFLOW => return error.FileTooBig,
@@ -1347,7 +1347,7 @@ fn dirCreateFilePosix(
.INTR => continue,
.CANCELED => return error.Canceled,
- .BADF => |err| return errnoBug(err),
+ .BADF => |err| return errnoBug(err), // File descriptor used after closed.
.INVAL => |err| return errnoBug(err), // invalid parameters
.NOLCK => return error.SystemResources,
.AGAIN => return error.WouldBlock,
@@ -1427,7 +1427,7 @@ fn dirCreateFileWasi(
.FAULT => |err| return errnoBug(err),
// Provides INVAL with a linux host on a bad path name, but NOENT on Windows
.INVAL => return error.BadPathName,
- .BADF => |err| return errnoBug(err),
+ .BADF => |err| return errnoBug(err), // File descriptor used after closed.
.ACCES => return error.AccessDenied,
.FBIG => return error.FileTooBig,
.OVERFLOW => return error.FileTooBig,
@@ -1506,7 +1506,7 @@ fn dirOpenFile(
.FAULT => |err| return errnoBug(err),
.INVAL => return error.BadPathName,
- .BADF => |err| return errnoBug(err),
+ .BADF => |err| return errnoBug(err), // File descriptor used after closed.
.ACCES => return error.AccessDenied,
.FBIG => return error.FileTooBig,
.OVERFLOW => return error.FileTooBig,
@@ -1548,7 +1548,7 @@ fn dirOpenFile(
.INTR => continue,
.CANCELED => return error.Canceled,
- .BADF => |err| return errnoBug(err),
+ .BADF => |err| return errnoBug(err), // File descriptor used after closed.
.INVAL => |err| return errnoBug(err), // invalid parameters
.NOLCK => return error.SystemResources,
.AGAIN => return error.WouldBlock,
@@ -1653,7 +1653,7 @@ fn fileReadStreaming(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io.File
.INVAL => |err| return errnoBug(err),
.FAULT => |err| return errnoBug(err),
- .BADF => |err| return errnoBug(err),
+ .BADF => |err| return errnoBug(err), // File descriptor used after closed.
.IO => return error.InputOutput,
.ISDIR => return error.IsDir,
.NOBUFS => return error.SystemResources,
@@ -1678,7 +1678,7 @@ fn fileReadStreaming(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io.File
.FAULT => |err| return errnoBug(err),
.SRCH => return error.ProcessNotFound,
.AGAIN => return error.WouldBlock,
- .BADF => return error.NotOpenForReading, // can be a race condition
+ .BADF => |err| return errnoBug(err), // File descriptor used after closed.
.IO => return error.InputOutput,
.ISDIR => return error.IsDir,
.NOBUFS => return error.SystemResources,
@@ -1779,7 +1779,7 @@ fn fileReadPositional(userdata: ?*anyopaque, file: Io.File, data: [][]u8, offset
.INVAL => |err| return errnoBug(err),
.FAULT => |err| return errnoBug(err),
.AGAIN => |err| return errnoBug(err),
- .BADF => return error.NotOpenForReading, // can be a race condition
+ .BADF => |err| return errnoBug(err), // File descriptor used after closed.
.IO => return error.InputOutput,
.ISDIR => return error.IsDir,
.NOBUFS => return error.SystemResources,
@@ -1807,7 +1807,7 @@ fn fileReadPositional(userdata: ?*anyopaque, file: Io.File, data: [][]u8, offset
.FAULT => |err| return errnoBug(err),
.SRCH => return error.ProcessNotFound,
.AGAIN => return error.WouldBlock,
- .BADF => return error.NotOpenForReading, // can be a race condition
+ .BADF => |err| return errnoBug(err), // File descriptor used after closed.
.IO => return error.InputOutput,
.ISDIR => return error.IsDir,
.NOBUFS => return error.SystemResources,
@@ -1844,7 +1844,7 @@ fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekErr
.INTR => continue,
.CANCELED => return error.Canceled,
- .BADF => |err| return errnoBug(err), // Always a race condition.
+ .BADF => |err| return errnoBug(err), // File descriptor used after closed.
.INVAL => return error.Unseekable,
.OVERFLOW => return error.Unseekable,
.SPIPE => return error.Unseekable,
@@ -1866,7 +1866,7 @@ fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekErr
.INTR => continue,
.CANCELED => return error.Canceled,
- .BADF => |err| return errnoBug(err), // Always a race condition.
+ .BADF => |err| return errnoBug(err), // File descriptor used after closed.
.INVAL => return error.Unseekable,
.OVERFLOW => return error.Unseekable,
.SPIPE => return error.Unseekable,
@@ -1885,7 +1885,7 @@ fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekErr
.INTR => continue,
.CANCELED => return error.Canceled,
- .BADF => |err| return errnoBug(err), // Always a race condition.
+ .BADF => |err| return errnoBug(err), // File descriptor used after closed.
.INVAL => return error.Unseekable,
.OVERFLOW => return error.Unseekable,
.SPIPE => return error.Unseekable,
@@ -2111,7 +2111,7 @@ fn netListenIpPosix(
switch (posix.errno(posix.system.listen(socket_fd, options.kernel_backlog))) {
.SUCCESS => break,
.ADDRINUSE => return error.AddressInUse,
- .BADF => |err| return errnoBug(err),
+ .BADF => |err| return errnoBug(err), // File descriptor used after closed.
else => |err| return posix.unexpectedErrno(err),
}
}
@@ -2150,7 +2150,7 @@ fn netListenUnix(
switch (posix.errno(posix.system.listen(socket_fd, options.kernel_backlog))) {
.SUCCESS => break,
.ADDRINUSE => return error.AddressInUse,
- .BADF => |err| return errnoBug(err),
+ .BADF => |err| return errnoBug(err), // File descriptor used after closed.
else => |err| return posix.unexpectedErrno(err),
}
}
@@ -2178,7 +2178,7 @@ fn posixBindUnix(t: *Threaded, fd: posix.socket_t, addr: *const posix.sockaddr,
.ROFS => return error.ReadOnlyFileSystem,
.PERM => return error.PermissionDenied,
- .BADF => |err| return errnoBug(err), // always a race condition if this error is returned
+ .BADF => |err| return errnoBug(err), // File descriptor used after closed.
.INVAL => |err| return errnoBug(err), // invalid parameters
.NOTSOCK => |err| return errnoBug(err), // invalid `sockfd`
.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
.CANCELED => return error.Canceled,
.ADDRINUSE => return error.AddressInUse,
- .BADF => |err| return errnoBug(err), // always a race condition if this error is returned
+ .BADF => |err| return errnoBug(err), // File descriptor used after closed.
.INVAL => |err| return errnoBug(err), // invalid parameters
.NOTSOCK => |err| return errnoBug(err), // invalid `sockfd`
.AFNOSUPPORT => return error.AddressFamilyUnsupported,
@@ -2221,7 +2221,7 @@ fn posixConnect(t: *Threaded, socket_fd: posix.socket_t, addr: *const posix.sock
.AFNOSUPPORT => return error.AddressFamilyUnsupported,
.AGAIN, .INPROGRESS => return error.WouldBlock,
.ALREADY => return error.ConnectionPending,
- .BADF => |err| return errnoBug(err),
+ .BADF => |err| return errnoBug(err), // File descriptor used after closed.
.CONNREFUSED => return error.ConnectionRefused,
.CONNRESET => return error.ConnectionResetByPeer,
.FAULT => |err| return errnoBug(err),
@@ -2260,7 +2260,7 @@ fn posixConnectUnix(t: *Threaded, fd: posix.socket_t, addr: *const posix.sockadd
.ROFS => return error.ReadOnlyFileSystem,
.PERM => return error.PermissionDenied,
- .BADF => |err| return errnoBug(err),
+ .BADF => |err| return errnoBug(err), // File descriptor used after closed.
.CONNABORTED => |err| return errnoBug(err),
.FAULT => |err| return errnoBug(err),
.ISCONN => |err| return errnoBug(err),
@@ -2279,7 +2279,7 @@ fn posixGetSockName(t: *Threaded, socket_fd: posix.fd_t, addr: *posix.sockaddr,
.INTR => continue,
.CANCELED => return error.Canceled,
- .BADF => |err| return errnoBug(err), // always a race condition
+ .BADF => |err| return errnoBug(err), // File descriptor used after closed.
.FAULT => |err| return errnoBug(err),
.INVAL => |err| return errnoBug(err), // invalid parameters
.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
.INTR => continue,
.CANCELED => return error.Canceled,
- .BADF => |err| return errnoBug(err), // always a race condition
+ .BADF => |err| return errnoBug(err), // File descriptor used after closed.
.NOTSOCK => |err| return errnoBug(err), // always a race condition
.INVAL => |err| return errnoBug(err),
.FAULT => |err| return errnoBug(err),
@@ -2430,6 +2430,7 @@ fn openSocketPosix(
}
fn netAcceptPosix(userdata: ?*anyopaque, listen_fd: net.Socket.Handle) net.Server.AcceptError!net.Stream {
+ if (!have_networking) return error.NetworkDown;
const t: *Threaded = @ptrCast(@alignCast(userdata));
var storage: PosixAddress = undefined;
var addr_len: posix.socklen_t = @sizeOf(PosixAddress);
@@ -2456,11 +2457,12 @@ fn netAcceptPosix(userdata: ?*anyopaque, listen_fd: net.Socket.Handle) net.Serve
},
.INTR => continue,
.CANCELED => return error.Canceled,
+
.AGAIN => |err| return errnoBug(err),
- .BADF => |err| return errnoBug(err), // always a race condition
+ .BADF => |err| return errnoBug(err), // File descriptor used after closed.
.CONNABORTED => return error.ConnectionAborted,
.FAULT => |err| return errnoBug(err),
- .INVAL => return error.SocketNotListening,
+ .INVAL => |err| return errnoBug(err),
.NOTSOCK => |err| return errnoBug(err),
.MFILE => return error.ProcessFdQuotaExceeded,
.NFILE => return error.SystemFdQuotaExceeded,
@@ -2504,7 +2506,7 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.
.INVAL => |err| return errnoBug(err),
.FAULT => |err| return errnoBug(err),
.AGAIN => |err| return errnoBug(err),
- .BADF => |err| return errnoBug(err),
+ .BADF => |err| return errnoBug(err), // File descriptor used after closed.
.NOBUFS => return error.SystemResources,
.NOMEM => return error.SystemResources,
.NOTCONN => return error.SocketUnconnected,
@@ -2526,7 +2528,7 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.
.INVAL => |err| return errnoBug(err),
.FAULT => |err| return errnoBug(err),
.AGAIN => |err| return errnoBug(err),
- .BADF => |err| return errnoBug(err), // Always a race condition.
+ .BADF => |err| return errnoBug(err), // File descriptor used after closed.
.NOBUFS => return error.SystemResources,
.NOMEM => return error.SystemResources,
.NOTCONN => return error.SocketUnconnected,
@@ -2625,7 +2627,7 @@ fn netSendOne(
.ACCES => return error.AccessDenied,
.ALREADY => return error.FastOpenAlreadyInProgress,
- .BADF => |err| return errnoBug(err),
+ .BADF => |err| return errnoBug(err), // File descriptor used after closed.
.CONNRESET => return error.ConnectionResetByPeer,
.DESTADDRREQ => |err| return errnoBug(err),
.FAULT => |err| return errnoBug(err),
@@ -2694,7 +2696,7 @@ fn netSendMany(
.AGAIN => |err| return errnoBug(err),
.ALREADY => return error.FastOpenAlreadyInProgress,
- .BADF => |err| return errnoBug(err), // Always a race condition.
+ .BADF => |err| return errnoBug(err), // File descriptor used after closed.
.CONNRESET => return error.ConnectionResetByPeer,
.DESTADDRREQ => |err| return errnoBug(err), // The socket is not connection-mode, and no peer address is set.
.FAULT => |err| return errnoBug(err), // An invalid user space address was specified for an argument.
@@ -2905,7 +2907,7 @@ fn netWritePosix(
.ACCES => |err| return errnoBug(err),
.AGAIN => |err| return errnoBug(err),
.ALREADY => return error.FastOpenAlreadyInProgress,
- .BADF => |err| return errnoBug(err), // always a race condition
+ .BADF => |err| return errnoBug(err), // File descriptor used after closed.
.CONNRESET => return error.ConnectionResetByPeer,
.DESTADDRREQ => |err| return errnoBug(err), // The socket is not connection-mode, and no peer address is set.
.FAULT => |err| return errnoBug(err), // An invalid user space address was specified for an argument.
@@ -2979,7 +2981,7 @@ fn netInterfaceNameResolve(
.INVAL => |err| return errnoBug(err), // Bad parameters.
.NOTTY => |err| return errnoBug(err),
.NXIO => |err| return errnoBug(err),
- .BADF => |err| return errnoBug(err), // Always a race condition.
+ .BADF => |err| return errnoBug(err), // File descriptor used after closed.
.FAULT => |err| return errnoBug(err), // Bad pointer parameter.
.IO => |err| return errnoBug(err), // sock_fd is not a file descriptor
.NODEV => return error.InterfaceNotFound,
lib/std/posix.zig
@@ -3622,44 +3622,7 @@ pub fn listen(sock: socket_t, backlog: u31) ListenError!void {
}
}
-pub const AcceptError = error{
- ConnectionAborted,
-
- /// The file descriptor sockfd does not refer to a socket.
- FileDescriptorNotASocket,
-
- /// The per-process limit on the number of open file descriptors has been reached.
- ProcessFdQuotaExceeded,
-
- /// The system-wide limit on the total number of open files has been reached.
- SystemFdQuotaExceeded,
-
- /// Not enough free memory. This often means that the memory allocation is limited
- /// by the socket buffer limits, not by the system memory.
- SystemResources,
-
- /// Socket is not listening for new connections.
- SocketNotListening,
-
- ProtocolFailure,
-
- /// Firewall rules forbid connection.
- BlockedByFirewall,
-
- /// This error occurs when no global event loop is configured,
- /// and accepting from the socket would block.
- WouldBlock,
-
- /// An incoming connection was indicated, but was subsequently terminated by the
- /// remote peer prior to accepting the call.
- ConnectionResetByPeer,
-
- /// The network subsystem has failed.
- NetworkDown,
-
- /// The referenced socket is not a type that supports connection-oriented service.
- OperationNotSupported,
-} || UnexpectedError;
+pub const AcceptError = std.Io.net.Server.AcceptError;
/// Accept a connection on a socket.
/// If `sockfd` is opened in non blocking mode, the function will