factor/extra/io/windows/nt/sockets/sockets.factor

255 lines
8.3 KiB
Factor
Raw Normal View History

2008-02-01 00:00:08 -05:00
USING: alien alien.accessors alien.c-types byte-arrays
2008-02-09 22:34:42 -05:00
continuations destructors io.nonblocking io.timeouts io.sockets
io.sockets.impl io namespaces io.streams.duplex io.windows
2008-02-01 00:00:08 -05:00
io.windows.nt.backend windows.winsock kernel libc math sequences
2008-04-02 21:09:56 -04:00
threads classes.tuple.lib system ;
2007-09-20 18:09:08 -04:00
IN: io.windows.nt.sockets
: malloc-int ( object -- object )
"int" heap-size malloc tuck 0 set-alien-signed-4 ; inline
2008-04-02 21:09:56 -04:00
M: winnt WSASocket-flags ( -- DWORD )
2007-09-20 18:09:08 -04:00
WSA_FLAG_OVERLAPPED ;
: get-ConnectEx-ptr ( socket -- void* )
SIO_GET_EXTENSION_FUNCTION_POINTER
WSAID_CONNECTEX
"GUID" heap-size
"void*" <c-object>
[
"void*" heap-size
"DWORD" <c-object>
f
f
WSAIoctl SOCKET_ERROR = [
winsock-error-string throw
] when
] keep *void* ;
TUPLE: ConnectEx-args port
s* name* namelen* lpSendBuffer* dwSendDataLength*
lpdwBytesSent* lpOverlapped* ptr* ;
: init-connect ( sockaddr size ConnectEx -- )
2007-09-20 18:09:08 -04:00
[ set-ConnectEx-args-namelen* ] keep
[ set-ConnectEx-args-name* ] keep
f over set-ConnectEx-args-lpSendBuffer*
0 over set-ConnectEx-args-dwSendDataLength*
f over set-ConnectEx-args-lpdwBytesSent*
(make-overlapped) swap set-ConnectEx-args-lpOverlapped* ;
: (ConnectEx) ( ConnectEx -- )
\ ConnectEx-args >tuple*<
"int"
{ "SOCKET" "sockaddr_in*" "int" "PVOID" "DWORD" "LPDWORD" "void*" }
"stdcall" alien-indirect drop
winsock-error-string [ throw ] when* ;
: connect-continuation ( ConnectEx port -- )
>r ConnectEx-args-lpOverlapped* r>
2dup save-callback
2008-01-28 00:59:36 -05:00
get-overlapped-result drop ;
2007-09-20 18:09:08 -04:00
2008-04-02 21:09:56 -04:00
M: winnt (client) ( addrspec -- client-in client-out )
2007-09-20 18:09:08 -04:00
[
\ ConnectEx-args construct-empty
over make-sockaddr/size pick init-connect
2007-09-20 18:09:08 -04:00
over tcp-socket over set-ConnectEx-args-s*
dup ConnectEx-args-s* add-completion
dup ConnectEx-args-s* get-ConnectEx-ptr over set-ConnectEx-args-ptr*
dup ConnectEx-args-s* INADDR_ANY roll bind-socket
dup (ConnectEx)
dup ConnectEx-args-s* <win32-socket> dup <reader&writer>
>r [ connect-continuation ] keep [ pending-error ] keep r>
2007-09-20 18:09:08 -04:00
] with-destructors ;
TUPLE: AcceptEx-args port
sListenSocket* sAcceptSocket* lpOutputBuffer* dwReceiveDataLength*
dwLocalAddressLength* dwRemoteAddressLength* lpdwBytesReceived* lpOverlapped* ;
: init-accept-buffer ( server-port AcceptEx -- )
>r server-port-addr sockaddr-type heap-size 16 +
dup dup 2 * malloc dup free-always r>
2007-09-20 18:09:08 -04:00
[ set-AcceptEx-args-lpOutputBuffer* ] keep
[ set-AcceptEx-args-dwLocalAddressLength* ] keep
set-AcceptEx-args-dwRemoteAddressLength* ;
: init-accept ( server-port AcceptEx -- )
[ init-accept-buffer ] 2keep
[ set-AcceptEx-args-port ] 2keep
>r port-handle win32-file-handle r> [ set-AcceptEx-args-sListenSocket* ] keep
dup AcceptEx-args-port server-port-addr tcp-socket
over set-AcceptEx-args-sAcceptSocket*
0 over set-AcceptEx-args-dwReceiveDataLength*
f over set-AcceptEx-args-lpdwBytesReceived*
2008-01-28 00:59:36 -05:00
(make-overlapped) swap set-AcceptEx-args-lpOverlapped* ;
2007-09-20 18:09:08 -04:00
: ((accept)) ( AcceptEx -- )
2007-09-20 18:09:08 -04:00
\ AcceptEx-args >tuple*<
AcceptEx drop
winsock-error-string [ throw ] when* ;
: make-accept-continuation ( AcceptEx -- )
2008-01-28 00:59:36 -05:00
dup AcceptEx-args-lpOverlapped*
swap AcceptEx-args-port save-callback ;
2007-09-20 18:09:08 -04:00
: check-accept-error ( AcceptEx -- )
2008-01-28 00:59:36 -05:00
dup AcceptEx-args-lpOverlapped*
swap AcceptEx-args-port get-overlapped-result drop ;
2007-09-20 18:09:08 -04:00
: extract-remote-host ( AcceptEx -- addrspec )
[
[ AcceptEx-args-lpOutputBuffer* ] keep
[ AcceptEx-args-dwReceiveDataLength* ] keep
[ AcceptEx-args-dwLocalAddressLength* ] keep
AcceptEx-args-dwRemoteAddressLength*
f <void*>
0 <int>
f <void*> [
0 <int> GetAcceptExSockaddrs
] keep *void*
] keep AcceptEx-args-port server-port-addr parse-sockaddr ;
: accept-continuation ( AcceptEx -- addrspec client )
2007-09-20 18:09:08 -04:00
[ make-accept-continuation ] keep
[ check-accept-error ] keep
[ extract-remote-host ] keep
! addrspec AcceptEx
[ AcceptEx-args-sAcceptSocket* add-completion ] keep
AcceptEx-args-sAcceptSocket* <win32-socket> ;
2007-09-20 18:09:08 -04:00
2008-04-02 21:09:56 -04:00
M: winnt (accept) ( server -- addrspec handle )
2007-09-20 18:09:08 -04:00
[
2008-01-31 13:27:37 -05:00
[
dup check-server-port
\ AcceptEx-args construct-empty
[ init-accept ] keep
[ ((accept)) ] keep
2008-01-31 13:27:37 -05:00
[ accept-continuation ] keep
AcceptEx-args-port pending-error
2008-02-09 22:34:42 -05:00
] with-timeout
2007-09-20 18:09:08 -04:00
] with-destructors ;
2008-04-02 21:09:56 -04:00
M: winnt (server) ( addrspec -- handle )
2007-09-20 18:09:08 -04:00
[
SOCK_STREAM server-fd dup listen-on-socket
dup add-completion
<win32-socket>
2007-09-20 18:09:08 -04:00
] with-destructors ;
2008-04-02 21:09:56 -04:00
M: winnt <datagram> ( addrspec -- datagram )
2007-09-20 18:09:08 -04:00
[
[
SOCK_DGRAM server-fd
dup add-completion
2008-01-21 15:33:43 -05:00
<win32-socket>
2007-09-20 18:09:08 -04:00
] keep <datagram-port>
] with-destructors ;
TUPLE: WSARecvFrom-args port
s* lpBuffers* dwBufferCount* lpNumberOfBytesRecvd*
lpFlags* lpFrom* lpFromLen* lpOverlapped* lpCompletionRoutine* ;
2008-01-28 02:06:27 -05:00
: make-receive-buffer ( -- WSABUF )
"WSABUF" malloc-object dup free-always
default-buffer-size get over set-WSABUF-len
default-buffer-size get malloc dup free-always over set-WSABUF-buf ;
2007-09-20 18:09:08 -04:00
: init-WSARecvFrom ( datagram WSARecvFrom -- )
[ set-WSARecvFrom-args-port ] 2keep
[
>r delegate port-handle delegate win32-file-handle r>
set-WSARecvFrom-args-s*
] 2keep [
>r datagram-port-addr sockaddr-type heap-size r>
2dup >r malloc dup free-always r> set-WSARecvFrom-args-lpFrom*
>r malloc-int dup free-always r> set-WSARecvFrom-args-lpFromLen*
2007-09-20 18:09:08 -04:00
] keep
2008-01-28 02:06:27 -05:00
make-receive-buffer over set-WSARecvFrom-args-lpBuffers*
2007-09-20 18:09:08 -04:00
1 over set-WSARecvFrom-args-dwBufferCount*
0 malloc-int dup free-always over set-WSARecvFrom-args-lpFlags*
0 malloc-int dup free-always over set-WSARecvFrom-args-lpNumberOfBytesRecvd*
2008-01-28 00:59:36 -05:00
(make-overlapped) swap set-WSARecvFrom-args-lpOverlapped* ;
2007-09-20 18:09:08 -04:00
2008-01-28 00:59:36 -05:00
: WSARecvFrom-continuation ( WSARecvFrom -- n )
dup WSARecvFrom-args-lpOverlapped*
swap WSARecvFrom-args-port [ save-callback ] 2keep
get-overlapped-result ;
2007-09-20 18:09:08 -04:00
: call-WSARecvFrom ( WSARecvFrom -- )
\ WSARecvFrom-args >tuple*<
WSARecvFrom
socket-error* ;
: parse-WSARecvFrom ( n WSARecvFrom -- packet addrspec )
[
WSARecvFrom-args-lpBuffers* WSABUF-buf
swap memory>byte-array
2007-09-20 18:09:08 -04:00
] keep
[ WSARecvFrom-args-lpFrom* ] keep
WSARecvFrom-args-port datagram-port-addr parse-sockaddr ;
2008-04-02 21:09:56 -04:00
M: winnt receive ( datagram -- packet addrspec )
2007-09-20 18:09:08 -04:00
[
dup check-datagram-port
\ WSARecvFrom-args construct-empty
[ init-WSARecvFrom ] keep
[ call-WSARecvFrom ] keep
[ WSARecvFrom-continuation ] keep
[ WSARecvFrom-args-port pending-error ] keep
parse-WSARecvFrom
] with-destructors ;
TUPLE: WSASendTo-args port
s* lpBuffers* dwBufferCount* lpNumberOfBytesSent*
dwFlags* lpTo* iToLen* lpOverlapped* lpCompletionRoutine* ;
2008-01-28 02:06:27 -05:00
: make-send-buffer ( packet -- WSABUF )
"WSABUF" malloc-object dup free-always
over malloc-byte-array dup free-always over set-WSABUF-buf
swap length over set-WSABUF-len ;
2007-09-20 18:09:08 -04:00
: init-WSASendTo ( packet addrspec datagram WSASendTo -- )
[ set-WSASendTo-args-port ] 2keep
[
2008-01-28 02:06:27 -05:00
>r port-handle win32-file-handle r> set-WSASendTo-args-s*
] keep
[
>r make-sockaddr/size >r
malloc-byte-array dup free-always
r> r>
2007-09-20 18:09:08 -04:00
[ set-WSASendTo-args-iToLen* ] keep
set-WSASendTo-args-lpTo*
2008-01-28 02:06:27 -05:00
] keep
[
>r make-send-buffer r> set-WSASendTo-args-lpBuffers*
2007-09-20 18:09:08 -04:00
] keep
1 over set-WSASendTo-args-dwBufferCount*
0 over set-WSASendTo-args-dwFlags*
2008-01-28 02:06:27 -05:00
0 <uint> over set-WSASendTo-args-lpNumberOfBytesSent*
2008-01-28 00:59:36 -05:00
(make-overlapped) swap set-WSASendTo-args-lpOverlapped* ;
2007-09-20 18:09:08 -04:00
: WSASendTo-continuation ( WSASendTo -- )
2008-01-28 00:59:36 -05:00
dup WSASendTo-args-lpOverlapped*
swap WSASendTo-args-port
[ save-callback ] 2keep
get-overlapped-result drop ;
2007-09-20 18:09:08 -04:00
: call-WSASendTo ( WSASendTo -- )
\ WSASendTo-args >tuple*<
WSASendTo socket-error* ;
2007-11-07 14:01:45 -05:00
USE: io.sockets
2008-04-02 21:09:56 -04:00
M: winnt send ( packet addrspec datagram -- )
2007-09-20 18:09:08 -04:00
[
3dup check-datagram-send
\ WSASendTo-args construct-empty
[ init-WSASendTo ] keep
[ call-WSASendTo ] keep
[ WSASendTo-continuation ] keep
WSASendTo-args-port pending-error
] with-destructors ;