Skip to content

Commit

Permalink
Updated POSIXError
Browse files Browse the repository at this point in the history
  • Loading branch information
colemancda committed Apr 19, 2019
1 parent 126fa2c commit 64c90c4
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 48 deletions.
2 changes: 1 addition & 1 deletion Sources/BluetoothLinux/DeviceCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,5 @@ internal func HCISendCommand <T: HCICommand> (_ deviceDescriptor: CInt,

// write to device descriptor socket
guard write(deviceDescriptor, &data, data.count) >= 0 // should we check if all data was written?
else { throw POSIXError.fromErrno! }
else { throw POSIXError.fromErrno() }
}
8 changes: 4 additions & 4 deletions Sources/BluetoothLinux/DevicePollEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ internal func HCIPollEvent(_ deviceDescriptor: CInt,
guard withUnsafeMutablePointer(to: &oldFilter, {
let pointer = UnsafeMutableRawPointer($0)
return getsockopt(deviceDescriptor, SOL_HCI, HCISocketOption.Filter.rawValue, pointer, &oldFilterLength) == 0
}) else { throw POSIXError.fromErrno! }
}) else { throw POSIXError.fromErrno() }

var newFilter = HCIFilter()
newFilter.clear()
Expand All @@ -56,15 +56,15 @@ internal func HCIPollEvent(_ deviceDescriptor: CInt,
guard withUnsafeMutablePointer(to: &newFilter, {
let pointer = UnsafeMutableRawPointer($0)
return setsockopt(deviceDescriptor, SOL_HCI, HCISocketOption.Filter.rawValue, pointer, newFilterLength) == 0
}) else { throw POSIXError.fromErrno! }
}) else { throw POSIXError.fromErrno() }

// restore old filter in case of error
func restoreFilter(_ error: Error) -> Error {

guard withUnsafeMutablePointer(to: &oldFilter, {
let pointer = UnsafeMutableRawPointer($0)
return setsockopt(deviceDescriptor, SOL_HCI, HCISocketOption.Filter.rawValue, pointer, newFilterLength) == 0
}) else { return BluetoothHostControllerError.couldNotRestoreFilter(error, POSIXError.fromErrno!) }
}) else { return BluetoothHostControllerError.couldNotRestoreFilter(error, POSIXError.fromErrno()) }

return error
}
Expand Down Expand Up @@ -102,7 +102,7 @@ internal func HCIPollEvent(_ deviceDescriptor: CInt,
} else {

// attempt to restore filter and throw
throw restoreFilter(POSIXError.fromErrno!)
throw restoreFilter(POSIXError.fromErrno())
}
}

Expand Down
12 changes: 6 additions & 6 deletions Sources/BluetoothLinux/DeviceRequest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ internal func HCISendRequest <Command: HCICommand> (_ deviceDescriptor: CInt,

// get old filter
guard getsockopt(deviceDescriptor, SOL_HCI, HCISocketOption.Filter.rawValue, oldFilterPointer, &filterLength) == 0
else { throw POSIXError.fromErrno! }
else { throw POSIXError.fromErrno() }

// configure new filter
newFilter.clear()
Expand All @@ -222,13 +222,13 @@ internal func HCISendRequest <Command: HCICommand> (_ deviceDescriptor: CInt,

// set new filter
guard setsockopt(deviceDescriptor, SOL_HCI, HCISocketOption.Filter.rawValue, newFilterPointer, filterLength) == 0
else { throw POSIXError.fromErrno! }
else { throw POSIXError.fromErrno() }

// restore old filter in case of error
func restoreFilter(_ error: Error) -> Error {

guard setsockopt(deviceDescriptor, SOL_HCI, HCISocketOption.Filter.rawValue, oldFilterPointer, filterLength) == 0
else { return BluetoothHostControllerError.couldNotRestoreFilter(error, POSIXError.fromErrno!) }
else { return BluetoothHostControllerError.couldNotRestoreFilter(error, POSIXError.fromErrno()) }

return error
}
Expand Down Expand Up @@ -268,7 +268,7 @@ internal func HCISendRequest <Command: HCICommand> (_ deviceDescriptor: CInt,
} else {

// attempt to restore filter and throw
throw restoreFilter(POSIXError.fromErrno!)
throw restoreFilter(POSIXError.fromErrno())
}
}

Expand Down Expand Up @@ -298,7 +298,7 @@ internal func HCISendRequest <Command: HCICommand> (_ deviceDescriptor: CInt,
} else {

// attempt to restore filter and throw
throw restoreFilter(POSIXError.fromErrno!)
throw restoreFilter(POSIXError.fromErrno())
}
}

