Merge pull request #107 from AlanQuatermain/master

A few cleanups and one bug fix.
This commit is contained in:
Bill Abt
2018-01-19 09:01:45 -05:00
committed by GitHub
2 changed files with 89 additions and 423 deletions
+38 -51
View File
@@ -825,7 +825,7 @@ public class Socket: SocketReader, SocketWriter {
readBuffer.deinitialize()
readBuffer.deallocate(capacity: oldValue)
readBuffer = UnsafeMutablePointer<CChar>.allocate(capacity: readBufferSize)
readBuffer.initialize(to:0)
readBuffer.initialize(to: 0, count: readBufferSize)
}
}
}
@@ -1129,7 +1129,7 @@ public class Socket: SocketReader, SocketWriter {
// Setup the array of readfds...
var readfds = fd_set()
FD.ZERO(set: &readfds)
readfds.zero()
var highSocketfd: Int32 = 0
for socket in sockets {
@@ -1137,7 +1137,7 @@ public class Socket: SocketReader, SocketWriter {
if socket.socketfd > highSocketfd {
highSocketfd = socket.socketfd
}
FD.SET(fd: socket.socketfd, set: &readfds)
readfds.set(socket.socketfd)
}
// Issue the select...
@@ -1160,15 +1160,7 @@ public class Socket: SocketReader, SocketWriter {
}
// Build the array of returned sockets...
var dataSockets = [Socket]()
for socket in sockets {
if FD.ISSET(fd: socket.socketfd, set: &readfds) {
dataSockets.append(socket)
}
}
return dataSockets
return sockets.filter { readfds.isSet($0.socketfd) }
}
///
@@ -1237,7 +1229,7 @@ public class Socket: SocketReader, SocketWriter {
private init(family: ProtocolFamily, type: SocketType, proto: SocketProtocol) throws {
// Initialize the read buffer...
self.readBuffer.initialize(to: 0)
self.readBuffer.initialize(to: 0, count: readBufferSize)
// If the family is .unix, set the protocol to .unix as well...
var sockProto = proto
@@ -1259,15 +1251,7 @@ public class Socket: SocketReader, SocketWriter {
throw Error(code: Socket.SOCKET_ERR_UNABLE_TO_CREATE_SOCKET, reason: self.lastError())
}
#if !os(Linux)
// Set the socket to ignore SIGPIPE to avoid dying on interrupted connections...
// Note: Linux does not support the SO_NOSIGPIPE option. Instead, we use the
// MSG_NOSIGNAL flags passed to send. See the write() functions below.
var on: Int32 = 1
if setsockopt(self.socketfd, SOL_SOCKET, SO_NOSIGPIPE, &on, socklen_t(MemoryLayout<Int32>.size)) < 0 {
throw Error(code: Socket.SOCKET_ERR_SETSOCKOPT_FAILED, reason: self.lastError())
}
#endif
try disableSIGPIPE(on: self.socketfd)
// Create the signature...
try self.signature = Signature(
@@ -1290,7 +1274,7 @@ public class Socket: SocketReader, SocketWriter {
self.isConnected = true
self.isListening = false
self.readBuffer.initialize(to: 0)
self.readBuffer.initialize(to: 0, count: readBufferSize)
self.socketfd = fd
@@ -1299,15 +1283,9 @@ public class Socket: SocketReader, SocketWriter {
let type = Int32(SOCK_STREAM.rawValue)
#else
let type = SOCK_STREAM
// Set the socket to ignore SIGPIPE to avoid dying on interrupted connections...
// Note: Linux does not support the SO_NOSIGPIPE option. Instead, we use the
// MSG_NOSIGNAL flags passed to send. See the write() functions below.
var on: Int32 = 1
if setsockopt(self.socketfd, SOL_SOCKET, SO_NOSIGPIPE, &on, socklen_t(MemoryLayout<Int32>.size)) < 0 {
throw Error(code: Socket.SOCKET_ERR_SETSOCKOPT_FAILED, reason: self.lastError())
}
#endif
try disableSIGPIPE(on: self.socketfd)
if path != nil {
@@ -1664,7 +1642,7 @@ public class Socket: SocketReader, SocketWriter {
if status == EAI_SYSTEM {
errorString = String(validatingUTF8: strerror(errno)) ?? "Unknown error code."
} else {
errorString = String(validatingUTF8: gai_strerror(errno)) ?? "Unknown error code."
errorString = String(validatingUTF8: gai_strerror(status)) ?? "Unknown error code."
}
throw Error(code: Socket.SOCKET_ERR_GETADDRINFO_FAILED, reason: errorString)
}
@@ -1727,8 +1705,8 @@ public class Socket: SocketReader, SocketWriter {
// Set up for the select call...
var writefds = fd_set()
FD.ZERO(set: &writefds)
FD.SET(fd: socketDescriptor!, set: &writefds)
writefds.zero()
writefds.set(socketDescriptor!)
var timer = timeval()
@@ -1757,7 +1735,7 @@ public class Socket: SocketReader, SocketWriter {
// If the socket is writable, we're probably connected, but check anyway to be sure...
// Otherwise, we've timed out waiting to connect.
if FD.ISSET(fd: socketDescriptor!, set: &writefds) {
if writefds.isSet(socketDescriptor!) {
// Check the socket...
var result: Int = 0
@@ -1831,15 +1809,7 @@ public class Socket: SocketReader, SocketWriter {
throw Error(code: Socket.SOCKET_ERR_WRONG_PROTOCOL, reason: "Unable to determine connected socket protocol family.")
}
#if !os(Linux)
// Set the new socket to ignore SIGPIPE to avoid dying on interrupted connections...
// Note: Linux does not support the SO_NOSIGPIPE option. Instead, we use the
// MSG_NOSIGNAL flags passed to send. See the write() functions below.
var on: Int32 = 1
if setsockopt(self.socketfd, SOL_SOCKET, SO_NOSIGPIPE, &on, socklen_t(MemoryLayout<Int32>.size)) < 0 {
throw Error(code: Socket.SOCKET_ERR_SETSOCKOPT_FAILED, reason: self.lastError())
}
#endif
try disableSIGPIPE(on: self.socketfd)
try self.signature = Signature(
protocolFamily: Int32(info!.pointee.ai_family),
@@ -3175,12 +3145,12 @@ public class Socket: SocketReader, SocketWriter {
// Create a read and write file descriptor set for this socket...
var readfds = fd_set()
FD.ZERO(set: &readfds)
FD.SET(fd: self.socketfd, set: &readfds)
readfds.zero()
readfds.set(self.socketfd)
var writefds = fd_set()
FD.ZERO(set: &writefds)
FD.SET(fd: self.socketfd, set: &writefds)
writefds.zero()
writefds.set(self.socketfd)
// Do the wait...
var count: Int32 = 0
@@ -3226,7 +3196,7 @@ public class Socket: SocketReader, SocketWriter {
}
// Return a tuple containing whether or not this socket is readable and/or writable...
return (FD.ISSET(fd: self.socketfd, set: &readfds), FD.ISSET(fd: self.socketfd, set: &writefds))
return (readfds.isSet(self.socketfd), writefds.isSet(self.socketfd))
}
///
@@ -3433,7 +3403,7 @@ public class Socket: SocketReader, SocketWriter {
private func readDataIntoStorage() throws -> Int {
// Clear the buffer...
self.readBuffer.initialize(to: 0x0)
self.readBuffer.initialize(to: 0x0, count: readBufferSize)
var recvFlags: Int32 = 0
if self.readStorage.length > 0 {
@@ -3545,7 +3515,7 @@ public class Socket: SocketReader, SocketWriter {
private func readDatagramIntoStorage() throws -> (bytesRead: Int, fromAddress: Address?) {
// Clear the buffer...
self.readBuffer.initialize(to: 0x0)
self.readBuffer.initialize(to: 0x0, count: readBufferSize)
var recvFlags: Int32 = 0
if self.readStorage.length > 0 {
recvFlags |= Int32(MSG_DONTWAIT)
@@ -3641,5 +3611,22 @@ public class Socket: SocketReader, SocketWriter {
return String(validatingUTF8: strerror(errno)) ?? "Error: \(errno)"
}
///
/// Private function to set no-SIGPIPE on a socket. No-op on Linux.
///
/// - Parameter fd: The socket file descriptor upon which to act.
///
private func disableSIGPIPE(on fd: Int32) throws {
#if !os(Linux)
// Set the new socket to ignore SIGPIPE to avoid dying on interrupted connections...
// Note: Linux does not support the SO_NOSIGPIPE option. Instead, we use the
// MSG_NOSIGNAL flags passed to send. See the write() functions below.
var on: Int32 = 1
if setsockopt(self.socketfd, SOL_SOCKET, SO_NOSIGPIPE, &on, socklen_t(MemoryLayout<Int32>.size)) < 0 {
throw Error(code: Socket.SOCKET_ERR_SETSOCKOPT_FAILED, reason: self.lastError())
}
#endif
}
}
+51 -372
View File
@@ -112,387 +112,66 @@ extension Socket.Address {
}
}
#if arch(arm) && os(Linux)
#if os(Linux)
public struct FD {
/// Replacement for FD_ZERO macro
public static func ZERO(set: inout fd_set) {
set.__fds_bits = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
}
/// Replacement for FD_SET macro
public static func SET(fd: Int32, set: inout fd_set) {
let intOffset = Int32(fd / 32)
let bitOffset: Int32 = Int32(fd % 32)
let mask: Int32 = 1 << bitOffset
switch intOffset {
case 0: set.__fds_bits.0 = set.__fds_bits.0 | mask
case 1: set.__fds_bits.1 = set.__fds_bits.1 | mask
case 2: set.__fds_bits.2 = set.__fds_bits.2 | mask
case 3: set.__fds_bits.3 = set.__fds_bits.3 | mask
case 4: set.__fds_bits.4 = set.__fds_bits.4 | mask
case 5: set.__fds_bits.5 = set.__fds_bits.5 | mask
case 6: set.__fds_bits.6 = set.__fds_bits.6 | mask
case 7: set.__fds_bits.7 = set.__fds_bits.7 | mask
case 8: set.__fds_bits.8 = set.__fds_bits.8 | mask
case 9: set.__fds_bits.9 = set.__fds_bits.9 | mask
case 10: set.__fds_bits.10 = set.__fds_bits.10 | mask
case 11: set.__fds_bits.11 = set.__fds_bits.11 | mask
case 12: set.__fds_bits.12 = set.__fds_bits.12 | mask
case 13: set.__fds_bits.13 = set.__fds_bits.13 | mask
case 14: set.__fds_bits.14 = set.__fds_bits.14 | mask
case 15: set.__fds_bits.15 = set.__fds_bits.15 | mask
case 16: set.__fds_bits.16 = set.__fds_bits.16 | mask
case 17: set.__fds_bits.17 = set.__fds_bits.17 | mask
case 18: set.__fds_bits.18 = set.__fds_bits.18 | mask
case 19: set.__fds_bits.19 = set.__fds_bits.19 | mask
case 20: set.__fds_bits.20 = set.__fds_bits.20 | mask
case 21: set.__fds_bits.21 = set.__fds_bits.21 | mask
case 22: set.__fds_bits.22 = set.__fds_bits.22 | mask
case 23: set.__fds_bits.23 = set.__fds_bits.23 | mask
case 24: set.__fds_bits.24 = set.__fds_bits.24 | mask
case 25: set.__fds_bits.25 = set.__fds_bits.25 | mask
case 26: set.__fds_bits.26 = set.__fds_bits.26 | mask
case 27: set.__fds_bits.27 = set.__fds_bits.27 | mask
case 28: set.__fds_bits.28 = set.__fds_bits.28 | mask
case 29: set.__fds_bits.29 = set.__fds_bits.29 | mask
case 30: set.__fds_bits.20 = set.__fds_bits.30 | mask
case 31: set.__fds_bits.31 = set.__fds_bits.31 | mask
default: break
}
}
/// Replacement for FD_CLR macro
public static func CLR(fd: Int32, set: inout fd_set) {
let intOffset = Int32(fd / 32)
let bitOffset: Int32 = Int32(fd % 32)
let mask: Int32 = ~(1 << bitOffset)
switch intOffset {
case 0: set.__fds_bits.0 = set.__fds_bits.0 & mask
case 1: set.__fds_bits.1 = set.__fds_bits.1 & mask
case 2: set.__fds_bits.2 = set.__fds_bits.2 & mask
case 3: set.__fds_bits.3 = set.__fds_bits.3 & mask
case 4: set.__fds_bits.4 = set.__fds_bits.4 & mask
case 5: set.__fds_bits.5 = set.__fds_bits.5 & mask
case 6: set.__fds_bits.6 = set.__fds_bits.6 & mask
case 7: set.__fds_bits.7 = set.__fds_bits.7 & mask
case 8: set.__fds_bits.8 = set.__fds_bits.8 & mask
case 9: set.__fds_bits.9 = set.__fds_bits.9 & mask
case 10: set.__fds_bits.10 = set.__fds_bits.10 & mask
case 11: set.__fds_bits.11 = set.__fds_bits.11 & mask
case 12: set.__fds_bits.12 = set.__fds_bits.12 & mask
case 13: set.__fds_bits.13 = set.__fds_bits.13 & mask
case 14: set.__fds_bits.14 = set.__fds_bits.14 & mask
case 15: set.__fds_bits.15 = set.__fds_bits.15 & mask
case 16: set.__fds_bits.16 = set.__fds_bits.16 & mask
case 17: set.__fds_bits.17 = set.__fds_bits.17 & mask
case 18: set.__fds_bits.18 = set.__fds_bits.18 & mask
case 19: set.__fds_bits.19 = set.__fds_bits.19 & mask
case 20: set.__fds_bits.20 = set.__fds_bits.20 & mask
case 21: set.__fds_bits.21 = set.__fds_bits.21 & mask
case 22: set.__fds_bits.22 = set.__fds_bits.22 & mask
case 23: set.__fds_bits.23 = set.__fds_bits.23 & mask
case 24: set.__fds_bits.24 = set.__fds_bits.24 & mask
case 25: set.__fds_bits.25 = set.__fds_bits.25 & mask
case 26: set.__fds_bits.26 = set.__fds_bits.26 & mask
case 27: set.__fds_bits.27 = set.__fds_bits.27 & mask
case 28: set.__fds_bits.28 = set.__fds_bits.28 & mask
case 29: set.__fds_bits.29 = set.__fds_bits.29 & mask
case 30: set.__fds_bits.20 = set.__fds_bits.30 & mask
case 31: set.__fds_bits.31 = set.__fds_bits.31 & mask
default: break
}
}
/// Replacement for FD_ISSET macro
public static func ISSET(fd: Int32, set: inout fd_set) -> Bool {
let intOffset = Int32(fd / 32)
let bitOffset = Int32(fd % 32)
let mask: Int32 = 1 << bitOffset
switch intOffset {
case 0: return set.__fds_bits.0 & mask != 0
case 1: return set.__fds_bits.1 & mask != 0
case 2: return set.__fds_bits.2 & mask != 0
case 3: return set.__fds_bits.3 & mask != 0
case 4: return set.__fds_bits.4 & mask != 0
case 5: return set.__fds_bits.5 & mask != 0
case 6: return set.__fds_bits.6 & mask != 0
case 7: return set.__fds_bits.7 & mask != 0
case 8: return set.__fds_bits.8 & mask != 0
case 9: return set.__fds_bits.9 & mask != 0
case 10: return set.__fds_bits.10 & mask != 0
case 11: return set.__fds_bits.11 & mask != 0
case 12: return set.__fds_bits.12 & mask != 0
case 13: return set.__fds_bits.13 & mask != 0
case 14: return set.__fds_bits.14 & mask != 0
case 15: return set.__fds_bits.15 & mask != 0
case 16: return set.__fds_bits.16 & mask != 0
case 17: return set.__fds_bits.17 & mask != 0
case 18: return set.__fds_bits.18 & mask != 0
case 19: return set.__fds_bits.19 & mask != 0
case 20: return set.__fds_bits.20 & mask != 0
case 21: return set.__fds_bits.21 & mask != 0
case 22: return set.__fds_bits.22 & mask != 0
case 23: return set.__fds_bits.23 & mask != 0
case 24: return set.__fds_bits.24 & mask != 0
case 25: return set.__fds_bits.25 & mask != 0
case 26: return set.__fds_bits.26 & mask != 0
case 27: return set.__fds_bits.27 & mask != 0
case 28: return set.__fds_bits.28 & mask != 0
case 29: return set.__fds_bits.29 & mask != 0
case 30: return set.__fds_bits.30 & mask != 0
case 31: return set.__fds_bits.31 & mask != 0
default: return false
}
}
}
#if arch(arm)
let __fd_set_count = 16
#else
let __fd_set_count = 32
#endif
#elseif os(Linux)
public struct FD {
/// Replacement for FD_ZERO macro
public static func ZERO(set: inout fd_set) {
set.__fds_bits = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
}
/// Replacement for FD_SET macro
public static func SET(fd: Int32, set: inout fd_set) {
let intOffset = Int(fd / 16)
let bitOffset: Int = Int(fd % 16)
let mask: Int = 1 << bitOffset
switch intOffset {
case 0: set.__fds_bits.0 = set.__fds_bits.0 | mask
case 1: set.__fds_bits.1 = set.__fds_bits.1 | mask
case 2: set.__fds_bits.2 = set.__fds_bits.2 | mask
case 3: set.__fds_bits.3 = set.__fds_bits.3 | mask
case 4: set.__fds_bits.4 = set.__fds_bits.4 | mask
case 5: set.__fds_bits.5 = set.__fds_bits.5 | mask
case 6: set.__fds_bits.6 = set.__fds_bits.6 | mask
case 7: set.__fds_bits.7 = set.__fds_bits.7 | mask
case 8: set.__fds_bits.8 = set.__fds_bits.8 | mask
case 9: set.__fds_bits.9 = set.__fds_bits.9 | mask
case 10: set.__fds_bits.10 = set.__fds_bits.10 | mask
case 11: set.__fds_bits.11 = set.__fds_bits.11 | mask
case 12: set.__fds_bits.12 = set.__fds_bits.12 | mask
case 13: set.__fds_bits.13 = set.__fds_bits.13 | mask
case 14: set.__fds_bits.14 = set.__fds_bits.14 | mask
case 15: set.__fds_bits.15 = set.__fds_bits.15 | mask
default: break
}
}
/// Replacement for FD_CLR macro
public static func CLR(fd: Int32, set: inout fd_set) {
let intOffset = Int(fd / 16)
let bitOffset: Int = Int(fd % 16)
let mask: Int = ~(1 << bitOffset)
switch intOffset {
case 0: set.__fds_bits.0 = set.__fds_bits.0 & mask
case 1: set.__fds_bits.1 = set.__fds_bits.1 & mask
case 2: set.__fds_bits.2 = set.__fds_bits.2 & mask
case 3: set.__fds_bits.3 = set.__fds_bits.3 & mask
case 4: set.__fds_bits.4 = set.__fds_bits.4 & mask
case 5: set.__fds_bits.5 = set.__fds_bits.5 & mask
case 6: set.__fds_bits.6 = set.__fds_bits.6 & mask
case 7: set.__fds_bits.7 = set.__fds_bits.7 & mask
case 8: set.__fds_bits.8 = set.__fds_bits.8 & mask
case 9: set.__fds_bits.9 = set.__fds_bits.9 & mask
case 10: set.__fds_bits.10 = set.__fds_bits.10 & mask
case 11: set.__fds_bits.11 = set.__fds_bits.11 & mask
case 12: set.__fds_bits.12 = set.__fds_bits.12 & mask
case 13: set.__fds_bits.13 = set.__fds_bits.13 & mask
case 14: set.__fds_bits.14 = set.__fds_bits.14 & mask
case 15: set.__fds_bits.15 = set.__fds_bits.15 & mask
default: break
}
}
/// Replacement for FD_ISSET macro
public static func ISSET(fd: Int32, set: inout fd_set) -> Bool {
let intOffset = Int(fd / 16)
let bitOffset = Int(fd % 16)
let mask: Int = 1 << bitOffset
switch intOffset {
case 0: return set.__fds_bits.0 & mask != 0
case 1: return set.__fds_bits.1 & mask != 0
case 2: return set.__fds_bits.2 & mask != 0
case 3: return set.__fds_bits.3 & mask != 0
case 4: return set.__fds_bits.4 & mask != 0
case 5: return set.__fds_bits.5 & mask != 0
case 6: return set.__fds_bits.6 & mask != 0
case 7: return set.__fds_bits.7 & mask != 0
case 8: return set.__fds_bits.8 & mask != 0
case 9: return set.__fds_bits.9 & mask != 0
case 10: return set.__fds_bits.10 & mask != 0
case 11: return set.__fds_bits.11 & mask != 0
case 12: return set.__fds_bits.12 & mask != 0
case 13: return set.__fds_bits.13 & mask != 0
case 14: return set.__fds_bits.14 & mask != 0
case 15: return set.__fds_bits.15 & mask != 0
default: return false
extension fd_set
{
@inline(__always)
mutating func withCArrayAccess<T>(block: (UnsafeMutablePointer<Int32>) throws -> T) rethrows -> T {
return try withUnsafeMutablePointer(to: &__fds_bits) {
try block(UnsafeMutableRawPointer($0).assumingMemoryBound(to: Int32.self))
}
}
}
#else
#else // not Linux on ARM
public struct FD {
/// Replacement for FD_ZERO macro
public static func ZERO(set: inout fd_set) {
set.fds_bits = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
}
/// Replacement for FD_SET macro
public static func SET(fd: Int32, set: inout fd_set) {
let intOffset = Int32(fd / 32)
let bitOffset = fd % 32
let mask: Int32 = 1 << bitOffset
switch intOffset {
case 0: set.fds_bits.0 = set.fds_bits.0 | mask
case 1: set.fds_bits.1 = set.fds_bits.1 | mask
case 2: set.fds_bits.2 = set.fds_bits.2 | mask
case 3: set.fds_bits.3 = set.fds_bits.3 | mask
case 4: set.fds_bits.4 = set.fds_bits.4 | mask
case 5: set.fds_bits.5 = set.fds_bits.5 | mask
case 6: set.fds_bits.6 = set.fds_bits.6 | mask
case 7: set.fds_bits.7 = set.fds_bits.7 | mask
case 8: set.fds_bits.8 = set.fds_bits.8 | mask
case 9: set.fds_bits.9 = set.fds_bits.9 | mask
case 10: set.fds_bits.10 = set.fds_bits.10 | mask
case 11: set.fds_bits.11 = set.fds_bits.11 | mask
case 12: set.fds_bits.12 = set.fds_bits.12 | mask
case 13: set.fds_bits.13 = set.fds_bits.13 | mask
case 14: set.fds_bits.14 = set.fds_bits.14 | mask
case 15: set.fds_bits.15 = set.fds_bits.15 | mask
case 16: set.fds_bits.16 = set.fds_bits.16 | mask
case 17: set.fds_bits.17 = set.fds_bits.17 | mask
case 18: set.fds_bits.18 = set.fds_bits.18 | mask
case 19: set.fds_bits.19 = set.fds_bits.19 | mask
case 20: set.fds_bits.20 = set.fds_bits.20 | mask
case 21: set.fds_bits.21 = set.fds_bits.21 | mask
case 22: set.fds_bits.22 = set.fds_bits.22 | mask
case 23: set.fds_bits.23 = set.fds_bits.23 | mask
case 24: set.fds_bits.24 = set.fds_bits.24 | mask
case 25: set.fds_bits.25 = set.fds_bits.25 | mask
case 26: set.fds_bits.26 = set.fds_bits.26 | mask
case 27: set.fds_bits.27 = set.fds_bits.27 | mask
case 28: set.fds_bits.28 = set.fds_bits.28 | mask
case 29: set.fds_bits.29 = set.fds_bits.29 | mask
case 30: set.fds_bits.30 = set.fds_bits.30 | mask
case 31: set.fds_bits.31 = set.fds_bits.31 | mask
default: break
let __fd_set_count = Int(__DARWIN_FD_SETSIZE) / MemoryLayout<Int32>.stride
extension fd_set
{
@inline(__always)
mutating func withCArrayAccess<T>(block: (UnsafeMutablePointer<Int32>) throws -> T) rethrows -> T {
return try withUnsafeMutablePointer(to: &fds_bits) {
try block(UnsafeMutableRawPointer($0).assumingMemoryBound(to: Int32.self))
}
}
/// Replacement for FD_CLR macro
public static func CLR(fd: Int32, set: inout fd_set) {
let intOffset = Int32(fd / 32)
let bitOffset = fd % 32
let mask: Int32 = ~(1 << bitOffset)
switch intOffset {
case 0: set.fds_bits.0 = set.fds_bits.0 & mask
case 1: set.fds_bits.1 = set.fds_bits.1 & mask
case 2: set.fds_bits.2 = set.fds_bits.2 & mask
case 3: set.fds_bits.3 = set.fds_bits.3 & mask
case 4: set.fds_bits.4 = set.fds_bits.4 & mask
case 5: set.fds_bits.5 = set.fds_bits.5 & mask
case 6: set.fds_bits.6 = set.fds_bits.6 & mask
case 7: set.fds_bits.7 = set.fds_bits.7 & mask
case 8: set.fds_bits.8 = set.fds_bits.8 & mask
case 9: set.fds_bits.9 = set.fds_bits.9 & mask
case 10: set.fds_bits.10 = set.fds_bits.10 & mask
case 11: set.fds_bits.11 = set.fds_bits.11 & mask
case 12: set.fds_bits.12 = set.fds_bits.12 & mask
case 13: set.fds_bits.13 = set.fds_bits.13 & mask
case 14: set.fds_bits.14 = set.fds_bits.14 & mask
case 15: set.fds_bits.15 = set.fds_bits.15 & mask
case 16: set.fds_bits.16 = set.fds_bits.16 & mask
case 17: set.fds_bits.17 = set.fds_bits.17 & mask
case 18: set.fds_bits.18 = set.fds_bits.18 & mask
case 19: set.fds_bits.19 = set.fds_bits.19 & mask
case 20: set.fds_bits.20 = set.fds_bits.20 & mask
case 21: set.fds_bits.21 = set.fds_bits.21 & mask
case 22: set.fds_bits.22 = set.fds_bits.22 & mask
case 23: set.fds_bits.23 = set.fds_bits.23 & mask
case 24: set.fds_bits.24 = set.fds_bits.24 & mask
case 25: set.fds_bits.25 = set.fds_bits.25 & mask
case 26: set.fds_bits.26 = set.fds_bits.26 & mask
case 27: set.fds_bits.27 = set.fds_bits.27 & mask
case 28: set.fds_bits.28 = set.fds_bits.28 & mask
case 29: set.fds_bits.29 = set.fds_bits.29 & mask
case 30: set.fds_bits.30 = set.fds_bits.30 & mask
case 31: set.fds_bits.31 = set.fds_bits.31 & mask
default: break
}
}
/// Replacement for FD_ISSET macro
public static func ISSET(fd: Int32, set: inout fd_set) -> Bool {
let intOffset = Int32(fd / 32)
let bitOffset = fd % 32
let mask: Int32 = 1 << bitOffset
switch intOffset {
case 0: return set.fds_bits.0 & mask != 0
case 1: return set.fds_bits.1 & mask != 0
case 2: return set.fds_bits.2 & mask != 0
case 3: return set.fds_bits.3 & mask != 0
case 4: return set.fds_bits.4 & mask != 0
case 5: return set.fds_bits.5 & mask != 0
case 6: return set.fds_bits.6 & mask != 0
case 7: return set.fds_bits.7 & mask != 0
case 8: return set.fds_bits.8 & mask != 0
case 9: return set.fds_bits.9 & mask != 0
case 10: return set.fds_bits.10 & mask != 0
case 11: return set.fds_bits.11 & mask != 0
case 12: return set.fds_bits.12 & mask != 0
case 13: return set.fds_bits.13 & mask != 0
case 14: return set.fds_bits.14 & mask != 0
case 15: return set.fds_bits.15 & mask != 0
case 16: return set.fds_bits.16 & mask != 0
case 17: return set.fds_bits.17 & mask != 0
case 18: return set.fds_bits.18 & mask != 0
case 19: return set.fds_bits.19 & mask != 0
case 20: return set.fds_bits.20 & mask != 0
case 21: return set.fds_bits.21 & mask != 0
case 22: return set.fds_bits.22 & mask != 0
case 23: return set.fds_bits.23 & mask != 0
case 24: return set.fds_bits.24 & mask != 0
case 25: return set.fds_bits.25 & mask != 0
case 26: return set.fds_bits.26 & mask != 0
case 27: return set.fds_bits.27 & mask != 0
case 28: return set.fds_bits.28 & mask != 0
case 29: return set.fds_bits.29 & mask != 0
case 30: return set.fds_bits.30 & mask != 0
case 31: return set.fds_bits.31 & mask != 0
default: return false
}
}
}
#endif
public extension fd_set
{
@inline(__always)
private static func address(for fd: Int32) -> (Int, Int32) {
let intOffset = Int(fd) / __fd_set_count
let bitOffset = Int(fd) % __fd_set_count
let mask = Int32(1 << bitOffset)
return (intOffset, mask)
}
public mutating func zero() {
withCArrayAccess { $0.initialize(to: 0, count: __fd_set_count) }
}
public mutating func set(_ fd: Int32) {
let (index, mask) = fd_set.address(for: fd)
withCArrayAccess { $0[index] |= mask }
}
public mutating func clear(_ fd: Int32) {
let (index, mask) = fd_set.address(for: fd)
withCArrayAccess { $0[index] &= ~mask }
}
public mutating func isSet(_ fd: Int32) -> Bool {
let (index, mask) = fd_set.address(for: fd)
return withCArrayAccess { $0[index] & mask != 0 }
}
}