31
31
32
32
#if canImport(WinSDK)
33
33
import WinSDK. WinSock2
34
+ import Foundation
34
35
35
36
let O_NONBLOCK = Int32 ( 1 )
36
37
let F_SETFL = Int32 ( 1 )
37
38
let F_GETFL = Int32 ( 1 )
38
39
var errno : Int32 { WSAGetLastError ( ) }
39
40
let EWOULDBLOCK = WSAEWOULDBLOCK
40
- let EBADF = WSA_INVALID_HANDLE
41
+ let EBADF = WSAENOTSOCK
41
42
let EINPROGRESS = WSAEINPROGRESS
42
43
let EISCONN = WSAEISCONN
43
- public typealias sa_family_t = UInt8
44
+ public typealias sa_family_t = ADDRESS_FAMILY
44
45
45
46
public extension Socket {
46
47
typealias FileDescriptorType = UInt64
@@ -59,10 +60,9 @@ extension Socket {
59
60
static let datagram = Int32 ( SOCK_DGRAM)
60
61
static let in_addr_any = WinSDK . in_addr ( )
61
62
static let ipproto_ip = Int32 ( IPPROTO_IP)
62
- static let ipproto_ipv6 = Int32 ( IPPROTO_IPV6)
63
+ static let ipproto_ipv6 = Int32 ( IPPROTO_IPV6 . rawValue )
63
64
static let ip_pktinfo = Int32 ( IP_PKTINFO)
64
65
static let ipv6_pktinfo = Int32 ( IPV6_PKTINFO)
65
- static let ipv6_recvpktinfo = Int32 ( IPV6_RECVPKTINFO)
66
66
67
67
static func makeAddressINET( port: UInt16 ) -> WinSDK . sockaddr_in {
68
68
WinSDK . sockaddr_in (
@@ -107,6 +107,7 @@ extension Socket {
107
107
}
108
108
109
109
static func fcntl( _ fd: FileDescriptorType , _ cmd: Int32 ) -> Int32 {
110
+ guard fd != INVALID_SOCKET else { return - 1 }
110
111
return 0
111
112
}
112
113
@@ -123,7 +124,110 @@ extension Socket {
123
124
}
124
125
125
126
static func socketpair( _ domain: Int32 , _ type: Int32 , _ protocol: Int32 ) -> ( FileDescriptorType , FileDescriptorType ) {
126
- ( - 1 , - 1 ) // no supported
127
+ guard domain == AF_UNIX else { return ( INVALID_SOCKET, INVALID_SOCKET) }
128
+ func makeTempUnixPath( ) -> URL {
129
+ let tempURL = FileManager . default. temporaryDirectory. appendingPathComponent ( " socketpair_ \( UUID ( ) . uuidString. prefix ( 8 ) ) .sock " , isDirectory: false )
130
+ try ? FileManager . default. removeItem ( at: tempURL)
131
+ return tempURL
132
+ }
133
+
134
+ if type == SOCK_STREAM {
135
+ let tempURL = makeTempUnixPath ( )
136
+ defer { try ? FileManager . default. removeItem ( at: tempURL) }
137
+
138
+ let listener = socket ( domain, type, `protocol`)
139
+
140
+ guard listener != INVALID_SOCKET else { return ( INVALID_SOCKET, INVALID_SOCKET) }
141
+
142
+ let addr = makeAddressUnix ( path: tempURL. path)
143
+
144
+ let bindListenerResult = addr. withSockAddr {
145
+ bind ( listener, $0, addr. size)
146
+ }
147
+
148
+ guard bindListenerResult == 0 else { return ( INVALID_SOCKET, INVALID_SOCKET) }
149
+
150
+ guard listen ( listener, 1 ) == 0 else {
151
+ _ = close ( listener)
152
+ return ( INVALID_SOCKET, INVALID_SOCKET)
153
+ }
154
+
155
+ let connector = socket ( domain, type, `protocol`)
156
+
157
+ guard connector != INVALID_SOCKET else {
158
+ _ = close ( listener)
159
+ return ( INVALID_SOCKET, INVALID_SOCKET)
160
+ }
161
+
162
+ let connectResult = addr. withSockAddr { connect ( connector, $0, addr. size) == 0 }
163
+
164
+ guard connectResult else {
165
+ _ = close ( listener)
166
+ _ = close ( connector)
167
+ return ( INVALID_SOCKET, INVALID_SOCKET)
168
+ }
169
+
170
+ let acceptor = accept ( listener, nil , nil )
171
+ guard acceptor != INVALID_SOCKET else {
172
+ _ = close ( listener)
173
+ _ = close ( connector)
174
+ return ( INVALID_SOCKET, INVALID_SOCKET)
175
+ }
176
+
177
+ _ = close ( listener)
178
+
179
+ return ( connector, acceptor)
180
+ } else if type == SOCK_DGRAM {
181
+ return ( INVALID_SOCKET, INVALID_SOCKET)
182
+ // unsupported at this time: https://github.com/microsoft/WSL/issues/5272
183
+ // let tempURL1 = makeTempUnixPath()
184
+ // let tempURL2 = makeTempUnixPath()
185
+ // guard FileManager.default.createFile(atPath: tempURL1.path, contents: nil) else { return (INVALID_SOCKET, INVALID_SOCKET) }
186
+ // guard FileManager.default.createFile(atPath: tempURL2.path, contents: nil) else { return (INVALID_SOCKET, INVALID_SOCKET) }
187
+
188
+ // defer { try? FileManager.default.removeItem(at: tempURL1) }
189
+ // defer { try? FileManager.default.removeItem(at: tempURL2) }
190
+
191
+ // let socket1 = socket(domain, type, `protocol`)
192
+ // let socket2 = socket(domain, type, `protocol`)
193
+
194
+ // guard socket1 != INVALID_SOCKET, socket2 != INVALID_SOCKET else {
195
+ // if socket1 != INVALID_SOCKET { _ = close(socket1) }
196
+ // if socket2 != INVALID_SOCKET { _ = close(socket2) }
197
+ // return (INVALID_SOCKET, INVALID_SOCKET)
198
+ // }
199
+
200
+ // let addr1 = makeAddressUnix(path: tempURL1.path)
201
+ // let addr2 = makeAddressUnix(path: tempURL2.path)
202
+
203
+ // guard addr1.withSockAddr({ bind(socket1, $0, addr1.size) }) == 0 else {
204
+ // _ = close(socket1)
205
+ // _ = close(socket2)
206
+ // return (INVALID_SOCKET, INVALID_SOCKET)
207
+ // }
208
+
209
+ // guard addr2.withSockAddr({ bind(socket2, $0, addr2.size) }) == 0 else {
210
+ // _ = close(socket1)
211
+ // _ = close(socket2)
212
+ // return (INVALID_SOCKET, INVALID_SOCKET)
213
+ // }
214
+
215
+ // guard addr2.withSockAddr({ connect(socket1, $0, addr2.size) }) == 0 else {
216
+ // _ = close(socket1)
217
+ // _ = close(socket2)
218
+ // return (INVALID_SOCKET, INVALID_SOCKET)
219
+ // }
220
+
221
+ // guard addr1.withSockAddr({ connect(socket2, $0, addr1.size) }) == 0 else {
222
+ // _ = close(socket1)
223
+ // _ = close(socket2)
224
+ // return (INVALID_SOCKET, INVALID_SOCKET)
225
+ // }
226
+
227
+ // return (socket1, socket2)
228
+ } else {
229
+ return ( INVALID_SOCKET, INVALID_SOCKET)
230
+ }
127
231
}
128
232
129
233
static func setsockopt( _ fd: FileDescriptorType , _ level: Int32 , _ name: Int32 ,
@@ -196,19 +300,29 @@ extension Socket {
196
300
}
197
301
198
302
static func recvfrom( _ fd: FileDescriptorType , _ buffer: UnsafeMutableRawPointer ! , _ nbyte: Int , _ flags: Int32 , _ addr: UnsafeMutablePointer < sockaddr > ! , _ len: UnsafeMutablePointer < socklen_t > ! ) -> Int {
199
- WinSDK . recvfrom ( fd, buffer, nbyte, flags, addr, len)
303
+ Int ( WinSDK . recvfrom ( fd, buffer, Int32 ( nbyte) , flags, addr, len) )
200
304
}
201
305
202
306
static func sendto( _ fd: FileDescriptorType , _ buffer: UnsafeRawPointer ! , _ nbyte: Int , _ flags: Int32 , _ destaddr: UnsafePointer < sockaddr > ! , _ destlen: socklen_t ) -> Int {
203
- WinSDK . sendto ( fd, buffer, nbyte, flags, destaddr, destlen)
307
+ Int ( WinSDK . sendto ( fd, buffer, Int32 ( nbyte) , flags, destaddr, destlen) )
204
308
}
309
+ }
205
310
206
- static func recvmsg( _ fd: FileDescriptorType , _ message: UnsafeMutablePointer < msghdr > , _ flags: Int32 ) -> Int {
207
- WinSDK . recvmsg ( fd, message, flags)
311
+ public extension in_addr {
312
+ var s_addr : UInt32 {
313
+ get {
314
+ S_un . S_addr
315
+ } set {
316
+ S_un . S_addr = newValue
317
+ }
208
318
}
319
+ }
209
320
210
- static func sendmsg( _ fd: FileDescriptorType , _ message: UnsafePointer < msghdr > , _ flags: Int32 ) -> Int {
211
- WinSDK . sendmsg ( fd, message, flags)
321
+ private extension URL {
322
+ var fileSystemRepresentation : String {
323
+ withUnsafeFileSystemRepresentation {
324
+ String ( cString: $0!)
325
+ }
212
326
}
213
327
}
214
328
0 commit comments