]> gitweb.factorcode.org Git - factor.git/blob - basis/windows/winsock/winsock.factor
Merge qualified, alias, symbols, constants into core
[factor.git] / basis / windows / winsock / winsock.factor
1 ! Copyright (C) 2006 Mackenzie Straight, Doug Coleman.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: alien alien.c-types alien.strings alien.syntax arrays
4 byte-arrays kernel math sequences windows.types windows.kernel32
5 windows.errors windows math.bitwise io.encodings.utf16n ;
6 IN: windows.winsock
7
8 USE: libc
9 : alien>byte-array ( alien str -- byte-array )
10     heap-size dup <byte-array> [ -rot memcpy ] keep ;
11
12 TYPEDEF: void* SOCKET
13
14 : <wsadata> ( -- byte-array )
15     HEX: 190 <byte-array> ;
16
17 CONSTANT: SOCK_STREAM    1
18 CONSTANT: SOCK_DGRAM     2
19 CONSTANT: SOCK_RAW       3
20 CONSTANT: SOCK_RDM       4
21 CONSTANT: SOCK_SEQPACKET 5
22
23 CONSTANT: SO_DEBUG       HEX:   1
24 CONSTANT: SO_ACCEPTCONN  HEX:   2
25 CONSTANT: SO_REUSEADDR   HEX:   4
26 CONSTANT: SO_KEEPALIVE   HEX:   8
27 CONSTANT: SO_DONTROUTE   HEX:  10
28 CONSTANT: SO_BROADCAST   HEX:  20
29 CONSTANT: SO_USELOOPBACK HEX:  40
30 CONSTANT: SO_LINGER      HEX:  80
31 CONSTANT: SO_OOBINLINE   HEX: 100
32 : SO_DONTLINGER ( -- n ) SO_LINGER bitnot ; inline
33
34 CONSTANT: SO_SNDBUF     HEX: 1001
35 CONSTANT: SO_RCVBUF     HEX: 1002
36 CONSTANT: SO_SNDLOWAT   HEX: 1003
37 CONSTANT: SO_RCVLOWAT   HEX: 1004
38 CONSTANT: SO_SNDTIMEO   HEX: 1005
39 CONSTANT: SO_RCVTIMEO   HEX: 1006
40 CONSTANT: SO_ERROR      HEX: 1007
41 CONSTANT: SO_TYPE       HEX: 1008
42
43 CONSTANT: TCP_NODELAY   HEX:    1
44
45 CONSTANT: AF_UNSPEC      0
46 CONSTANT: AF_UNIX        1
47 CONSTANT: AF_INET        2
48 CONSTANT: AF_IMPLINK     3
49 CONSTANT: AF_PUP         4
50 CONSTANT: AF_CHAOS       5
51 CONSTANT: AF_NS          6
52 CONSTANT: AF_ISO         7
53 ALIAS: AF_OSI    AF_ISO
54 CONSTANT: AF_ECMA        8
55 CONSTANT: AF_DATAKIT     9
56 CONSTANT: AF_CCITT      10
57 CONSTANT: AF_SNA        11
58 CONSTANT: AF_DECnet     12
59 CONSTANT: AF_DLI        13
60 CONSTANT: AF_LAT        14
61 CONSTANT: AF_HYLINK     15
62 CONSTANT: AF_APPLETALK  16
63 CONSTANT: AF_NETBIOS    17
64 CONSTANT: AF_MAX        18
65 CONSTANT: AF_INET6      23
66 CONSTANT: AF_IRDA       26
67 CONSTANT: AF_BTM        32
68
69 CONSTANT: PF_UNSPEC      0
70 CONSTANT: PF_LOCAL       1
71 CONSTANT: PF_INET        2
72 CONSTANT: PF_INET6      23
73
74 CONSTANT: AI_PASSIVE     1
75 CONSTANT: AI_CANONNAME   2
76 CONSTANT: AI_NUMERICHOST 4
77 : AI_MASK ( -- n ) { AI_PASSIVE AI_CANONNAME AI_NUMERICHOST } flags ;
78
79 CONSTANT: NI_NUMERICHOST 1
80 CONSTANT: NI_NUMERICSERV 2
81
82 CONSTANT: IPPROTO_TCP    6
83 CONSTANT: IPPROTO_UDP   17
84 CONSTANT: IPPROTO_RM   113
85
86 CONSTANT: WSA_FLAG_OVERLAPPED 1
87 ALIAS: WSA_WAIT_EVENT_0 WAIT_OBJECT_0
88 ALIAS: WSA_MAXIMUM_WAIT_EVENTS MAXIMUM_WAIT_OBJECTS
89 CONSTANT: WSA_INVALID_EVENT f
90 CONSTANT: WSA_WAIT_FAILED -1
91 ALIAS: WSA_WAIT_IO_COMPLETION WAIT_IO_COMPLETION
92 ALIAS: WSA_WAIT_TIMEOUT WAIT_TIMEOUT
93 ALIAS: WSA_INFINITE INFINITE
94 ALIAS: WSA_IO_PENDING ERROR_IO_PENDING
95
96 CONSTANT: INADDR_ANY 0
97
98 : INVALID_SOCKET ( -- alien ) -1 <alien> ; inline
99 CONSTANT: SOCKET_ERROR -1
100
101 CONSTANT: SD_RECV 0
102 CONSTANT: SD_SEND 1
103 CONSTANT: SD_BOTH 2
104
105 CONSTANT: SOL_SOCKET HEX: ffff
106
107 ! TYPEDEF: uint in_addr_t
108 ! C-STRUCT: in_addr
109     ! { "in_addr_t" "s_addr" } ;
110
111 C-STRUCT: sockaddr-in
112     { "short" "family" }
113     { "ushort" "port" }
114     { "uint" "addr" }
115     { { "char" 8 } "pad" } ;
116
117 C-STRUCT: sockaddr-in6
118     { "uchar" "family" }
119     { "ushort" "port" }
120     { "uint" "flowinfo" }
121     { { "uchar" 16 } "addr" }
122     { "uint" "scopeid" } ;
123
124 C-STRUCT: hostent
125     { "char*" "name" }
126     { "void*" "aliases" }
127     { "short" "addrtype" }
128     { "short" "length" }
129     { "void*" "addr-list" } ;
130
131 C-STRUCT: addrinfo
132     { "int" "flags" }
133     { "int" "family" }
134     { "int" "socktype" }
135     { "int" "protocol" }
136     { "size_t" "addrlen" }
137     { "char*" "canonname" }
138     { "sockaddr*" "addr" }
139     { "addrinfo*" "next" } ;
140
141 C-STRUCT: timeval
142     { "long" "sec" }
143     { "long" "usec" } ;
144
145 : hostent-addr ( hostent -- addr ) hostent-addr-list *void* ; ! *uint ;
146
147 LIBRARY: winsock
148
149
150 FUNCTION: int setsockopt ( SOCKET s, int level, int optname, char* optval, int optlen ) ;
151
152 FUNCTION: ushort htons ( ushort n ) ;
153 FUNCTION: ushort ntohs ( ushort n ) ;
154 FUNCTION: int bind ( void* socket, sockaddr_in* sockaddr, int len ) ;
155 FUNCTION: int listen ( void* socket, int backlog ) ;
156 FUNCTION: char* inet_ntoa ( int in-addr ) ;
157 FUNCTION: int getaddrinfo ( char* nodename,
158                             char* servername,
159                             addrinfo* hints,
160                             addrinfo** res ) ;
161
162 FUNCTION: void freeaddrinfo ( addrinfo* ai ) ;
163
164
165 FUNCTION: hostent* gethostbyname ( char* name ) ;
166 FUNCTION: int gethostname ( char* name, int len ) ;
167 FUNCTION: int connect ( void* socket, sockaddr_in* sockaddr, int addrlen ) ;
168 FUNCTION: int select ( int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, timeval* timeout ) ;
169 FUNCTION: int closesocket ( SOCKET s ) ;
170 FUNCTION: int shutdown ( SOCKET s, int how ) ;
171 FUNCTION: int send ( SOCKET s, char* buf, int len, int flags ) ;
172 FUNCTION: int recv ( SOCKET s, char* buf, int len, int flags ) ;
173
174 FUNCTION: int getsockname ( SOCKET s, sockaddr_in* address, int* addrlen ) ;
175 FUNCTION: int getpeername ( SOCKET s, sockaddr_in* address, int* addrlen ) ;
176
177 TYPEDEF: uint SERVICETYPE
178 TYPEDEF: OVERLAPPED WSAOVERLAPPED
179 TYPEDEF: WSAOVERLAPPED* LPWSAOVERLAPPED
180 TYPEDEF: uint GROUP
181 TYPEDEF: void* LPCONDITIONPROC
182 TYPEDEF: HANDLE WSAEVENT
183 TYPEDEF: LPHANDLE LPWSAEVENT
184 TYPEDEF: sockaddr* LPSOCKADDR
185
186 C-STRUCT: FLOWSPEC
187     { "uint"        "TokenRate" }
188     { "uint"        "TokenBucketSize" }
189     { "uint"        "PeakBandwidth" }
190     { "uint"        "Latency" }
191     { "uint"        "DelayVariation" }
192     { "SERVICETYPE" "ServiceType" }
193     { "uint"        "MaxSduSize" }
194     { "uint"        "MinimumPolicedSize" } ;
195 TYPEDEF: FLOWSPEC* PFLOWSPEC
196 TYPEDEF: FLOWSPEC* LPFLOWSPEC
197
198 C-STRUCT: WSABUF
199     { "ulong" "len" }
200     { "void*" "buf" } ;
201 TYPEDEF: WSABUF* LPWSABUF
202
203 C-STRUCT: QOS
204     { "FLOWSPEC" "SendingFlowspec" }
205     { "FLOWSPEC" "ReceivingFlowspec" }
206     { "WSABUF" "ProviderSpecific" } ;
207 TYPEDEF: QOS* LPQOS
208
209 CONSTANT: MAX_PROTOCOL_CHAIN 7
210
211 C-STRUCT: WSAPROTOCOLCHAIN
212     { "int" "ChainLen" }
213     ! { { "DWORD" MAX_PROTOCOL_CHAIN } "ChainEntries" } ;
214     { { "DWORD" 7 } "ChainEntries" } ;
215 TYPEDEF: WSAPROTOCOLCHAIN* LPWSAPROTOCOLCHAIN
216
217 CONSTANT: WSAPROTOCOL_LEN 255
218
219 C-STRUCT: WSAPROTOCOL_INFOW
220     { "DWORD" "dwServiceFlags1" }
221     { "DWORD" "dwServiceFlags2" }
222     { "DWORD" "dwServiceFlags3" }
223     { "DWORD" "dwServiceFlags4" }
224     { "DWORD" "dwProviderFlags" }
225     { "GUID" "ProviderId" }
226     { "DWORD" "dwCatalogEntryId" }
227     { "WSAPROTOCOLCHAIN" "ProtocolChain" }
228     { "int" "iVersion" }
229     { "int" "iAddressFamily" }
230     { "int" "iMaxSockAddr" }
231     { "int" "iMinSockAddr" }
232     { "int" "iSocketType" }
233     { "int" "iProtocol" }
234     { "int" "iProtocolMaxOffset" }
235     { "int" "iNetworkByteOrder" }
236     { "int" "iSecurityScheme" }
237     { "DWORD" "dwMessageSize" }
238     { "DWORD" "dwProviderReserved" }
239     { { "WCHAR" 256 } "szProtocol" } ;
240     ! { { "WCHAR" 256 } "szProtocol"[WSAPROTOCOL_LEN+1] } ;
241 TYPEDEF: WSAPROTOCOL_INFOW* PWSAPROTOCOL_INFOW
242 TYPEDEF: WSAPROTOCOL_INFOW* LPWSAPROTOCOL_INFOW
243 TYPEDEF: WSAPROTOCOL_INFOW WSAPROTOCOL_INFO
244 TYPEDEF: WSAPROTOCOL_INFOW* PWSAPROTOCOL_INFO
245 TYPEDEF: WSAPROTOCOL_INFOW* LPWSAPROTOCOL_INFO
246
247
248 C-STRUCT: WSANAMESPACE_INFOW
249     { "GUID"    "NSProviderId" }
250     { "DWORD"   "dwNameSpace" }
251     { "BOOL"    "fActive" }
252     { "DWORD"   "dwVersion" }
253     { "LPWSTR"  "lpszIdentifier" } ;
254 TYPEDEF: WSANAMESPACE_INFOW* PWSANAMESPACE_INFOW
255 TYPEDEF: WSANAMESPACE_INFOW* LPWSANAMESPACE_INFOW
256 TYPEDEF: WSANAMESPACE_INFOW WSANAMESPACE_INFO
257 TYPEDEF: WSANAMESPACE_INFO* PWSANAMESPACE_INFO
258 TYPEDEF: WSANAMESPACE_INFO* LPWSANAMESPACE_INFO
259
260 : FD_MAX_EVENTS 10 ;
261
262 C-STRUCT: WSANETWORKEVENTS
263     { "long" "lNetworkEvents" }
264     ! { { "int" "FD_MAX_EVENTS" } "iErrorCode" } ;
265     { { "int" 10 } "iErrorCode" } ;
266 TYPEDEF: WSANETWORKEVENTS* PWSANETWORKEVENTS
267 TYPEDEF: WSANETWORKEVENTS* LPWSANETWORKEVENTS
268
269 ! C-STRUCT: WSAOVERLAPPED
270     ! { "DWORD" "Internal" }
271     ! { "DWORD" "InternalHigh" }
272     ! { "DWORD" "Offset" }
273     ! { "DWORD" "OffsetHigh" }
274     ! { "WSAEVENT" "hEvent" }
275     ! { "DWORD" "bytesTransferred" } ;
276 ! TYPEDEF: WSAOVERLAPPED* LPWSAOVERLAPPED
277
278 FUNCTION: SOCKET WSAAccept ( SOCKET s,
279                              sockaddr* addr,
280                              LPINT addrlen,
281                              LPCONDITIONPROC lpfnCondition,
282                              DWORD dwCallbackData ) ;
283
284 ! FUNCTION: INT WSAAddressToString ( LPSOCKADDR lpsaAddress, DWORD dwAddressLength, LPWSAPROTOCOL_INFO lpProtocolInfo, LPTSTR lpszAddressString, LPDWORD lpdwAddressStringLength ) ;
285
286 FUNCTION: int WSACleanup ( ) ;
287 FUNCTION: BOOL WSACloseEvent ( WSAEVENT hEvent ) ;
288
289 FUNCTION: int WSAConnect ( SOCKET s,
290                            sockaddr* name,
291                            int namelen,
292                            LPWSABUF lpCallerData,
293                            LPWSABUF lpCalleeData,
294                            LPQOS lpSQOS,
295                            LPQOS lpGQOS ) ;
296 FUNCTION: WSAEVENT WSACreateEvent ( ) ;
297 ! FUNCTION: INT WSAEnumNameSpaceProviders ( LPDWORD lpdwBufferLength, LPWSANAMESPACE_INFO lpnspBuffer ) ;
298 FUNCTION: int WSAEnumNetworkEvents ( SOCKET s,
299                                      WSAEVENT hEventObject,
300                                      LPWSANETWORKEVENTS lpNetworkEvents ) ;
301 ! FUNCTION: int WSAEnumProtocols ( LPINT lpiProtocols, LPWSAPROTOCOL_INFO lpProtocolBuffer, LPDWORD lpwdBufferLength ) ;
302
303 FUNCTION: int WSAEventSelect ( SOCKET s,
304                                WSAEVENT hEventObject,
305                                long lNetworkEvents ) ;
306 FUNCTION: int WSAGetLastError ( ) ;
307 FUNCTION: BOOL WSAGetOverlappedResult ( SOCKET s,
308                                         LPWSAOVERLAPPED lpOverlapped,
309                                         LPDWORD lpcbTransfer,
310                                         BOOL fWait,
311                                         LPDWORD lpdwFlags ) ;
312
313 FUNCTION: int WSAIoctl ( SOCKET s,
314                          DWORD dwIoControlCode,
315                          LPVOID lpvInBuffer,
316                          DWORD cbInBuffer,
317                          LPVOID lpvOutBuffer,
318                          DWORD cbOutBuffer,
319                          LPDWORD lpcbBytesReturned,
320                          void* lpOverlapped,
321                          void* lpCompletionRoutine ) ;
322
323 TYPEDEF: void* LPWSAOVERLAPPED_COMPLETION_ROUTINE
324 FUNCTION: int WSARecv ( SOCKET s,
325                         LPWSABUF lpBuffers,
326                         DWORD dwBufferCount,
327                         LPDWORD lpNumberOfBytesRecvd,
328                         LPDWORD lpFlags,
329                         LPWSAOVERLAPPED lpOverlapped,
330                     LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine ) ;
331
332 FUNCTION: int WSARecvFrom ( SOCKET s,
333                     LPWSABUF lpBuffers,
334                     DWORD dwBufferCount,
335                     LPDWORD lpNumberOfBytesRecvd,
336                     LPDWORD lpFlags,
337                     sockaddr* lpFrom,
338                     LPINT lpFromlen,
339                     LPWSAOVERLAPPED lpOverlapped,
340                     LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine ) ;
341
342 FUNCTION: BOOL WSAResetEvent ( WSAEVENT hEvent ) ;
343 FUNCTION: int WSASend ( SOCKET s,
344                         LPWSABUF lpBuffers,
345                         DWORD dwBufferCount,
346                         LPDWORD lpNumberOfBytesSent,
347                         LPDWORD lpFlags,
348                         LPWSAOVERLAPPED lpOverlapped,
349                  LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine ) ;
350
351 FUNCTION: int WSASendTo ( SOCKET s,
352                           LPWSABUF lpBuffers,
353                           DWORD dwBufferCount,
354                           LPDWORD lpNumberOfBytesSent,
355                           DWORD dwFlags,
356                           sockaddr* lpTo,
357                           int iToLen,
358                           LPWSAOVERLAPPED lpOverlapped,
359   LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine ) ;
360
361
362 FUNCTION: int WSAStartup ( short version, void* out-data ) ;
363
364
365
366 FUNCTION: SOCKET WSASocketW ( int af,
367                              int type,
368                              int protocol,
369                              LPWSAPROTOCOL_INFOW lpProtocolInfo,
370                              GROUP g,
371                              DWORD flags ) ;
372 ALIAS: WSASocket WSASocketW
373
374 FUNCTION: DWORD WSAWaitForMultipleEvents ( DWORD cEvents,
375                                            WSAEVENT* lphEvents,
376                                            BOOL fWaitAll,
377                                            DWORD dwTimeout,
378                                            BOOL fAlertable ) ;
379
380
381
382
383 LIBRARY: mswsock
384
385 ! Not in Windows CE
386 FUNCTION: int AcceptEx ( void* listen, void* accept, void* out-buf, int recv-len, int addr-len, int remote-len, void* out-len, void* overlapped ) ;
387 FUNCTION: void GetAcceptExSockaddrs ( void* a, int b, int c, int d, void* e, void* f, void* g, void* h ) ;
388
389 CONSTANT: SIO_GET_EXTENSION_FUNCTION_POINTER -939524090
390
391 : WSAID_CONNECTEX ( -- GUID )
392     "GUID" <c-object>
393     HEX: 25a207b9 over set-GUID-Data1
394     HEX: ddf3 over set-GUID-Data2
395     HEX: 4660 over set-GUID-Data3
396     B{
397         HEX: 8e HEX: e9 HEX: 76 HEX: e5
398         HEX: 8c HEX: 74 HEX: 06 HEX: 3e
399     } over set-GUID-Data4 ;
400
401 : winsock-expected-error? ( n -- ? )
402     ERROR_IO_PENDING ERROR_SUCCESS WSA_IO_PENDING 3array member? ;
403
404 : (winsock-error-string) ( n -- str )
405     ! #! WSAStartup returns the error code 'n' directly
406     dup winsock-expected-error?
407     [ drop f ] [ error_message utf16n alien>string ] if ;
408
409 : winsock-error-string ( -- string/f )
410     WSAGetLastError (winsock-error-string) ;
411
412 : winsock-error ( -- )
413     winsock-error-string [ throw ] when* ;
414
415 : winsock-error=0/f ( n/f -- )
416     { 0 f } member? [
417         winsock-error-string throw
418     ] when ;
419
420 : winsock-error!=0/f ( n/f -- )
421     { 0 f } member? [
422         winsock-error-string throw
423     ] unless ;
424
425 : winsock-return-check ( n/f -- )
426     dup { 0 f } member? [
427         drop
428     ] [
429         (winsock-error-string) throw
430     ] if ;
431
432 : socket-error* ( n -- )
433     SOCKET_ERROR = [
434         WSAGetLastError
435         dup WSA_IO_PENDING = [
436             drop
437         ] [
438             (winsock-error-string) throw
439         ] if
440     ] when ;
441
442 : socket-error ( n -- )
443     SOCKET_ERROR = [ winsock-error ] when ;
444
445 : init-winsock ( -- )
446     HEX: 0202 <wsadata> WSAStartup winsock-return-check ;