Repository: vapor/vapor
File: Sources/TCP/Socket/Socket+Bind.swift (Swift)

Code before:
            freeaddrinfo(result)
        }

        guard let info = result else {
            throw Error(identifier: "unwrapAddress", reason: "Could not unwrap address info.")
        }

        res = libc.bind(descriptor.raw, info.pointee.ai_addr, info.pointee.ai_addrlen)
        guard res == 0 else {
            throw Error.posix(errno, identifier: "bind")
        }
    }

    /// listen - listen for connections on a socket
    /// http://man7.org/linux/man-pages/man2/listen.2.html
    public func listen(backlog: Int32 = 4096) throws {
        let res = libc.listen(descriptor.raw, backlog)
        guard res == 0 else {
            throw Error.posix(errno, identifier: "listen")
        }
    }

    /// accept, accept4 - accept a connection on a socket
    /// http://man7.org/linux/man-pages/man2/accept.2.html
    public func accept() throws -> Socket {
        var address = sockaddr_storage()
        
        let clientfd = withUnsafeMutablePointer(to: &address) { address -> Int32 in
            return address.withMemoryRebound(to: sockaddr.self, capacity: 1) { address -> Int32 in
                var size = socklen_t(MemoryLayout<sockaddr>.size)
                
                return withUnsafeMutablePointer(to: &size) { (size: UnsafeMutablePointer<socklen_t>) -> Int32 in
                    return libc.accept(self.descriptor.raw, address, size)
                }
            }
        }
        
        guard clientfd > 0 else {
            throw Error.posix(errno, identifier: "accept")
        }

        let socket = Socket(
            established: Descriptor(raw: clientfd),
            isNonBlocking: isNonBlocking,
            shouldReuseAddress: shouldReuseAddress
        )
        
        socket.address = Address(storage: address)
        
        return socket
    }

Review comment (suggestion):
Is there a way we could put this line and 57-65 onto the `Address` class? they seem a bit out of place here. 

Code after:
        defer {
            freeaddrinfo(result)
        }

        guard let info = result else {
            throw Error(identifier: "unwrapAddress", reason: "Could not unwrap address info.")
        }

        res = libc.bind(descriptor, info.pointee.ai_addr, info.pointee.ai_addrlen)
        guard res == 0 else {
            throw Error.posix(errno, identifier: "bind")
        }
    }

    /// listen - listen for connections on a socket
    /// http://man7.org/linux/man-pages/man2/listen.2.html
    public func listen(backlog: Int32 = 4096) throws {
        let res = libc.listen(descriptor, backlog)
        guard res == 0 else {
            throw Error.posix(errno, identifier: "listen")
        }
    }

    /// accept, accept4 - accept a connection on a socket
    /// http://man7.org/linux/man-pages/man2/accept.2.html
    public func accept() throws -> Socket {
        let (clientfd, address) = try Address.withSockaddrPointer { address -> Int32 in
            var size = socklen_t(MemoryLayout<sockaddr>.size)
            
            let descriptor = libc.accept(self.descriptor, address, &size)
            
            guard descriptor > 0 else {
                throw Error.posix(errno, identifier: "accept")
            }
            
            return descriptor
        }
        
        let socket = Socket(
            established: clientfd,
            isNonBlocking: isNonBlocking,
            shouldReuseAddress: shouldReuseAddress,
            address: address
        )
        
        return socket
    }
}