| 
									
										
										
										
											2013-10-21 16:58:33 -04:00
										 |  |  | ! Copyright (C) 2004, 2008 Slava Pestov, Ivan Tikhonov. | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | ! See http://factorcode.org/license.txt for BSD license. | 
					
						
							| 
									
										
										
										
											2010-09-23 14:19:15 -04:00
										 |  |  | USING: accessors alien alien.c-types alien.data alien.strings | 
					
						
							| 
									
										
										
										
											2015-07-16 16:14:17 -04:00
										 |  |  | arrays byte-arrays classes.struct combinators destructors | 
					
						
							|  |  |  | io.backend.unix io.encodings.ascii io.encodings.utf8 io.files | 
					
						
							|  |  |  | io.pathnames io.sockets.private kernel libc locals math | 
					
						
							|  |  |  | namespaces sequences system unix unix.ffi vocabs ;
 | 
					
						
							| 
									
										
										
										
											2008-04-20 06:15:46 -04:00
										 |  |  | EXCLUDE: io.sockets => accept ;
 | 
					
						
							| 
									
										
										
										
											2008-12-14 21:03:00 -05:00
										 |  |  | IN: io.sockets.unix | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-21 12:15:33 -04:00
										 |  |  | : socket-fd ( domain type protocol -- fd )
 | 
					
						
							|  |  |  |     socket dup io-error <fd> init-fd |dispose ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-13 16:34:29 -04:00
										 |  |  | : get-socket-option ( fd level opt -- val )
 | 
					
						
							|  |  |  |     [ handle-fd ] 2dip -1 int <ref> [ | 
					
						
							|  |  |  |         dup byte-length int <ref> getsockopt io-error | 
					
						
							|  |  |  |     ] keep int deref ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-14 04:55:33 -04:00
										 |  |  | : set-socket-option ( fd level opt -- )
 | 
					
						
							| 
									
										
										
										
											2010-10-20 18:42:53 -04:00
										 |  |  |     [ handle-fd ] 2dip 1 int <ref> dup byte-length setsockopt io-error ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-20 22:46:14 -05:00
										 |  |  | M: unix addrinfo-error-string | 
					
						
							| 
									
										
										
										
											2014-03-16 07:56:48 -04:00
										 |  |  |     gai_strerror ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-20 22:46:14 -05:00
										 |  |  | M: unix sockaddr-of-family | 
					
						
							| 
									
										
										
										
											2009-09-04 06:02:33 -04:00
										 |  |  |     { | 
					
						
							|  |  |  |         { AF_INET [ sockaddr-in memory>struct ] } | 
					
						
							|  |  |  |         { AF_INET6 [ sockaddr-in6 memory>struct ] } | 
					
						
							|  |  |  |         { AF_UNIX [ sockaddr-un memory>struct ] } | 
					
						
							|  |  |  |         [ 2drop f ] | 
					
						
							|  |  |  |     } case ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-20 22:46:14 -05:00
										 |  |  | M: unix addrspec-of-family | 
					
						
							| 
									
										
										
										
											2009-09-04 06:02:33 -04:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-09-04 17:42:05 -04:00
										 |  |  |         { AF_INET [ T{ ipv4 } ] } | 
					
						
							|  |  |  |         { AF_INET6 [ T{ ipv6 } ] } | 
					
						
							| 
									
										
										
										
											2009-09-04 06:02:33 -04:00
										 |  |  |         { AF_UNIX [ T{ local } ] } | 
					
						
							|  |  |  |         [ drop f ] | 
					
						
							|  |  |  |     } case ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | ! Client sockets - TCP and Unix domain | 
					
						
							| 
									
										
										
										
											2014-11-20 22:46:14 -05:00
										 |  |  | M: object (get-local-address) | 
					
						
							| 
									
										
										
										
											2010-10-20 18:42:53 -04:00
										 |  |  |     [ handle-fd ] dip empty-sockaddr/size int <ref> | 
					
						
							| 
									
										
										
										
											2008-05-14 04:55:33 -04:00
										 |  |  |     [ getsockname io-error ] 2keep drop ;
 | 
					
						
							| 
									
										
										
										
											2008-05-12 19:53:22 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-20 22:46:14 -05:00
										 |  |  | M: object (get-remote-address) | 
					
						
							| 
									
										
										
										
											2010-10-20 18:42:53 -04:00
										 |  |  |     [ handle-fd ] dip empty-sockaddr/size int <ref> | 
					
						
							| 
									
										
										
										
											2008-05-15 20:05:07 -04:00
										 |  |  |     [ getpeername io-error ] 2keep drop ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-14 20:03:07 -04:00
										 |  |  | : init-client-socket ( fd -- )
 | 
					
						
							|  |  |  |     SOL_SOCKET SO_OOBINLINE set-socket-option ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : wait-to-connect ( port -- )
 | 
					
						
							| 
									
										
										
										
											2016-03-14 11:42:54 -04:00
										 |  |  |     dup +output+ wait-for-port | 
					
						
							|  |  |  |     dup handle>> SOL_SOCKET SO_ERROR get-socket-option | 
					
						
							|  |  |  |     [ drop ] [ (throw-errno) ] if-zero ; inline
 | 
					
						
							| 
									
										
										
										
											2014-11-20 22:46:14 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | M: object establish-connection | 
					
						
							|  |  |  |     2dup
 | 
					
						
							|  |  |  |     [ handle>> handle-fd ] [ make-sockaddr/size ] bi*
 | 
					
						
							|  |  |  |     connect 0 = [ 2drop ] [ | 
					
						
							|  |  |  |         errno { | 
					
						
							|  |  |  |             { EINTR [ establish-connection ] } | 
					
						
							| 
									
										
										
										
											2016-03-14 11:42:54 -04:00
										 |  |  |             { EINPROGRESS [ drop wait-to-connect ] } | 
					
						
							| 
									
										
										
										
											2014-11-21 13:19:12 -05:00
										 |  |  |             [ (throw-errno) ] | 
					
						
							| 
									
										
										
										
											2014-11-20 22:46:14 -05:00
										 |  |  |         } case
 | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							| 
									
										
										
										
											2008-05-12 19:53:22 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-27 11:31:02 -04:00
										 |  |  | : ?bind-client ( socket -- )
 | 
					
						
							| 
									
										
										
										
											2010-01-19 17:53:15 -05:00
										 |  |  |     bind-local-address get [ | 
					
						
							|  |  |  |         [ fd>> ] dip make-sockaddr/size | 
					
						
							| 
									
										
										
										
											2010-01-23 10:07:35 -05:00
										 |  |  |         [ bind ] unix-system-call drop
 | 
					
						
							| 
									
										
										
										
											2010-01-19 17:53:15 -05:00
										 |  |  |     ] [ | 
					
						
							|  |  |  |         drop
 | 
					
						
							|  |  |  |     ] if* ; inline
 | 
					
						
							| 
									
										
										
										
											2009-09-27 11:31:02 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-25 06:10:47 -04:00
										 |  |  | M: object remote>handle | 
					
						
							| 
									
										
										
										
											2010-09-21 12:15:33 -04:00
										 |  |  |     [ protocol-family SOCK_STREAM ] [ protocol ] bi socket-fd | 
					
						
							| 
									
										
										
										
											2009-09-27 11:31:02 -04:00
										 |  |  |     [ init-client-socket ] [ ?bind-client ] [ ] tri ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | ! Server sockets - TCP and Unix domain | 
					
						
							|  |  |  | : init-server-socket ( fd -- )
 | 
					
						
							| 
									
										
										
										
											2008-05-14 04:55:33 -04:00
										 |  |  |     SOL_SOCKET SO_REUSEADDR set-socket-option ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-12 19:53:22 -04:00
										 |  |  | : server-socket-fd ( addrspec type -- fd )
 | 
					
						
							| 
									
										
										
										
											2010-09-21 12:15:33 -04:00
										 |  |  |     [ dup protocol-family ] dip pick protocol socket-fd | 
					
						
							| 
									
										
										
										
											2009-08-30 23:21:14 -04:00
										 |  |  |     [ init-server-socket ] keep
 | 
					
						
							| 
									
										
										
										
											2010-01-23 10:07:35 -05:00
										 |  |  |     [ handle-fd swap make-sockaddr/size [ bind ] unix-system-call drop ] keep ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-20 22:46:14 -05:00
										 |  |  | M: object (server) | 
					
						
							| 
									
										
										
										
											2008-05-12 19:53:22 -04:00
										 |  |  |     [ | 
					
						
							| 
									
										
										
										
											2008-05-14 20:41:39 -04:00
										 |  |  |         SOCK_STREAM server-socket-fd | 
					
						
							| 
									
										
										
										
											2010-01-23 10:07:35 -05:00
										 |  |  |         dup handle-fd 128 [ listen ] unix-system-call drop
 | 
					
						
							| 
									
										
										
										
											2008-05-12 19:53:22 -04:00
										 |  |  |     ] with-destructors ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-16 01:57:52 -04:00
										 |  |  | : do-accept ( server addrspec -- fd sockaddr )
 | 
					
						
							| 
									
										
										
										
											2010-10-20 18:42:53 -04:00
										 |  |  |     [ handle>> handle-fd ] [ empty-sockaddr/size int <ref> ] bi*
 | 
					
						
							| 
									
										
										
										
											2008-05-16 01:57:52 -04:00
										 |  |  |     [ accept ] 2keep drop ; inline
 | 
					
						
							| 
									
										
										
										
											2008-05-13 19:24:46 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-20 22:46:14 -05:00
										 |  |  | M: object (accept) | 
					
						
							|  |  |  |     2dup do-accept over 0 >= [ | 
					
						
							|  |  |  |         [ 2nip <fd> init-fd ] dip
 | 
					
						
							|  |  |  |     ] [ | 
					
						
							|  |  |  |         errno { | 
					
						
							|  |  |  |             { EINTR [ 2drop (accept) ] } | 
					
						
							|  |  |  |             { EAGAIN [ | 
					
						
							|  |  |  |                 2drop
 | 
					
						
							|  |  |  |                 [ drop +input+ wait-for-port ] | 
					
						
							|  |  |  |                 [ (accept) ] | 
					
						
							|  |  |  |                 2bi
 | 
					
						
							|  |  |  |             ] } | 
					
						
							| 
									
										
										
										
											2014-11-21 13:19:12 -05:00
										 |  |  |             [ (throw-errno) ] | 
					
						
							| 
									
										
										
										
											2014-11-20 22:46:14 -05:00
										 |  |  |         } case
 | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | ! Datagram sockets - UDP and Unix domain | 
					
						
							| 
									
										
										
										
											2008-05-13 19:24:46 -04:00
										 |  |  | M: unix (datagram) | 
					
						
							|  |  |  |     [ SOCK_DGRAM server-socket-fd ] with-destructors ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-21 23:00:18 -04:00
										 |  |  | M: unix (raw) | 
					
						
							|  |  |  |     [ SOCK_RAW server-socket-fd ] with-destructors ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-29 13:46:19 -04:00
										 |  |  | M: unix (broadcast) | 
					
						
							|  |  |  |     dup handle>> SOL_SOCKET SO_BROADCAST set-socket-option ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-16 22:37:21 -04:00
										 |  |  | :: do-receive ( n buf port -- count sockaddr )
 | 
					
						
							| 
									
										
										
										
											2009-10-28 17:11:33 -04:00
										 |  |  |     port addr>> empty-sockaddr/size :> ( sockaddr len )
 | 
					
						
							| 
									
										
										
										
											2009-09-04 06:02:33 -04:00
										 |  |  |     port handle>> handle-fd ! s | 
					
						
							| 
									
										
										
										
											2011-10-16 22:37:21 -04:00
										 |  |  |     buf ! buf | 
					
						
							|  |  |  |     n ! nbytes | 
					
						
							| 
									
										
										
										
											2009-09-04 06:02:33 -04:00
										 |  |  |     0 ! flags | 
					
						
							|  |  |  |     sockaddr ! from | 
					
						
							| 
									
										
										
										
											2010-10-20 18:42:53 -04:00
										 |  |  |     len int <ref> ! fromlen | 
					
						
							| 
									
										
										
										
											2011-10-16 22:37:21 -04:00
										 |  |  |     recvfrom sockaddr ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : (receive-loop) ( n buf datagram -- count sockaddr )
 | 
					
						
							|  |  |  |     3dup do-receive over 0 > [ [ 3drop ] 2dip ] [ | 
					
						
							|  |  |  |         2drop [ +input+ wait-for-port ] [ (receive-loop) ] bi
 | 
					
						
							|  |  |  |     ] if ; inline recursive
 | 
					
						
							| 
									
										
										
										
											2008-05-13 19:24:46 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-20 22:46:14 -05:00
										 |  |  | M: unix (receive-unsafe) | 
					
						
							| 
									
										
										
										
											2011-10-16 22:37:21 -04:00
										 |  |  |     (receive-loop) ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-13 19:24:46 -04:00
										 |  |  | :: do-send ( packet sockaddr len socket datagram -- )
 | 
					
						
							| 
									
										
										
										
											2008-05-14 04:55:33 -04:00
										 |  |  |     socket handle-fd packet dup length 0 sockaddr len sendto | 
					
						
							| 
									
										
										
										
											2008-05-13 19:24:46 -04:00
										 |  |  |     0 < [ | 
					
						
							| 
									
										
										
										
											2014-11-20 22:46:14 -05:00
										 |  |  |         errno { | 
					
						
							|  |  |  |             { EINTR [ | 
					
						
							|  |  |  |                 packet sockaddr len socket datagram do-send | 
					
						
							|  |  |  |             ] } | 
					
						
							|  |  |  |             { EAGAIN [ | 
					
						
							| 
									
										
										
										
											2008-05-13 19:24:46 -04:00
										 |  |  |                 datagram +output+ wait-for-port | 
					
						
							|  |  |  |                 packet sockaddr len socket datagram do-send | 
					
						
							| 
									
										
										
										
											2014-11-20 22:46:14 -05:00
										 |  |  |             ] } | 
					
						
							| 
									
										
										
										
											2014-11-21 13:19:12 -05:00
										 |  |  |             [ (throw-errno) ] | 
					
						
							| 
									
										
										
										
											2014-11-20 22:46:14 -05:00
										 |  |  |         } case
 | 
					
						
							| 
									
										
										
										
											2011-10-16 22:37:21 -04:00
										 |  |  |     ] when ; inline recursive
 | 
					
						
							| 
									
										
										
										
											2008-05-13 19:24:46 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-20 22:46:14 -05:00
										 |  |  | M: unix (send) | 
					
						
							| 
									
										
										
										
											2016-03-08 07:45:55 -05:00
										 |  |  |     [ make-sockaddr/size-outgoing ] [ [ handle>> ] keep ] bi* do-send ;
 | 
					
						
							| 
									
										
										
										
											2008-05-13 19:24:46 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | ! Unix domain sockets | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | M: local protocol-family drop PF_UNIX ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-03 18:08:54 -04:00
										 |  |  | M: local sockaddr-size drop sockaddr-un heap-size ;
 | 
					
						
							| 
									
										
										
										
											2008-10-02 04:38:36 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-03 18:08:54 -04:00
										 |  |  | M: local empty-sockaddr drop sockaddr-un <struct> ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | M: local make-sockaddr | 
					
						
							| 
									
										
										
										
											2009-10-28 18:25:50 -04:00
										 |  |  |     path>> absolute-path | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  |     dup length 1 + max-un-path > [ "Path too long" throw ] when
 | 
					
						
							| 
									
										
										
										
											2009-09-03 18:08:54 -04:00
										 |  |  |     sockaddr-un <struct> | 
					
						
							|  |  |  |         AF_UNIX >>family | 
					
						
							|  |  |  |         swap utf8 string>alien >>path ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | M: local parse-sockaddr | 
					
						
							|  |  |  |     drop
 | 
					
						
							| 
									
										
										
										
											2009-09-03 18:08:54 -04:00
										 |  |  |     path>> utf8 alien>string <local> ;
 | 
					
						
							| 
									
										
										
										
											2010-09-23 14:19:15 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-16 16:14:17 -04:00
										 |  |  | M: unix host-name | 
					
						
							|  |  |  |     256 [ <byte-array> dup ] keep gethostname io-error | 
					
						
							|  |  |  |     ascii alien>string ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-23 14:19:15 -04:00
										 |  |  | os linux? [ "io.sockets.unix.linux" require ] when
 |