]> gitweb.factorcode.org Git - factor.git/blob - basis/windows/winsock/winsock.factor
Merge branch 'master' of git://factorcode.org/git/factor into s3
[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 literals ;
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 CONSTANT: AI_MASK flags{ AI_PASSIVE AI_CANONNAME AI_NUMERICHOST }
77
78 CONSTANT: NI_NUMERICHOST 1
79 CONSTANT: NI_NUMERICSERV 2
80
81 CONSTANT: IPPROTO_TCP    6
82 CONSTANT: IPPROTO_UDP   17
83 CONSTANT: IPPROTO_RM   113
84
85 CONSTANT: WSA_FLAG_OVERLAPPED 1
86 ALIAS: WSA_WAIT_EVENT_0 WAIT_OBJECT_0
87 ALIAS: WSA_MAXIMUM_WAIT_EVENTS MAXIMUM_WAIT_OBJECTS
88 CONSTANT: WSA_INVALID_EVENT f
89 CONSTANT: WSA_WAIT_FAILED -1
90 ALIAS: WSA_WAIT_IO_COMPLETION WAIT_IO_COMPLETION
91 ALIAS: WSA_WAIT_TIMEOUT WAIT_TIMEOUT
92 ALIAS: WSA_INFINITE INFINITE
93 ALIAS: WSA_IO_PENDING ERROR_IO_PENDING
94
95 CONSTANT: INADDR_ANY 0
96
97 : INVALID_SOCKET ( -- n ) -1 <alien> ; inline
98
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 C-TYPE: sockaddr
108
109 STRUCT: sockaddr-in
110     { family short }
111     { port ushort }
112     { addr uint }
113     { pad char[8] } ;
114
115 STRUCT: sockaddr-in6
116     { family uchar }
117     { port ushort }
118     { flowinfo uint }
119     { addr uchar[16] }
120     { scopeid uint } ;
121
122 STRUCT: hostent
123     { name c-string }
124     { aliases void* }
125     { addrtype short }
126     { length short }
127     { addr-list void* } ;
128
129 STRUCT: addrinfo
130     { flags int }
131     { family int }
132     { socktype int }
133     { protocol int }
134     { addrlen size_t }
135     { canonname c-string }
136     { addr sockaddr* }
137     { next addrinfo* } ;
138
139 STRUCT: timeval
140     { sec long }
141     { usec long } ;
142
143 C-TYPE: fd_set
144
145 LIBRARY: winsock
146
147 FUNCTION: int setsockopt ( SOCKET s, int level, int optname, c-string optval, int optlen ) ;
148
149 FUNCTION: ushort htons ( ushort n ) ;
150 FUNCTION: ushort ntohs ( ushort n ) ;
151 FUNCTION: int bind ( void* socket, sockaddr-in* sockaddr, int len ) ;
152 FUNCTION: int listen ( void* socket, int backlog ) ;
153 FUNCTION: c-string inet_ntoa ( int in-addr ) ;
154 FUNCTION: int getaddrinfo ( c-string nodename,
155                             c-string servername,
156                             addrinfo* hints,
157                             addrinfo** res ) ;
158
159 FUNCTION: void freeaddrinfo ( addrinfo* ai ) ;
160
161
162 FUNCTION: hostent* gethostbyname ( c-string name ) ;
163 FUNCTION: int gethostname ( c-string name, int len ) ;
164 FUNCTION: int connect ( void* socket, sockaddr-in* sockaddr, int addrlen ) ;
165 FUNCTION: int select ( int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, timeval* timeout ) ;
166 FUNCTION: int closesocket ( SOCKET s ) ;
167 FUNCTION: int shutdown ( SOCKET s, int how ) ;
168 FUNCTION: int send ( SOCKET s, c-string buf, int len, int flags ) ;
169 FUNCTION: int recv ( SOCKET s, c-string buf, int len, int flags ) ;
170
171 FUNCTION: int getsockname ( SOCKET s, sockaddr-in* address, int* addrlen ) ;
172 FUNCTION: int getpeername ( SOCKET s, sockaddr-in* address, int* addrlen ) ;
173
174 TYPEDEF: uint SERVICETYPE
175 TYPEDEF: OVERLAPPED WSAOVERLAPPED
176 TYPEDEF: WSAOVERLAPPED* LPWSAOVERLAPPED
177 TYPEDEF: uint GROUP
178 TYPEDEF: void* LPCONDITIONPROC
179 TYPEDEF: HANDLE WSAEVENT
180 TYPEDEF: LPHANDLE LPWSAEVENT
181 TYPEDEF: sockaddr* LPSOCKADDR
182
183 STRUCT: FLOWSPEC
184     { TokenRate          uint        }
185     { TokenBucketSize    uint        }
186     { PeakBandwidth      uint        }
187     { Latency            uint        }
188     { DelayVariation     uint        }
189     { ServiceType        SERVICETYPE }
190     { MaxSduSize         uint        }
191     { MinimumPolicedSize uint        } ;
192 TYPEDEF: FLOWSPEC* PFLOWSPEC
193 TYPEDEF: FLOWSPEC* LPFLOWSPEC
194
195 STRUCT: WSABUF
196     { len ulong }
197     { buf void* } ;
198 TYPEDEF: WSABUF* LPWSABUF
199
200 STRUCT: QOS
201     { SendingFlowspec FLOWSPEC }
202     { ReceivingFlowspec FLOWSPEC }
203     { ProviderSpecific WSABUF } ;
204 TYPEDEF: QOS* LPQOS
205
206 CONSTANT: MAX_PROTOCOL_CHAIN 7
207
208 STRUCT: WSAPROTOCOLCHAIN
209     { ChainLen int }
210     { ChainEntries { DWORD 7 } } ;
211     ! { ChainEntries { DWORD MAX_PROTOCOL_CHAIN } } ;
212 TYPEDEF: WSAPROTOCOLCHAIN* LPWSAPROTOCOLCHAIN
213
214 CONSTANT: WSAPROTOCOL_LEN 255
215
216 STRUCT: WSAPROTOCOL_INFOW
217     { dwServiceFlags1 DWORD }
218     { dwServiceFlags2 DWORD }
219     { dwServiceFlags3 DWORD }
220     { dwServiceFlags4 DWORD }
221     { dwProviderFlags DWORD }
222     { ProviderId GUID }
223     { dwCatalogEntryId DWORD }
224     { ProtocolChain WSAPROTOCOLCHAIN }
225     { iVersion int }
226     { iAddressFamily int }
227     { iMaxSockAddr int }
228     { iMinSockAddr int }
229     { iSocketType int }
230     { iProtocol int }
231     { iProtocolMaxOffset int }
232     { iNetworkByteOrder int }
233     { iSecurityScheme int }
234     { dwMessageSize DWORD }
235     { dwProviderReserved DWORD }
236     { szProtocol { WCHAR 256 } } ;
237     ! { szProtocol[WSAPROTOCOL_LEN+1] { WCHAR 256 } } ;
238 TYPEDEF: WSAPROTOCOL_INFOW* PWSAPROTOCOL_INFOW
239 TYPEDEF: WSAPROTOCOL_INFOW* LPWSAPROTOCOL_INFOW
240 TYPEDEF: WSAPROTOCOL_INFOW WSAPROTOCOL_INFO
241 TYPEDEF: WSAPROTOCOL_INFOW* PWSAPROTOCOL_INFO
242 TYPEDEF: WSAPROTOCOL_INFOW* LPWSAPROTOCOL_INFO
243
244
245 STRUCT: WSANAMESPACE_INFOW
246     { NSProviderId   GUID    }
247     { dwNameSpace    DWORD   }
248     { fActive        BOOL    }
249     { dwVersion      DWORD   }
250     { lpszIdentifier LPWSTR  } ;
251 TYPEDEF: WSANAMESPACE_INFOW* PWSANAMESPACE_INFOW
252 TYPEDEF: WSANAMESPACE_INFOW* LPWSANAMESPACE_INFOW
253 TYPEDEF: WSANAMESPACE_INFOW WSANAMESPACE_INFO
254 TYPEDEF: WSANAMESPACE_INFO* PWSANAMESPACE_INFO
255 TYPEDEF: WSANAMESPACE_INFO* LPWSANAMESPACE_INFO
256
257 CONSTANT: FD_MAX_EVENTS 10
258
259 STRUCT: WSANETWORKEVENTS
260     { lNetworkEvents long }
261     { iErrorCode { int FD_MAX_EVENTS } } ;
262 TYPEDEF: WSANETWORKEVENTS* PWSANETWORKEVENTS
263 TYPEDEF: WSANETWORKEVENTS* LPWSANETWORKEVENTS
264
265 ! STRUCT: WSAOVERLAPPED
266     ! { Internal DWORD }
267     ! { InternalHigh DWORD }
268     ! { Offset DWORD }
269     ! { OffsetHigh DWORD }
270     ! { hEvent WSAEVENT }
271     ! { bytesTransferred DWORD } ;
272 ! TYPEDEF: WSAOVERLAPPED* LPWSAOVERLAPPED
273
274 FUNCTION: SOCKET WSAAccept ( SOCKET s,
275                              sockaddr* addr,
276                              LPINT addrlen,
277                              LPCONDITIONPROC lpfnCondition,
278                              DWORD dwCallbackData ) ;
279
280 ! FUNCTION: INT WSAAddressToString ( LPSOCKADDR lpsaAddress, DWORD dwAddressLength, LPWSAPROTOCOL_INFO lpProtocolInfo, LPTSTR lpszAddressString, LPDWORD lpdwAddressStringLength ) ;
281
282 FUNCTION: int WSACleanup ( ) ;
283 FUNCTION: BOOL WSACloseEvent ( WSAEVENT hEvent ) ;
284
285 FUNCTION: int WSAConnect ( SOCKET s,
286                            sockaddr* name,
287                            int namelen,
288                            LPWSABUF lpCallerData,
289                            LPWSABUF lpCalleeData,
290                            LPQOS lpSQOS,
291                            LPQOS lpGQOS ) ;
292 FUNCTION: WSAEVENT WSACreateEvent ( ) ;
293 ! FUNCTION: INT WSAEnumNameSpaceProviders ( LPDWORD lpdwBufferLength, LPWSANAMESPACE_INFO lpnspBuffer ) ;
294 FUNCTION: int WSAEnumNetworkEvents ( SOCKET s,
295                                      WSAEVENT hEventObject,
296                                      LPWSANETWORKEVENTS lpNetworkEvents ) ;
297 ! FUNCTION: int WSAEnumProtocols ( LPINT lpiProtocols, LPWSAPROTOCOL_INFO lpProtocolBuffer, LPDWORD lpwdBufferLength ) ;
298
299 FUNCTION: int WSAEventSelect ( SOCKET s,
300                                WSAEVENT hEventObject,
301                                long lNetworkEvents ) ;
302 FUNCTION: int WSAGetLastError ( ) ;
303 FUNCTION: BOOL WSAGetOverlappedResult ( SOCKET s,
304                                         LPWSAOVERLAPPED lpOverlapped,
305                                         LPDWORD lpcbTransfer,
306                                         BOOL fWait,
307                                         LPDWORD lpdwFlags ) ;
308
309 FUNCTION: int WSAIoctl ( SOCKET s,
310                          DWORD dwIoControlCode,
311                          LPVOID lpvInBuffer,
312                          DWORD cbInBuffer,
313                          LPVOID lpvOutBuffer,
314                          DWORD cbOutBuffer,
315                          LPDWORD lpcbBytesReturned,
316                          void* lpOverlapped,
317                          void* lpCompletionRoutine ) ;
318
319 TYPEDEF: void* LPWSAOVERLAPPED_COMPLETION_ROUTINE
320 FUNCTION: int WSARecv ( SOCKET s,
321                         LPWSABUF lpBuffers,
322                         DWORD dwBufferCount,
323                         LPDWORD lpNumberOfBytesRecvd,
324                         LPDWORD lpFlags,
325                         LPWSAOVERLAPPED lpOverlapped,
326                     LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine ) ;
327
328 FUNCTION: int WSARecvFrom ( SOCKET s,
329                     LPWSABUF lpBuffers,
330                     DWORD dwBufferCount,
331                     LPDWORD lpNumberOfBytesRecvd,
332                     LPDWORD lpFlags,
333                     sockaddr* lpFrom,
334                     LPINT lpFromlen,
335                     LPWSAOVERLAPPED lpOverlapped,
336                     LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine ) ;
337
338 FUNCTION: BOOL WSAResetEvent ( WSAEVENT hEvent ) ;
339 FUNCTION: int WSASend ( SOCKET s,
340                         LPWSABUF lpBuffers,
341                         DWORD dwBufferCount,
342                         LPDWORD lpNumberOfBytesSent,
343                         LPDWORD lpFlags,
344                         LPWSAOVERLAPPED lpOverlapped,
345                  LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine ) ;
346
347 FUNCTION: int WSASendTo ( SOCKET s,
348                           LPWSABUF lpBuffers,
349                           DWORD dwBufferCount,
350                           LPDWORD lpNumberOfBytesSent,
351                           DWORD dwFlags,
352                           sockaddr* lpTo,
353                           int iToLen,
354                           LPWSAOVERLAPPED lpOverlapped,
355   LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine ) ;
356
357
358 FUNCTION: int WSAStartup ( short version, void* out-data ) ;
359
360
361
362 FUNCTION: SOCKET WSASocketW ( int af,
363                              int type,
364                              int protocol,
365                              LPWSAPROTOCOL_INFOW lpProtocolInfo,
366                              GROUP g,
367                              DWORD flags ) ;
368 ALIAS: WSASocket WSASocketW
369
370 FUNCTION: DWORD WSAWaitForMultipleEvents ( DWORD cEvents,
371                                            WSAEVENT* lphEvents,
372                                            BOOL fWaitAll,
373                                            DWORD dwTimeout,
374                                            BOOL fAlertable ) ;
375
376
377 LIBRARY: mswsock
378
379 ! Not in Windows CE
380 FUNCTION: int AcceptEx ( void* listen, void* accept, void* out-buf, int recv-len, int addr-len, int remote-len, void* out-len, void* overlapped ) ;
381
382 FUNCTION: void GetAcceptExSockaddrs (
383   PVOID lpOutputBuffer,
384   DWORD dwReceiveDataLength,
385   DWORD dwLocalAddressLength,
386   DWORD dwRemoteAddressLength,
387   LPSOCKADDR* LocalSockaddr,
388   LPINT LocalSockaddrLength,
389   LPSOCKADDR* RemoteSockaddr,
390   LPINT RemoteSockaddrLength
391 ) ;
392
393 CONSTANT: SIO_GET_EXTENSION_FUNCTION_POINTER -939524090
394
395 CONSTANT: WSAID_CONNECTEX GUID: {25a207b9-ddf3-4660-8ee9-76e58c74063e}
396
397 : winsock-expected-error? ( n -- ? )
398     ${ ERROR_IO_PENDING ERROR_SUCCESS WSA_IO_PENDING } member? ;
399
400 : (winsock-error-string) ( n -- str )
401     ! #! WSAStartup returns the error code 'n' directly
402     dup winsock-expected-error?
403     [ drop f ] [ n>win32-error-string ] if ;
404
405 : winsock-error-string ( -- string/f )
406     WSAGetLastError (winsock-error-string) ;
407
408 : winsock-error ( -- )
409     winsock-error-string [ throw ] when* ;
410
411 : winsock-error=0/f ( n/f -- )
412     { 0 f } member? [
413         winsock-error-string throw
414     ] when ;
415
416 : winsock-error!=0/f ( n/f -- )
417     { 0 f } member? [
418         winsock-error-string throw
419     ] unless ;
420
421 : winsock-return-check ( n/f -- )
422     dup { 0 f } member? [
423         drop
424     ] [
425         (winsock-error-string) throw
426     ] if ;
427
428 : socket-error* ( n -- )
429     SOCKET_ERROR = [
430         WSAGetLastError
431         dup WSA_IO_PENDING = [
432             drop
433         ] [
434             (winsock-error-string) throw
435         ] if
436     ] when ;
437
438 : socket-error ( n -- )
439     SOCKET_ERROR = [ winsock-error ] when ;
440
441 : init-winsock ( -- )
442     HEX: 0202 <wsadata> WSAStartup winsock-return-check ;
443
444 : shutdown-winsock ( -- ) WSACleanup winsock-return-check ;
445
446 [ init-winsock ] "windows.winsock" add-startup-hook
447 [ shutdown-winsock ] "windows.winsock" add-shutdown-hook