Ponyboy47/Pathman

View on GitHub
Sources/Pathman/Socket/SocketPath+Openable.swift

Summary

Maintainability
A
35 mins
Test Coverage
#if os(Linux)
import func Glibc.close
import func Glibc.socket
#else
import func Darwin.close
import func Darwin.socket
#endif
private let cSocket = socket
private let cCloseSocket = close

extension SocketPath: Openable {
    public typealias OpenOptions = SocketOptions
    public typealias Descriptor = FileDescriptor

    public struct SocketOptions: OpenOptionable {
        public let domain: SocketDomain = .local
        public let type: SocketType

        public init(type: SocketType) {
            self.type = type
        }
    }

    public func open(type: SocketType) throws -> Open<SocketPath> {
        return try open(options: SocketOptions(type: type))
    }

    public func open(options: SocketOptions) throws -> Open<SocketPath> {
        let fileDescriptor = cSocket(options.domain.rawValue,
                                     options.type.rawValue,
                                     0)

        guard fileDescriptor != -1 else {
            throw SocketError.getError()
        }

        return Open<SocketPath>(self, descriptor: fileDescriptor, fileDescriptor: fileDescriptor, options: options)
    }

    public static func close(opened: Open<SocketPath>) throws {
        guard let descriptor = opened.descriptor else {
            throw ClosedDescriptorError.doubleClose
        }

        guard cCloseSocket(descriptor) != -1 else { throw CloseSocketError.getError() }
    }
}