Expand All @@ -317,7 +317,7 @@ internal func HCISendRequest <Command: HCICommand> (_ deviceDescriptor: CInt,
func done() throws {

guard setsockopt(deviceDescriptor, SOL_HCI, HCISocketOption.Filter.rawValue, oldFilterPointer, filterLength) == 0
else { throw POSIXError.fromErrno! }
else { throw POSIXError.fromErrno() }
}

switch eventHeader.event {
Expand Down
14 changes: 7 additions & 7 deletions Sources/BluetoothLinux/HostController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ internal func HCIOpenDevice(_ deviceIdentifier: UInt16) throws -> CInt {
// Create HCI socket
let hciSocket = socket(AF_BLUETOOTH, SOCK_RAW | SOCK_CLOEXEC, BluetoothProtocol.hci.rawValue)

guard hciSocket >= 0 else { throw POSIXError.fromErrno! }
guard hciSocket >= 0 else { throw POSIXError.fromErrno() }

// Bind socket to the HCI device
var address = HCISocketAddress()
Expand All @@ -136,7 +136,7 @@ internal func HCIOpenDevice(_ deviceIdentifier: UInt16) throws -> CInt {

guard didBind else {
close(hciSocket)
throw POSIXError.fromErrno!
throw POSIXError.fromErrno()
}

return hciSocket
Expand All @@ -147,7 +147,7 @@ internal func HCIRequestDeviceList <T> (_ response: (_ hciSocket: CInt, _ list:
// open HCI socket
let hciSocket = socket(AF_BLUETOOTH, SOCK_RAW | SOCK_CLOEXEC, BluetoothProtocol.hci.rawValue)

guard hciSocket >= 0 else { throw POSIXError.fromErrno! }
guard hciSocket >= 0 else { throw POSIXError.fromErrno() }

defer { close(hciSocket) }

Expand All @@ -160,7 +160,7 @@ internal func HCIRequestDeviceList <T> (_ response: (_ hciSocket: CInt, _ list:
IOControl(hciSocket, HCI.IOCTL.GetDeviceList, $0)
}

guard ioctlValue >= 0 else { throw POSIXError.fromErrno! }
guard ioctlValue >= 0 else { throw POSIXError.fromErrno() }

return try response(hciSocket, &deviceList)
}
Expand Down Expand Up @@ -216,7 +216,7 @@ internal func HCIGetRoute(_ address: BluetoothAddress? = nil) throws -> UInt16?

guard withUnsafeMutablePointer(to: &deviceInfo, {
IOControl(CInt(dd), HCI.IOCTL.GetDeviceInfo, UnsafeMutableRawPointer($0)) }) == 0
else { throw POSIXError.fromErrno! }
else { throw POSIXError.fromErrno() }

return deviceInfo.address == address
}
Expand All @@ -228,7 +228,7 @@ internal func HCIDeviceInfo(_ deviceIdentifier: UInt16) throws -> HCIDeviceInfor

let hciSocket = socket(AF_BLUETOOTH, SOCK_RAW | SOCK_CLOEXEC, BluetoothProtocol.hci.rawValue)

guard hciSocket >= 0 else { throw POSIXError.fromErrno! }
guard hciSocket >= 0 else { throw POSIXError.fromErrno() }

defer { close(hciSocket) }

Expand All @@ -237,7 +237,7 @@ internal func HCIDeviceInfo(_ deviceIdentifier: UInt16) throws -> HCIDeviceInfor

guard withUnsafeMutablePointer(to: &deviceInfo, {
IOControl(hciSocket, HCI.IOCTL.GetDeviceInfo, UnsafeMutableRawPointer($0)) }) == 0
else { throw POSIXError.fromErrno! }
else { throw POSIXError.fromErrno() }

return deviceInfo
}
Expand Down
32 changes: 14 additions & 18 deletions Sources/BluetoothLinux/L2CAP.swift
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ public final class L2CAPSocket: L2CAPSocketProtocol {
var optionLength = socklen_t(MemoryLayout<CInt>.size)

guard getsockopt(fileDescriptor, SOL_SOCKET, socketOption, &optionValue, &optionLength) == 0
else { throw POSIXError.fromErrno! }
else { throw POSIXError.fromErrno() }

return optionValue
}
Expand All @@ -141,7 +141,7 @@ public final class L2CAPSocket: L2CAPSocketProtocol {

// error creating socket
guard internalSocket >= 0
else { throw POSIXError.fromErrno! }
else { throw POSIXError.fromErrno() }

// set source address
var localAddress = sockaddr_l2()
Expand All @@ -157,7 +157,7 @@ public final class L2CAPSocket: L2CAPSocketProtocol {
$0.withMemoryRebound(to: sockaddr.self, capacity: 1, {
bind(internalSocket, $0, socklen_t(MemoryLayout<sockaddr_l2>.size)) == 0
})
}) else { close(internalSocket); throw POSIXError.fromErrno! }
}) else { close(internalSocket); throw POSIXError.fromErrno() }

return (internalSocket, localAddress)
}
Expand Down Expand Up @@ -200,7 +200,7 @@ public final class L2CAPSocket: L2CAPSocketProtocol {
security.level = securityLevel.rawValue

guard setsockopt(internalSocket, SOL_BLUETOOTH, BT_SECURITY, &security, socklen_t(MemoryLayout<bt_security>.size)) == 0
else { throw POSIXError.fromErrno! }
else { throw POSIXError.fromErrno() }

self.securityLevel = securityLevel
}
Expand All @@ -210,7 +210,7 @@ public final class L2CAPSocket: L2CAPSocketProtocol {

// put socket into listening mode
guard listen(internalSocket, Int32(queueLimit)) == 0
else { throw POSIXError.fromErrno! }
else { throw POSIXError.fromErrno() }
}

/// Blocks the caller until a new connection is recieved.
Expand All @@ -228,7 +228,7 @@ public final class L2CAPSocket: L2CAPSocketProtocol {
})

