From 2bfc6d14d500dcaf66b8ee7d24637e25e3795a5e Mon Sep 17 00:00:00 2001 From: lithdew Date: Fri, 2 Apr 2021 05:28:25 +0900 Subject: [PATCH] os/linux: return error on EALREADY for connect() and getsockoptError() When a connected socket file descriptor on Linux is re-acquired after being closed, through fuzz testing, it appears that a subsequent attempt to establish a connection with the file descriptor causes EALREADY to be reported. Instead of panicking, choose to return error.ConnectionPending to allow for users to handle this fairly rare case. --- lib/std/os.zig | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/std/os.zig b/lib/std/os.zig index e4bd96de05..9826ba46f1 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -3254,6 +3254,9 @@ pub const ConnectError = error{ /// Connection was reset by peer before connect could complete. ConnectionResetByPeer, + + /// Socket is non-blocking and already has a pending connection in progress. + ConnectionPending, } || UnexpectedError; /// Initiate a connection on a socket. @@ -3294,7 +3297,7 @@ pub fn connect(sock: socket_t, sock_addr: *const sockaddr, len: socklen_t) Conne EADDRNOTAVAIL => return error.AddressNotAvailable, EAFNOSUPPORT => return error.AddressFamilyNotSupported, EAGAIN, EINPROGRESS => return error.WouldBlock, - EALREADY => unreachable, // The socket is nonblocking and a previous connection attempt has not yet been completed. + EALREADY => return error.ConnectionPending, EBADF => unreachable, // sockfd is not a valid open file descriptor. ECONNREFUSED => return error.ConnectionRefused, ECONNRESET => return error.ConnectionResetByPeer, @@ -3325,7 +3328,7 @@ pub fn getsockoptError(sockfd: fd_t) ConnectError!void { EADDRNOTAVAIL => return error.AddressNotAvailable, EAFNOSUPPORT => return error.AddressFamilyNotSupported, EAGAIN => return error.SystemResources, - EALREADY => unreachable, // The socket is nonblocking and a previous connection attempt has not yet been completed. + EALREADY => return error.ConnectionPending, EBADF => unreachable, // sockfd is not a valid open file descriptor. ECONNREFUSED => return error.ConnectionRefused, EFAULT => unreachable, // The socket structure address is outside the user's address space.