factor/basis/windows/winsock/winsock.factor

447 lines
14 KiB
Factor
Raw Normal View History

2007-09-20 18:09:08 -04:00
! Copyright (C) 2006 Mackenzie Straight, Doug Coleman.
2008-10-06 19:28:10 -04:00
! See http://factorcode.org/license.txt for BSD license.
2008-04-21 20:04:17 -04:00
USING: alien alien.c-types alien.strings alien.syntax arrays
byte-arrays kernel math sequences windows.types windows.kernel32
2008-12-09 04:22:38 -05:00
windows.errors windows math.bitwise alias io.encodings.utf16n ;
2007-09-20 18:09:08 -04:00
IN: windows.winsock
USE: libc
: alien>byte-array ( alien str -- byte-array )
heap-size dup <byte-array> [ -rot memcpy ] keep ;
TYPEDEF: void* SOCKET
: <wsadata> ( -- byte-array )
HEX: 190 <byte-array> ;
: SOCK_STREAM 1 ; inline
: SOCK_DGRAM 2 ; inline
: SOCK_RAW 3 ; inline
: SOCK_RDM 4 ; inline
: SOCK_SEQPACKET 5 ; inline
: SO_DEBUG HEX: 1 ; inline
: SO_ACCEPTCONN HEX: 2 ; inline
: SO_REUSEADDR HEX: 4 ; inline
: SO_KEEPALIVE HEX: 8 ; inline
: SO_DONTROUTE HEX: 10 ; inline
: SO_BROADCAST HEX: 20 ; inline
: SO_USELOOPBACK HEX: 40 ; inline
: SO_LINGER HEX: 80 ; inline
: SO_OOBINLINE HEX: 100 ; inline
: SO_DONTLINGER SO_LINGER bitnot ; inline
: SO_SNDBUF HEX: 1001 ; inline
: SO_RCVBUF HEX: 1002 ; inline
: SO_SNDLOWAT HEX: 1003 ; inline
: SO_RCVLOWAT HEX: 1004 ; inline
: SO_SNDTIMEO HEX: 1005 ; inline
: SO_RCVTIMEO HEX: 1006 ; inline
: SO_ERROR HEX: 1007 ; inline
: SO_TYPE HEX: 1008 ; inline
: TCP_NODELAY HEX: 1 ; inline
: AF_UNSPEC 0 ; inline
: AF_UNIX 1 ; inline
: AF_INET 2 ; inline
: AF_IMPLINK 3 ; inline
: AF_PUP 4 ; inline
: AF_CHAOS 5 ; inline
: AF_NS 6 ; inline
: AF_ISO 7 ; inline
: AF_OSI AF_ISO ; inline
: AF_ECMA 8 ; inline
: AF_DATAKIT 9 ; inline
: AF_CCITT 10 ; inline
: AF_SNA 11 ; inline
: AF_DECnet 12 ; inline
: AF_DLI 13 ; inline
: AF_LAT 14 ; inline
: AF_HYLINK 15 ; inline
: AF_APPLETALK 16 ; inline
: AF_NETBIOS 17 ; inline
: AF_MAX 18 ; inline
: AF_INET6 23 ; inline
: AF_IRDA 26 ; inline
: AF_BTM 32 ; inline
: PF_UNSPEC 0 ; inline
: PF_LOCAL 1 ; inline
: PF_INET 2 ; inline
: PF_INET6 23 ; inline
: AI_PASSIVE 1 ; inline
: AI_CANONNAME 2 ; inline
: AI_NUMERICHOST 4 ; inline
2008-06-09 17:27:52 -04:00
: AI_MASK ( -- n ) { AI_PASSIVE AI_CANONNAME AI_NUMERICHOST } flags ;
2007-09-20 18:09:08 -04:00
: NI_NUMERICHOST 1 ;
: NI_NUMERICSERV 2 ;
: IPPROTO_TCP 6 ; inline
: IPPROTO_UDP 17 ; inline
: IPPROTO_RM 113 ; inline
: WSA_FLAG_OVERLAPPED 1 ; inline
: WSA_WAIT_EVENT_0 WAIT_OBJECT_0 ; inline
: WSA_MAXIMUM_WAIT_EVENTS MAXIMUM_WAIT_OBJECTS ; inline
: WSA_INVALID_EVENT f ; inline
: WSA_WAIT_FAILED -1 ; inline
: WSA_WAIT_IO_COMPLETION WAIT_IO_COMPLETION ; inline
: WSA_WAIT_TIMEOUT WAIT_TIMEOUT ; inline
: WSA_INFINITE INFINITE ; inline
: WSA_IO_PENDING ERROR_IO_PENDING ; inline
: INADDR_ANY 0 ; inline
: INVALID_SOCKET -1 <alien> ; inline
: SOCKET_ERROR -1 ; inline
: SD_RECV 0 ; inline
: SD_SEND 1 ; inline
: SD_BOTH 2 ; inline
: SOL_SOCKET HEX: ffff ; inline
! TYPEDEF: uint in_addr_t
! C-STRUCT: in_addr
! { "in_addr_t" "s_addr" } ;
C-STRUCT: sockaddr-in
{ "short" "family" }
{ "ushort" "port" }
{ "uint" "addr" }
{ { "char" 8 } "pad" } ;
C-STRUCT: sockaddr-in6
{ "uchar" "family" }
{ "ushort" "port" }
{ "uint" "flowinfo" }
{ { "uchar" 16 } "addr" }
{ "uint" "scopeid" } ;
C-STRUCT: hostent
{ "char*" "name" }
{ "void*" "aliases" }
{ "short" "addrtype" }
{ "short" "length" }
{ "void*" "addr-list" } ;
C-STRUCT: addrinfo
{ "int" "flags" }
{ "int" "family" }
{ "int" "socktype" }
{ "int" "protocol" }
{ "size_t" "addrlen" }
{ "char*" "canonname" }
{ "sockaddr*" "addr" }
{ "addrinfo*" "next" } ;
2008-10-06 19:28:10 -04:00
C-STRUCT: timeval
{ "long" "sec" }
{ "long" "usec" } ;
2008-06-09 17:27:52 -04:00
: hostent-addr ( hostent -- addr ) hostent-addr-list *void* ; ! *uint ;
2007-09-20 18:09:08 -04:00
LIBRARY: winsock
FUNCTION: int setsockopt ( SOCKET s, int level, int optname, char* optval, int optlen ) ;
FUNCTION: ushort htons ( ushort n ) ;
FUNCTION: ushort ntohs ( ushort n ) ;
FUNCTION: int bind ( void* socket, sockaddr_in* sockaddr, int len ) ;
FUNCTION: int listen ( void* socket, int backlog ) ;
FUNCTION: char* inet_ntoa ( int in-addr ) ;
FUNCTION: int getaddrinfo ( char* nodename,
char* servername,
addrinfo* hints,
addrinfo** res ) ;
FUNCTION: void freeaddrinfo ( addrinfo* ai ) ;
FUNCTION: hostent* gethostbyname ( char* name ) ;
FUNCTION: int gethostname ( char* name, int len ) ;
FUNCTION: int connect ( void* socket, sockaddr_in* sockaddr, int addrlen ) ;
FUNCTION: int select ( int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, timeval* timeout ) ;
FUNCTION: int closesocket ( SOCKET s ) ;
FUNCTION: int shutdown ( SOCKET s, int how ) ;
2007-11-06 20:44:45 -05:00
FUNCTION: int send ( SOCKET s, char* buf, int len, int flags ) ;
FUNCTION: int recv ( SOCKET s, char* buf, int len, int flags ) ;
2007-09-20 18:09:08 -04:00
FUNCTION: int getsockname ( SOCKET s, sockaddr_in* address, int* addrlen ) ;
FUNCTION: int getpeername ( SOCKET s, sockaddr_in* address, int* addrlen ) ;
2007-09-20 18:09:08 -04:00
TYPEDEF: uint SERVICETYPE
TYPEDEF: OVERLAPPED WSAOVERLAPPED
TYPEDEF: WSAOVERLAPPED* LPWSAOVERLAPPED
TYPEDEF: uint GROUP
TYPEDEF: void* LPCONDITIONPROC
TYPEDEF: HANDLE WSAEVENT
TYPEDEF: LPHANDLE LPWSAEVENT
TYPEDEF: sockaddr* LPSOCKADDR
C-STRUCT: FLOWSPEC
{ "uint" "TokenRate" }
{ "uint" "TokenBucketSize" }
{ "uint" "PeakBandwidth" }
{ "uint" "Latency" }
{ "uint" "DelayVariation" }
{ "SERVICETYPE" "ServiceType" }
{ "uint" "MaxSduSize" }
{ "uint" "MinimumPolicedSize" } ;
TYPEDEF: FLOWSPEC* PFLOWSPEC
TYPEDEF: FLOWSPEC* LPFLOWSPEC
C-STRUCT: WSABUF
{ "ulong" "len" }
{ "void*" "buf" } ;
TYPEDEF: WSABUF* LPWSABUF
C-STRUCT: QOS
{ "FLOWSPEC" "SendingFlowspec" }
{ "FLOWSPEC" "ReceivingFlowspec" }
{ "WSABUF" "ProviderSpecific" } ;
TYPEDEF: QOS* LPQOS
: MAX_PROTOCOL_CHAIN 7 ; inline
C-STRUCT: WSAPROTOCOLCHAIN
{ "int" "ChainLen" }
! { { "DWORD" MAX_PROTOCOL_CHAIN } "ChainEntries" } ;
{ { "DWORD" 7 } "ChainEntries" } ;
TYPEDEF: WSAPROTOCOLCHAIN* LPWSAPROTOCOLCHAIN
: WSAPROTOCOL_LEN 255 ; inline
C-STRUCT: WSAPROTOCOL_INFOW
{ "DWORD" "dwServiceFlags1" }
{ "DWORD" "dwServiceFlags2" }
{ "DWORD" "dwServiceFlags3" }
{ "DWORD" "dwServiceFlags4" }
{ "DWORD" "dwProviderFlags" }
{ "GUID" "ProviderId" }
{ "DWORD" "dwCatalogEntryId" }
{ "WSAPROTOCOLCHAIN" "ProtocolChain" }
{ "int" "iVersion" }
{ "int" "iAddressFamily" }
{ "int" "iMaxSockAddr" }
{ "int" "iMinSockAddr" }
{ "int" "iSocketType" }
{ "int" "iProtocol" }
{ "int" "iProtocolMaxOffset" }
{ "int" "iNetworkByteOrder" }
{ "int" "iSecurityScheme" }
{ "DWORD" "dwMessageSize" }
{ "DWORD" "dwProviderReserved" }
{ { "WCHAR" 256 } "szProtocol" } ;
! { { "WCHAR" 256 } "szProtocol"[WSAPROTOCOL_LEN+1] } ;
TYPEDEF: WSAPROTOCOL_INFOW* PWSAPROTOCOL_INFOW
TYPEDEF: WSAPROTOCOL_INFOW* LPWSAPROTOCOL_INFOW
TYPEDEF: WSAPROTOCOL_INFOW WSAPROTOCOL_INFO
TYPEDEF: WSAPROTOCOL_INFOW* PWSAPROTOCOL_INFO
TYPEDEF: WSAPROTOCOL_INFOW* LPWSAPROTOCOL_INFO
C-STRUCT: WSANAMESPACE_INFOW
{ "GUID" "NSProviderId" }
{ "DWORD" "dwNameSpace" }
{ "BOOL" "fActive" }
{ "DWORD" "dwVersion" }
{ "LPWSTR" "lpszIdentifier" } ;
TYPEDEF: WSANAMESPACE_INFOW* PWSANAMESPACE_INFOW
TYPEDEF: WSANAMESPACE_INFOW* LPWSANAMESPACE_INFOW
TYPEDEF: WSANAMESPACE_INFOW WSANAMESPACE_INFO
TYPEDEF: WSANAMESPACE_INFO* PWSANAMESPACE_INFO
TYPEDEF: WSANAMESPACE_INFO* LPWSANAMESPACE_INFO
: FD_MAX_EVENTS 10 ;
C-STRUCT: WSANETWORKEVENTS
{ "long" "lNetworkEvents" }
! { { "int" "FD_MAX_EVENTS" } "iErrorCode" } ;
{ { "int" 10 } "iErrorCode" } ;
TYPEDEF: WSANETWORKEVENTS* PWSANETWORKEVENTS
TYPEDEF: WSANETWORKEVENTS* LPWSANETWORKEVENTS
! C-STRUCT: WSAOVERLAPPED
! { "DWORD" "Internal" }
! { "DWORD" "InternalHigh" }
! { "DWORD" "Offset" }
! { "DWORD" "OffsetHigh" }
! { "WSAEVENT" "hEvent" }
! { "DWORD" "bytesTransferred" } ;
! TYPEDEF: WSAOVERLAPPED* LPWSAOVERLAPPED
FUNCTION: SOCKET WSAAccept ( SOCKET s,
sockaddr* addr,
LPINT addrlen,
LPCONDITIONPROC lpfnCondition,
DWORD dwCallbackData ) ;
! FUNCTION: INT WSAAddressToString ( LPSOCKADDR lpsaAddress, DWORD dwAddressLength, LPWSAPROTOCOL_INFO lpProtocolInfo, LPTSTR lpszAddressString, LPDWORD lpdwAddressStringLength ) ;
FUNCTION: int WSACleanup ( ) ;
FUNCTION: BOOL WSACloseEvent ( WSAEVENT hEvent ) ;
FUNCTION: int WSAConnect ( SOCKET s,
sockaddr* name,
int namelen,
LPWSABUF lpCallerData,
LPWSABUF lpCalleeData,
LPQOS lpSQOS,
LPQOS lpGQOS ) ;
FUNCTION: WSAEVENT WSACreateEvent ( ) ;
! FUNCTION: INT WSAEnumNameSpaceProviders ( LPDWORD lpdwBufferLength, LPWSANAMESPACE_INFO lpnspBuffer ) ;
FUNCTION: int WSAEnumNetworkEvents ( SOCKET s,
WSAEVENT hEventObject,
LPWSANETWORKEVENTS lpNetworkEvents ) ;
! FUNCTION: int WSAEnumProtocols ( LPINT lpiProtocols, LPWSAPROTOCOL_INFO lpProtocolBuffer, LPDWORD lpwdBufferLength ) ;
FUNCTION: int WSAEventSelect ( SOCKET s,
WSAEVENT hEventObject,
long lNetworkEvents ) ;
FUNCTION: int WSAGetLastError ( ) ;
FUNCTION: BOOL WSAGetOverlappedResult ( SOCKET s,
LPWSAOVERLAPPED lpOverlapped,
LPDWORD lpcbTransfer,
BOOL fWait,
LPDWORD lpdwFlags ) ;
FUNCTION: int WSAIoctl ( SOCKET s,
DWORD dwIoControlCode,
LPVOID lpvInBuffer,
DWORD cbInBuffer,
LPVOID lpvOutBuffer,
DWORD cbOutBuffer,
LPDWORD lpcbBytesReturned,
void* lpOverlapped,
void* lpCompletionRoutine ) ;
TYPEDEF: void* LPWSAOVERLAPPED_COMPLETION_ROUTINE
FUNCTION: int WSARecv ( SOCKET s,
LPWSABUF lpBuffers,
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesRecvd,
LPDWORD lpFlags,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine ) ;
FUNCTION: int WSARecvFrom ( SOCKET s,
LPWSABUF lpBuffers,
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesRecvd,
LPDWORD lpFlags,
sockaddr* lpFrom,
LPINT lpFromlen,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine ) ;
FUNCTION: BOOL WSAResetEvent ( WSAEVENT hEvent ) ;
FUNCTION: int WSASend ( SOCKET s,
LPWSABUF lpBuffers,
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesSent,
LPDWORD lpFlags,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine ) ;
FUNCTION: int WSASendTo ( SOCKET s,
LPWSABUF lpBuffers,
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesSent,
DWORD dwFlags,
sockaddr* lpTo,
int iToLen,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine ) ;
FUNCTION: int WSAStartup ( short version, void* out-data ) ;
FUNCTION: SOCKET WSASocketW ( int af,
int type,
int protocol,
LPWSAPROTOCOL_INFOW lpProtocolInfo,
GROUP g,
DWORD flags ) ;
2008-06-09 17:27:52 -04:00
ALIAS: WSASocket WSASocketW
2007-09-20 18:09:08 -04:00
FUNCTION: DWORD WSAWaitForMultipleEvents ( DWORD cEvents,
WSAEVENT* lphEvents,
BOOL fWaitAll,
DWORD dwTimeout,
BOOL fAlertable ) ;
LIBRARY: mswsock
! Not in Windows CE
FUNCTION: int AcceptEx ( void* listen, void* accept, void* out-buf, int recv-len, int addr-len, int remote-len, void* out-len, void* overlapped ) ;
FUNCTION: void GetAcceptExSockaddrs ( void* a, int b, int c, int d, void* e, void* f, void* g, void* h ) ;
: SIO_GET_EXTENSION_FUNCTION_POINTER -939524090 ; inline
2008-06-09 17:27:52 -04:00
: WSAID_CONNECTEX ( -- GUID )
2007-09-20 18:09:08 -04:00
"GUID" <c-object>
HEX: 25a207b9 over set-GUID-Data1
HEX: ddf3 over set-GUID-Data2
HEX: 4660 over set-GUID-Data3
B{
HEX: 8e HEX: e9 HEX: 76 HEX: e5
HEX: 8c HEX: 74 HEX: 06 HEX: 3e
} over set-GUID-Data4 ;
: winsock-expected-error? ( n -- ? )
ERROR_IO_PENDING ERROR_SUCCESS WSA_IO_PENDING 3array member? ;
: (winsock-error-string) ( n -- str )
! #! WSAStartup returns the error code 'n' directly
dup winsock-expected-error?
2008-04-20 06:15:46 -04:00
[ drop f ] [ error_message utf16n alien>string ] if ;
2007-09-20 18:09:08 -04:00
: winsock-error-string ( -- string/f )
WSAGetLastError (winsock-error-string) ;
2007-11-06 20:44:45 -05:00
: winsock-error ( -- )
winsock-error-string [ throw ] when* ;
2007-09-20 18:09:08 -04:00
: winsock-error=0/f ( n/f -- )
{ 0 f } member? [
winsock-error-string throw
] when ;
: winsock-error!=0/f ( n/f -- )
2007-11-11 16:09:24 -05:00
{ 0 f } member? [
winsock-error-string throw
] unless ;
: winsock-return-check ( n/f -- )
2007-09-20 18:09:08 -04:00
dup { 0 f } member? [
drop
] [
(winsock-error-string) throw
] if ;
: socket-error* ( n -- )
SOCKET_ERROR = [
WSAGetLastError
dup WSA_IO_PENDING = [
drop
] [
(winsock-error-string) throw
] if
] when ;
: socket-error ( n -- )
2007-11-06 20:44:45 -05:00
SOCKET_ERROR = [ winsock-error ] when ;
2007-09-20 18:09:08 -04:00
: init-winsock ( -- )
2007-11-11 16:09:24 -05:00
HEX: 0202 <wsadata> WSAStartup winsock-return-check ;