// error accepting new connection
guard client >= 0 else { throw POSIXError.fromErrno! }
guard client >= 0 else { throw POSIXError.fromErrno() }

let newSocket = L2CAPSocket(clientSocket: client,
remoteAddress: remoteAddress,
Expand Down Expand Up @@ -257,7 +257,7 @@ public final class L2CAPSocket: L2CAPSocketProtocol {
$0.withMemoryRebound(to: sockaddr.self, capacity: 1, {
connect(internalSocket, $0, socklen_t(MemoryLayout<sockaddr_l2>.size)) == 0
})
}) else { throw POSIXError.fromErrno! }
}) else { throw POSIXError.fromErrno() }

// make socket non-blocking
try setNonblocking()
Expand All @@ -276,13 +276,9 @@ public final class L2CAPSocket: L2CAPSocketProtocol {
let actualByteCount = read(internalSocket, &buffer, bufferSize)

guard actualByteCount >= 0 else {
if let error = POSIXError.fromErrno {
throw error
} else {
return nil
}
throw POSIXError.fromErrno()
}

let actualBytes = Array(buffer.prefix(actualByteCount))

return Data(actualBytes)
Expand All @@ -299,7 +295,7 @@ public final class L2CAPSocket: L2CAPSocketProtocol {
let fdCount = select(internalSocket + 1, &readSockets, nil, nil, &time)

guard fdCount != -1
else { throw POSIXError.fromErrno! }
else { throw POSIXError.fromErrno() }

return fdCount > 0
}
Expand All @@ -309,12 +305,12 @@ public final class L2CAPSocket: L2CAPSocketProtocol {
var flags = fcntl(internalSocket, F_GETFL, 0)

guard flags != -1
else { throw POSIXError.fromErrno! }
else { throw POSIXError.fromErrno() }

flags = fcntl(internalSocket, F_SETFL, flags | O_NONBLOCK);

guard flags != -1
else { throw POSIXError.fromErrno! }
else { throw POSIXError.fromErrno() }
}

/// Write to the socket.
Expand All @@ -325,7 +321,7 @@ public final class L2CAPSocket: L2CAPSocketProtocol {
let actualByteCount = write(internalSocket, &buffer, buffer.count)

guard actualByteCount >= 0
else { throw POSIXError.fromErrno! }
else { throw POSIXError.fromErrno() }

guard actualByteCount == buffer.count
else { throw L2CAPSocketError.sentLessBytes(actualByteCount) }
Expand All @@ -338,7 +334,7 @@ public final class L2CAPSocket: L2CAPSocketProtocol {
var optionLength = socklen_t(MemoryLayout<Options>.size)

guard getsockopt(internalSocket, SOL_L2CAP, L2CAP_OPTIONS, &optionValue, &optionLength) == 0
else { throw POSIXError.fromErrno! }
else { throw POSIXError.fromErrno() }

return optionValue
}
Expand Down
61 changes: 53 additions & 8 deletions Sources/BluetoothLinux/POSIXError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,26 @@ import Glibc
internal extension POSIXError {

/// Creates error from C ```errno```.
static var fromErrno: POSIXError? {
static func fromErrno(file: StaticString = #file,
line: UInt = #line,
function: StaticString = #function) -> POSIXError {

guard let code = POSIXErrorCode(rawValue: errno)
else { return nil }
else { fatalError("Invalid POSIX Error \(errno)") }

return POSIXError(code)
return POSIXError(code, function: function, file: file, line: line)
}

init(_ code: POSIXErrorCode) {
self.init(_nsError: NSPOSIXError(code))
init(_ code: POSIXErrorCode,
function: StaticString = #function,
file: StaticString = #file,
line: UInt = #line) {

self.init(_nsError: NSPOSIXError(code, function: function, file: file, line: line))
}

var debugInformation: String? {
return userInfo[NSPOSIXError.debugInformationKey] as? String
}
}

Expand All @@ -47,7 +57,7 @@ extension POSIXError: CustomStringConvertible {
}

#if os(macOS)
extension POSIXErrorCode {
extension POSIXErrorCode: CustomStringConvertible {
public var description: String {
return rawValue.description
}
Expand All @@ -64,15 +74,26 @@ extension POSIXError: LocalizedError {

// MARK: - Supporting Types

/// NSError subclass for POSIX Errors
internal final class NSPOSIXError: NSError {

let posixError: POSIXErrorCode

init(_ code: POSIXErrorCode) {
init(_ code: POSIXErrorCode,
function: StaticString = #function,
file: StaticString = #file,
line: UInt = #line) {

var userInfo = [String: Any](minimumCapacity: 1)
userInfo[NSPOSIXError.debugInformationKey] = NSPOSIXError.debugInformation(
function: function,
file: file,
line: line)

self.posixError = code
super.init(domain: NSPOSIXErrorDomain,
code: Int(code.rawValue),
userInfo: nil)
userInfo: userInfo)
}

required init?(coder decoder: NSCoder) {
Expand All @@ -96,6 +117,30 @@ internal final class NSPOSIXError: NSError {
override var description: String {
return "\(posixError.errorMessage) (\(posixError))"
}

var debugInformation: String? {
return userInfo[NSPOSIXError.debugInformationKey] as? String
}
}

internal extension NSPOSIXError {

/// Contains
static let debugInformationKey: String = "NSPOSIXErrorDebugInformation"
}

private extension NSPOSIXError {

static let module = NSStringFromClass(NSPOSIXError.self).components(separatedBy:".")[0]

static func debugInformation(function: StaticString,
file: StaticString,
line: UInt) -> String {

let file = "\(file)"
let fileName = file.components(separatedBy: "/").last ?? file
return "\(module):\(fileName):\(function):\(line)"
}
}

#if !swift(>=5.1) && (os(Linux) || os(Android))
Expand Down
Loading

0 comments on commit 64c90c4

Please sign in to comment.