Repository: apple/swift-nio
File: Sources/NIOPosix/ServerSocket.swift (Swift)

Code before:
    ///     - setNonBlocking: set non-blocking mode on the returned `Socket`. On Linux this will use accept4 with SOCK_NONBLOCK to save a system call.
    /// - returns: A `Socket` once a new connection was established or `nil` if this `ServerSocket` is in non-blocking mode and there is no new connection that can be accepted when this method is called.
    /// - throws: An `IOError` if the operation failed.
    func accept(setNonBlocking: Bool = false) throws -> Socket? {
        return try withUnsafeHandle { fd in
            #if os(Linux)
            let flags: Int32
            if setNonBlocking {
                flags = Linux.SOCK_NONBLOCK
            } else {
                flags = 0
            }
            let result = try Linux.accept4(descriptor: fd, addr: nil, len: nil, flags: flags)
            #else
            let result = try NIOBSDSocket.accept(socket: fd, address: nil, address_len: nil)
            #endif

            guard let fd = result else {
                return nil
            }
            let sock = try Socket(socket: fd)
            #if !os(Linux)
            if setNonBlocking {
                do {
                    try sock.setNonBlocking()
                } catch {
                    // best effort
                    try? sock.close()
                    throw error
                }
            }
            #endif
            return sock
        }
    }

    /// Close the socket.
    ///
    /// After the socket was closed all other methods will throw an `IOError` when called.
    ///
    /// - throws: An `IOError` if the operation failed.
    override func close() throws {
        let maybePathname = self.cleanupOnClose ? (try? self.localAddress().pathname) : nil
        try super.close()
        if let socketPath = maybePathname {
            try BaseSocket.cleanupSocket(unixDomainSocketPath: socketPath)
        }
    }
}


Review comment (bug):
```suggestion
                // If creating the Socket type fails, this might indicate that the underlying connection is already closed.
                // The socket is still open though. We therefore still need to close the socket 
                // or the file descriptor leaks which can lead to file descriptor exhaustion.
```

Code after:
    ///     - setNonBlocking: set non-blocking mode on the returned `Socket`. On Linux this will use accept4 with SOCK_NONBLOCK to save a system call.
    /// - returns: A `Socket` once a new connection was established or `nil` if this `ServerSocket` is in non-blocking mode and there is no new connection that can be accepted when this method is called.
    /// - throws: An `IOError` if the operation failed.
    func accept(setNonBlocking: Bool = false) throws -> Socket? {
        return try withUnsafeHandle { fd in
            #if os(Linux)
            let flags: Int32
            if setNonBlocking {
                flags = Linux.SOCK_NONBLOCK
            } else {
                flags = 0
            }
            let result = try Linux.accept4(descriptor: fd, addr: nil, len: nil, flags: flags)
            #else
            let result = try NIOBSDSocket.accept(socket: fd, address: nil, address_len: nil)
            #endif

            guard let fd = result else {
                return nil
            }

            let sock: Socket
            do {
                sock = try Socket(socket: fd)
            } catch {
                // best effort
                try? Posix.close(descriptor: fd)
                throw error
            }

            #if !os(Linux)
            if setNonBlocking {
                do {
                    try sock.setNonBlocking()
                } catch {
                    // best effort
                    try? sock.close()
                    throw error
                }
            }
            #endif
            return sock
        }
    }

    /// Close the socket.
    ///
    /// After the socket was closed all other methods will throw an `IOError` when called.
    ///
    /// - throws: An `IOError` if the operation failed.
    override func close() throws {