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