: pending-error ( reader -- ) port-error throw ;
-: postpone-error ( reader -- )
- err_no strerror swap set-port-error ;
+: EAGAIN 35 ;
+: EINTR 4 ;
+
+: postpone-error ( port -- )
+ err_no dup EAGAIN = over EINTR = or
+ [ 2drop ] [ strerror swap set-port-error ] ifte ;
! Associates a port with a list of continuations waiting on the
! port to finish I/O
port-cutoff dup 0 = not swap millis < and ;
: handle-fd? ( fdset task -- ? )
- dup io-task-port timeout?
- [
+ dup io-task-port timeout? [
2drop t
] [
io-task-fd swap 2dup bit-nth
>r f -rot set-bit-nth r>
] ifte ;
+: debug-out 14 getenv fwrite ;
+
: handle-fdset ( fdset tasks -- )
[
cdr tuck handle-fd? [ handle-fd ] [ drop ] ifte
drop
] ifte t swap set-reader-ready? ;
+: (refill) ( port -- n )
+ >port< tuck dup buffer-end swap buffer-capacity read ;
+
: refill ( port -- )
dup buffer-length 0 = [
- >port<
- tuck dup buffer-end swap buffer-capacity read
+ (refill)
dup 0 >= [ swap n>buffer ] [ drop postpone-error ] ifte
] [
drop
dup 0 >= [ drop 1 listen ] [ ( fd n - n) nip ] ifte
] with-socket-fd ;
+IN: streams
+
+C: client-stream ( host port fd -- stream )
+ [ >r <socket-stream> r> set-delegate ] keep
+ [ set-client-stream-port ] keep
+ [ set-client-stream-host ] keep ;
+
+: <client> ( host port -- stream )
+ #! Connect to a port number on a TCP/IP host.
+ client-socket <socket-stream> ;
+
+TUPLE: server client ;
+
+C: server ( port -- server )
+ #! Starts listening for TCP connections on localhost:port.
+ [ >r server-socket 0 <port> r> set-delegate ] keep ;
+
+IN: io-internals
+USE: unix-internals
+
TUPLE: accept-task ;
C: accept-task ( port -- task )
[ >r <io-task> r> set-delegate ] keep ;
-M: accept-task do-io-task ( task -- ? ) drop t ;
+: init-socket ( fd -- ) SOL_SOCKET SO_OOBINLINE sockopt ;
+
+: do-accept ( port sockaddr fd -- )
+ [
+ init-socket
+ dup sockaddr-in-addr inet-ntoa
+ swap sockaddr-in-port ntohs
+ ] keep <client-stream> swap set-server-client ;
+
+M: accept-task do-io-task ( task -- ? )
+ io-task-port <sockaddr-in>
+ over port-handle over "sockaddr-in" c-size <int> accept
+ dup 0 >= [ do-accept t ] [ 2drop postpone-error f ] ifte ;
M: accept-task task-container drop read-tasks get ;
HEX: ff bitand unparse %
] make-string ;
-: do-accept ( fd -- fd host port )
- <sockaddr-in>
- [ "sockaddr-in" c-size <int> accept dup io-error ] keep
- dup sockaddr-in-addr inet-ntoa
- swap sockaddr-in-port ntohs ;
-
: <socket-stream> ( fd -- stream )
dup f <fd-stream> ;
IN: streams
-C: client-stream ( fd host port -- stream )
- [ set-client-stream-port ] keep
- [ set-client-stream-host ] keep
- [
- >r
- dup SOL_SOCKET SO_OOBINLINE sockopt
- <socket-stream> r> set-delegate
- ] keep ;
-
-: <client> ( host port -- stream )
- #! Connect to a port number on a TCP/IP host.
- client-socket <socket-stream> ;
-
-: <server> ( port -- server )
- #! Starts listening for TCP connections on localhost:port.
- server-socket 0 <port> ;
-
: accept ( server -- client )
#! Wait for a client connection.
- dup wait-to-accept port-handle do-accept <client-stream> ;
+ dup wait-to-accept server-client ;