2 % (c) The GRASP/AQUA Project, Glasgow University, 1995-1998
4 \section[SocketPrim]{Low-level socket bindings}
6 The @SocketPrim@ module is for when you want full control over the
7 sockets, exposing the C socket API.
10 {-# OPTIONS -#include "stgio.h" -#include "cbits/ghcSockets.h" #-}
24 socket, -- :: Family -> SocketType -> ProtocolNumber -> IO Socket
25 connect, -- :: Socket -> SockAddr -> IO ()
26 bindSocket, -- :: Socket -> SockAddr -> IO ()
27 listen, -- :: Socket -> Int -> IO ()
28 accept, -- :: Socket -> IO (Socket, SockAddr)
29 getPeerName, -- :: Socket -> IO SockAddr
30 getSocketName, -- :: Socket -> IO SockAddr
32 socketPort, -- :: Socket -> IO PortNumber
34 writeSocket, -- :: Socket -> String -> IO Int
35 readSocket, -- :: Socket -> Int -> IO (String, Int)
36 readSocketAll, -- :: Socket -> IO String
38 socketToHandle, -- :: Socket -> IO Handle
40 sendTo, -- :: Socket -> String -> SockAddr -> IO Int
41 recvFrom, -- :: Socket -> Int -> IO (String, Int, SockAddr)
42 -- sendmsg -- :: Socket -> Message -> MsgFlags -> IO Int
43 -- recvmsg -- :: Socket -> MsgFlags -> IO Message
46 inet_addr, -- :: String -> IO HostAddress
47 inet_ntoa, -- :: HostAddress -> IO String
49 sIsConnected, -- :: Socket -> IO Bool
50 sIsBound, -- :: Socket -> IO Bool
51 sIsListening, -- :: Socket -> IO Bool
52 sIsReadable, -- :: Socket -> IO Bool
53 sIsWritable, -- :: Socket -> IO Bool
54 shutdown, -- :: Socket -> ShutdownCmd -> IO ()
55 sClose, -- :: Socket -> IO ()
59 getSocketOption, -- :: Socket -> SocketOption -> IO Int
60 setSocketOption, -- :: Socket -> SocketOption -> Int -> IO ()
63 mkPortNumber, -- :: Int -> PortNumber
73 -- The following are exported ONLY for use in the BSD module and
74 -- should not be used anywhere else.
76 packFamily, unpackFamily,
78 packSockAddr, unpackSockAddr
85 import PrelIOBase -- IOError, Handle representation
90 import IOExts ( IORef, newIORef, readIORef, writeIORef )
91 import PackedString ( unpackNBytesPS, byteArrayToPS,
92 unpackCString, unpackCStringIO,
98 %************************************************************************
100 \subsection[Socket-SocketTypes]{Socket Types}
102 %************************************************************************
105 There are a few possible ways to do this. The first is convert the
106 structs used in the C library into an equivalent Haskell type. An
107 other possible implementation is to keep all the internals in the C
108 code and use an Int\# and a status flag. The second method is used here
109 since a lot of the C structures are not required to be manipulated.
111 Originally the status was non-mutable so we had to return a new socket
112 each time we changed the status. This version now uses mutable
113 variables to avoid the need to do this. The result is a cleaner
114 interface and better security since the application programmer now
115 can't circumvent the status information to perform invalid operations
120 -- Returned Status Function called
121 = NotConnected -- socket
122 | Bound -- bindSocket
123 | Listening -- listen
124 | Connected -- connect/accept
125 | Error String -- Any
130 Int -- File Descriptor
133 Int -- Protocol Number
134 (IORef SocketStatus) -- Status Flag
137 The scheme used for addressing sockets is somewhat quirky. The
138 calls in the BSD socket API that need to know the socket address all
139 operate in terms of \tr{struct sockaddr}, a `virtual' type of socket address.
141 The Internet family of sockets are addressed as \tr{struct sockaddr\_in},
142 so when calling functions that operate on \tr{struct sockaddr}, we have
143 to type cast the Internet socket address into a \tr{struct sockaddr}. By luck(!),
144 the two structures are of the same size. Same casting is required of other
145 families of sockets such as Xerox NS. Similarly for Unix domain sockets.
147 To represent these socket addresses in Haskell-land, we do what BSD didn't do,
148 and use a union/algebraic type for the different families. Currently only
149 Unix domain sockets and the Internet family is supported.
153 -- NOTE: HostAddresses are represented in network byte order.
154 -- Functions that expect the address in machine byte order
155 -- will have to perform the necessary translation.
156 type HostAddress = Word
159 -- newtyped to prevent accidental use of sane-looking
160 -- port numbers that haven't actually been converted to
161 -- network-byte-order first.
163 newtype PortNumber = PNum Int -- 16-bit value stored in network byte order.
166 instance Show PortNumber where
167 showsPrec p (PNum pn) = showsPrec p pn_host
170 pn_host = unsafePerformIO (_casm_ ``%r=(int)ntohs((int)%0); '' pn)
173 mkPortNumber :: Int -> PortNumber
174 mkPortNumber v = unsafePerformIO $ do
175 po <- _casm_ ``%r=(int)htons((int)%0); '' v
178 data SockAddr -- C Names
179 #ifndef cygwin32_TARGET_OS
180 = SockAddrUnix -- struct sockaddr_un
182 | SockAddrInet -- struct sockaddr_in
183 PortNumber -- sin_port (network byte order)
184 HostAddress -- sin_addr (ditto)
186 = SockAddrInet -- struct sockaddr_in
187 PortNumber -- sin_port (network byte order)
188 HostAddress -- sin_addr (ditto)
193 type ProtocolNumber = Int
198 %************************************************************************
200 \subsection[Socket-Connections]{Connection Functions}
202 %************************************************************************
204 In the following connection and binding primitives. The names of the
205 equivalent C functions have been preserved where possible. It should
206 be noted that some of these names used in the C library, \tr{bind} in
207 particular, have a different meaning to many Haskell programmers and
208 have thus been renamed by appending the prefix Socket.
210 Create an unconnected socket of the given family, type and protocol.
211 The most common invocation of $socket$ is the following:
215 my_socket <- socket AF_INET Stream 6
220 socket :: Family -- Family Name (usually AF_INET)
221 -> SocketType -- Socket Type (usually Stream)
222 -> ProtocolNumber -- Protocol Number (getProtocolByName to find value)
223 -> IO Socket -- Unconnected Socket
225 socket family stype protocol = do
226 status <- _ccall_ createSocket (packFamily family)
227 (packSocketType stype)
230 -1 -> constructErrorAndFail "socket"
232 socket_status <- newIORef NotConnected
233 return (MkSocket n family stype protocol socket_status)
236 Given a port number this {\em binds} the socket to that port. This
237 means that the programmer is only interested in data being sent to
238 that port number. The $Family$ passed to $bindSocket$ must
239 be the same as that passed to $socket$. If the special port
240 number $aNY\_PORT$ is passed then the system assigns the next
243 Port numbers for standard unix services can be found by calling
244 $getServiceEntry$. These are traditionally port numbers below
245 1000; although there are afew, namely NFS and IRC, which used higher
248 The port number allocated to a socket bound by using $aNY\_PORT$ can be
249 found by calling $port$
252 bindSocket :: Socket -- Unconnected Socket
253 -> SockAddr -- Address to Bind to
256 bindSocket (MkSocket s family stype protocol socketStatus) addr = do
257 #ifndef cygwin32_TARGET_OS
258 let isDomainSocket = if family == AF_UNIX then 1 else (0::Int)
260 let isDomainSocket = 0
262 currentStatus <- readIORef socketStatus
263 if currentStatus /= NotConnected
265 fail (userError ("bindSocket: can't peform bind on socket in status " ++
268 addr' <- packSockAddr addr
269 let (_,sz) = boundsOfByteArray addr'
270 status <- _ccall_ bindSocket s addr' sz isDomainSocket
272 -1 -> constructErrorAndFail "bindSocket"
273 0 -> writeIORef socketStatus (Bound)
277 Make a connection to an already opened socket on a given machine and port.
278 assumes that we have already called createSocket, othewise it will fail.
280 This is the dual to $bindSocket$. The {\em server} process will
281 usually bind to a port number, the {\em client} will then connect to
282 the same port number. Port numbers of user applications are normally
283 agreed in advance, otherwise we must rely on some meta protocol for telling
284 the other side what port number we have been allocated.
287 connect :: Socket -- Unconnected Socket
288 -> SockAddr -- Socket address stuff
291 connect (MkSocket s family stype protocol socketStatus) addr = do
292 #ifndef cygwin32_TARGET_OS
293 let isDomainSocket = if family == AF_UNIX then 1 else (0::Int)
295 let isDomainSocket = 0
297 currentStatus <- readIORef socketStatus
298 if currentStatus /= NotConnected
300 fail (userError ("connect: can't peform connect on socket in status " ++
303 addr' <- packSockAddr addr
304 let (_,sz) = boundsOfByteArray addr'
305 status <- _ccall_ connectSocket s addr' sz isDomainSocket
307 -1 -> constructErrorAndFail "connect"
308 0 -> writeIORef socketStatus Connected
311 The programmer must call $listen$ to tell the system software
312 that they are now interested in receiving data on this port. This
313 must be called on the bound socket before any calls to read or write
316 The programmer also gives a number which indicates the length of the
317 incoming queue of unread messages for this socket. On most systems the
318 maximum queue length is around 5. To remove a message from the queue
319 for processing a call to $accept$ should be made.
322 listen :: Socket -- Connected & Bound Socket
323 -> Int -- Queue Length
326 listen (MkSocket s family stype protocol socketStatus) backlog = do
327 currentStatus <- readIORef socketStatus
328 if currentStatus /= Bound
330 fail (userError ("listen: can't peform listen on socket in status " ++
333 status <- _ccall_ listenSocket s backlog
335 -1 -> constructErrorAndFail "listen"
336 0 -> writeIORef socketStatus Listening
339 A call to $accept$ only returns when data is available on the given
340 socket, unless the socket has been set to non-blocking. It will
341 return a new socket which should be used to read the incoming data and
342 should then be closed. Using the socket returned by $accept$ allows
343 incoming requests to be queued on the original socket.
346 accept :: Socket -- Queue Socket
347 -> IO (Socket, -- Readable Socket
348 SockAddr) -- Peer details
350 accept sock@(MkSocket s family stype protocol status) = do
351 currentStatus <- readIORef status
352 okay <- sIsAcceptable sock
355 fail (userError ("accept: can't peform accept on socket in status " ++
358 (ptr, sz) <- allocSockAddr family
359 int_star <- stToIO (newIntArray (0,1))
360 stToIO (writeIntArray int_star 0 sz)
361 sock <- _ccall_ acceptSocket s ptr int_star
363 -1 -> constructErrorAndFail "accept"
365 sz <- stToIO (readIntArray int_star 0)
366 addr <- unpackSockAddr ptr sz
367 status <- newIORef Connected
368 return ((MkSocket sock family stype protocol status), addr)
371 %************************************************************************
373 \subsection[Socket-DataPass]{Data Passing Primitives}
375 %************************************************************************
377 To allow Haskell to talk to C programs we need to be able to
378 communicate in terms of byte streams. @writeSocket@ and
379 @readSocket@ should only be used for this purpose and not for
380 communication between Haskell programs. Haskell programs should use
381 the 1.3 IO hPutStr and associated machinery for communicating with
386 writeSocket :: Socket -- Connected Socket
387 -> String -- Data to send
388 -> IO Int -- Number of Bytes sent
390 writeSocket (MkSocket s family stype protocol status) xs = do
391 currentStatus <- readIORef status
392 if not ((currentStatus == Connected) || (currentStatus == Listening))
394 fail (userError ("writeSocket: can't peform write on socket in status " ++
397 nbytes <- _ccall_ writeDescriptor s xs (length xs)
399 -1 -> constructErrorAndFail "writeSocket"
403 sendTo :: Socket -- Bound/Connected Socket
404 -> String -- Data to send
406 -> IO Int -- Number of Bytes sent
408 sendTo (MkSocket s family stype protocol status) xs addr = do
409 currentStatus <- readIORef status
410 if not ((currentStatus == Connected) || (currentStatus == Listening) || (currentStatus == Bound))
412 fail (userError ("sendTo: can't peform write on socket in status " ++
415 addr' <- packSockAddr addr
416 let (_,sz) = boundsOfByteArray addr'
417 nbytes <- _ccall_ sendTo__ s xs (length xs) addr' sz
419 -1 -> constructErrorAndFail "sendTo"
422 readSocket :: Socket -- Connected (or bound) Socket
423 -> Int -- Number of Bytes to Read
424 -> IO (String, Int) -- (Data Read, Number of Bytes)
426 readSocket (MkSocket s family stype protocol status) nbytes = do
427 currentStatus <- readIORef status
428 if not ((currentStatus == Connected) || (currentStatus == Listening))
430 fail (userError ("readSocket: can't perform read on socket in status " ++
433 ptr <- stToIO (newCharArray (1, nbytes))
434 nbytes <- _ccall_ readDescriptor s ptr nbytes
436 -1 -> constructErrorAndFail "readSocket"
438 barr <- stToIO (unsafeFreezeByteArray ptr)
439 return (unpackNBytesPS (byteArrayToPS barr) n, n)
441 readSocketAll :: Socket -> IO String
446 (readSocket s 4096 >>= \ (str, nbytes) ->
455 recvFrom :: Socket -> Int -> IO (String, Int, SockAddr)
456 recvFrom (MkSocket s family stype protocol status) nbytes = do
457 currentStatus <- readIORef status
458 if not ((currentStatus == Connected) || (currentStatus == Listening) || (currentStatus == Bound))
460 fail (userError ("recvFrom: can't perform read on socket in status " ++
463 ptr <- stToIO (newCharArray (0, nbytes))
464 (ptr_addr,_) <- allocSockAddr AF_INET
465 nbytes <- _ccall_ recvFrom__ s ptr nbytes ptr_addr
467 -1 -> constructErrorAndFail "recvFrom"
469 barr <- stToIO (unsafeFreezeByteArray ptr)
470 addr <- unpackSockAddrInet ptr_addr
471 return (unpackNBytesPS (byteArrayToPS barr) n, n, addr)
475 The port number the given socket is currently connected to can be
476 determined by calling $port$, is generally only useful when bind
477 was given $aNY\_PORT$.
480 socketPort :: Socket -- Connected & Bound Socket
481 -> IO PortNumber -- Port Number of Socket
482 socketPort sock@(MkSocket s AF_INET stype protocol status) =
483 getSocketName sock >>= \(SockAddrInet port _) ->
485 socketPort (MkSocket s family stype protocol status) =
486 fail (userError ("socketPort: not supported for Family " ++ show family))
489 Calling $getPeerName$ returns the address details of the machine,
490 other than the local one, which is connected to the socket. This is
491 used in programs such as FTP to determine where to send the returning
492 data. The corresponding call to get the details of the local machine
496 getPeerName :: Socket -> IO SockAddr
498 getPeerName (MkSocket s family stype protocol status) = do
499 (ptr, sz) <- allocSockAddr family
500 int_star <- stToIO (newIntArray (0,1))
501 stToIO (writeIntArray int_star 0 sz)
502 status <- _ccall_ getPeerName s ptr int_star
504 -1 -> constructErrorAndFail "getPeerName"
506 sz <- stToIO (readIntArray int_star 0)
507 unpackSockAddr ptr sz
509 getSocketName :: Socket -> IO SockAddr
511 getSocketName (MkSocket s family stype protocol status) = do
512 (ptr, sz) <- allocSockAddr family
513 int_star <- stToIO (newIntArray (0,1))
514 stToIO (writeIntArray int_star 0 sz)
515 status <- _ccall_ getSockName s ptr int_star
517 -1 -> constructErrorAndFail "getSocketName"
519 sz <- stToIO (readIntArray int_star 0)
520 unpackSockAddr ptr sz
526 %************************************************************************
528 \subsection[Socket-Properties]{Socket Properties}
530 %************************************************************************
534 = Debug {- SO_DEBUG -}
535 | ReuseAddr {- SO_REUSEADDR -}
537 | SoError {- SO_ERROR -}
538 | DontRoute {- SO_DONTROUTE -}
539 | Broadcast {- SO_BROADCAST -}
540 | SendBuffer {- SO_SNDBUF -}
541 | RecvBuffer {- SO_RCVBUF -}
542 | KeepAlive {- SO_KEEPALIVE -}
543 | OOBInline {- SO_OOBINLINE -}
544 | MaxSegment {- TCP_MAXSEG -}
545 | NoDelay {- TCP_NODELAY -}
546 -- | Linger {- SO_LINGER -}
548 | RecvLowWater {- SO_RCVLOWAT -}
549 | SendLowWater {- SO_SNDLOWAT -}
550 | RecvTimeOut {- SO_RCVTIMEO -}
551 | SendTimeOut {- SO_SNDTIMEO -}
552 | UseLoopBack {- SO_USELOOPBACK -} -- not used, I believe.
555 packSocketOption :: SocketOption -> Int
556 packSocketOption so =
558 Debug -> ``SO_DEBUG''
559 ReuseAddr -> ``SO_REUSEADDR''
561 SoError -> ``SO_ERROR''
562 DontRoute -> ``SO_DONTROUTE''
563 Broadcast -> ``SO_BROADCAST''
564 SendBuffer -> ``SO_SNDBUF''
565 RecvBuffer -> ``SO_RCVBUF''
566 KeepAlive -> ``SO_KEEPALIVE''
567 OOBInline -> ``SO_OOBINLINE''
568 MaxSegment -> ``TCP_MAXSEG''
569 NoDelay -> ``TCP_NODELAY''
571 RecvLowWater -> ``SO_RCVLOWAT''
572 SendLowWater -> ``SO_SNDLOWAT''
573 RecvTimeOut -> ``SO_RCVTIMEO''
574 SendTimeOut -> ``SO_SNDTIMEO''
575 UseLoopBack -> ``SO_USELOOPBACK''
578 setSocketOption :: Socket
579 -> SocketOption -- Option Name
580 -> Int -- Option Value
582 setSocketOption (MkSocket s family stype protocol status) so v = do
583 rc <- _ccall_ setSocketOption__ s (packSocketOption so) v
585 then constructErrorAndFail "setSocketOption"
588 getSocketOption :: Socket
589 -> SocketOption -- Option Name
590 -> IO Int -- Option Value
591 getSocketOption (MkSocket s family stype protocol status) so = do
592 rc <- _ccall_ getSocketOption__ s (packSocketOption so)
593 if rc == -1 -- let's just hope that value isn't taken..
594 then constructErrorAndFail "getSocketOption"
599 A calling sequence table for the main functions is shown in the table below.
603 \begin{tabular}{|l|c|c|c|c|c|c|c|}
605 {\bf A Call to} & socket & connect & bindSocket & listen & accept & read & write \\
607 {\bf Precedes} & & & & & & & \\
609 socket & & & & & & & \\
611 connect & + & & & & & & \\
613 bindSocket & + & & & & & & \\
615 listen & & & + & & & & \\
617 accept & & & & + & & & \\
619 read & & + & & + & + & + & + \\
621 write & & + & & + & + & + & + \\
624 \caption{Sequence Table for Major functions of Socket}
629 %************************************************************************
631 \subsection[Socket-OSDefs]{OS Dependent Definitions}
633 %************************************************************************
636 The following Family and Socket Type declarations were manually derived
637 from @<sys/socket.h>@ on the appropriate machines.
639 Maybe a configure script that could parse the socket.h file to produce
640 the following declaration is required to make it ``portable'' rather than
641 using the dreaded \#ifdefs.
643 Presently only the following machine/os combinations are supported:
655 unpackFamily :: Int -> Family
656 packFamily :: Family -> Int
658 packSocketType :: SocketType -> Int
661 #if sunos4_TARGET_OS || solaris2_TARGET_OS
664 AF_UNSPEC -- unspecified
665 | AF_UNIX -- local to host (pipes, portals
666 | AF_INET -- internetwork: UDP, TCP, etc
667 | AF_IMPLINK -- arpanet imp addresses
668 | AF_PUP -- pup protocols: e.g. BSP
669 | AF_CHAOS -- mit CHAOS protocols
670 | AF_NS -- XEROX NS protocols
671 | AF_NBS -- nbs protocols
672 | AF_ECMA -- european computer manufacturers
673 | AF_DATAKIT -- datakit protocols
674 | AF_CCITT -- CCITT protocols, X.25 etc
676 | AF_DECnet -- DECnet
677 | AF_DLI -- Direct data link interface
679 | AF_HYLINK -- NSC Hyperchannel
680 | AF_APPLETALK -- Apple Talk
681 | AF_NIT -- Network Interface Tap
682 | AF_802 -- IEEE 802.2, also ISO 8802
683 | AF_OSI -- umbrella of all families used by OSI
684 | AF_X25 -- CCITT X.25
686 | AF_GOSSIP -- US Government OSI
687 | AF_IPX -- Novell Internet Protocol
688 deriving (Eq, Ord, Ix, Show)
690 packFamily = index (AF_UNSPEC, AF_IPX)
691 unpackFamily family = (range (AF_UNSPEC, AF_IPX))!!family
695 #if cygwin32_TARGET_OS
698 AF_UNSPEC -- unspecified
699 | AF_UNIX -- local to host (pipes, portals)
700 | AF_INET -- internetwork: UDP, TCP, etc
701 | AF_IMPLINK -- arpanet imp addresses
702 | AF_PUP -- pup protocols: e.g. BSP
703 | AF_CHAOS -- mit CHAOS protocols
704 | AF_NS -- XEROX NS protocols
705 | AF_ISO -- ISO protocols
706 | AF_OSI -- OSI protocols
707 | AF_ECMA -- european computer manufacturers
708 | AF_DATAKIT -- datakit protocols
709 | AF_CCITT -- CCITT protocols, X.25 etc
711 | AF_DECnet -- DECnet
712 | AF_DLI -- Direct data link interface
714 | AF_HYLINK -- NSC Hyperchannel
715 | AF_APPLETALK -- Apple Talk
716 | AF_NETBIOS -- NetBios-style addresses
717 deriving (Eq, Ord, Ix, Show)
719 packFamily = index (AF_UNSPEC, AF_NETBIOS)
720 unpackFamily family = (range (AF_UNSPEC, AF_NETBIOS))!!family
728 AF_UNSPEC -- unspecified
729 | AF_UNIX -- local to host (pipes, portals
730 | AF_INET -- internetwork: UDP, TCP, etc
731 | AF_IMPLINK -- arpanet imp addresses
732 | AF_PUP -- pup protocols: e.g. BSP
733 | AF_CHAOS -- mit CHAOS protocols
734 | AF_NS -- XEROX NS protocols
735 | AF_NBS -- nbs protocols
736 | AF_ECMA -- european computer manufacturers
737 | AF_DATAKIT -- datakit protocols
738 | AF_CCITT -- CCITT protocols, X.25 etc
740 | AF_DECnet -- DECnet
741 | AF_DLI -- Direct data link interface
743 | AF_HYLINK -- NSC Hyperchannel
744 | AF_APPLETALK -- Apple Talk
745 | AF_NIT -- Network Interface Tap
746 deriving (Eq, Ord, Ix, Show)
748 packFamily = index (AF_UNSPEC, AF_NIT)
749 unpackFamily family = (range (AF_UNSPEC, AF_NIT))!!family
753 #if osf1_TARGET_OS || osf3_TARGET_OS
756 AF_UNSPEC -- unspecified
757 | AF_UNIX -- local to host (pipes, portals)
758 | AF_INET -- internetwork: UDP, TCP, etc.
759 | AF_IMPLINK -- arpanet imp addresses
760 | AF_PUP -- pup protocols: e.g. BSP
761 | AF_CHAOS -- mit CHAOS protocols
762 | AF_NS -- XEROX NS protocols
763 | AF_ISO -- ISO protocols
764 | AF_ECMA -- european computer manufacturers
765 | AF_DATAKIT -- datakit protocols
766 | AF_CCITT -- CCITT protocols, X.25 etc
768 | AF_DECnet -- DECnet
769 | AF_DLI -- DEC Direct data link interface
771 | AF_HYLINK -- NSC Hyperchannel
772 | AF_APPLETALK -- Apple Talk
773 | AF_ROUTE -- Internal Routing Protocol
774 | AF_LINK -- Link layer interface
775 | Pseudo_AF_XTP -- eXpress Transfer Protocol (no AF)
776 | AF_NETMAN -- DNA Network Management
777 | AF_X25 -- X25 protocol
778 | AF_CTF -- Common Trace Facility
779 | AF_WAN -- Wide Area Network protocols
780 deriving (Eq, Ord, Ix, Show)
782 packFamily = index (AF_UNSPEC, AF_WAN)
783 unpackFamily family = (range (AF_UNSPEC, AF_WAN))!!family
794 deriving (Eq, Ord, Ix, Show)
796 packFamily = index (AF_UNSPEC, AF_IPX)
797 unpackFamily family = (range (AF_UNSPEC, AF_IPX))!!family
804 AF_UNSPEC -- unspecified
805 | AF_UNIX -- backward compatibility
806 | AF_INET -- internetwork: UDP, TCP, etc.
807 | AF_IMPLINK -- arpanet imp addresses
808 | AF_PUP -- pup protocols: e.g. BSP
809 | AF_CHAOS -- mit CHAOS protocols
810 | AF_NS -- XEROX NS protocols
811 | AF_ISO -- ISO protocols
812 | AF_ECMA -- european computer manufacturers
813 | AF_DATAKIT -- datakit protocols
814 | AF_CCITT -- CCITT protocols, X.25 etc
816 | AF_DECnet -- DECnet
817 | AF_DLI -- DEC Direct data link interface
819 | AF_HYLINK -- NSC Hyperchannel
820 | AF_APPLETALK -- Apple Talk
821 | AF_ROUTE -- Internal Routing Protocol
822 | AF_RAW -- Link layer interface
824 -- these two overlap AF_ROUTE and AF_RAW
825 -- | AF_NIT -- Network Interface Tap
826 -- | AF_802 -- IEEE 802.2, also ISO 8802
828 | AF_OSI -- umbrella for all families used by OSI
829 | AF_X25 -- CCITT X.25
831 | AF_GOSIP -- US Government OSI
833 | AF_SDL -- SGI Data Link for DLPI
834 | AF_INET6 -- Internet Protocol version 6
835 | AF_LINK -- Link layer interface
836 deriving (Eq, Ord, Ix, Show)
838 packFamily = index (AF_UNSPEC, AF_LINK)
839 unpackFamily family = (range (AF_UNSPEC, AF_LINK))!!family
846 AF_UNSPEC -- unspecified
847 | AF_UNIX -- local to host (pipes, portals)
848 | AF_INET -- internetwork: UDP, TCP, etc.
849 | AF_IMPLINK -- arpanet imp addresses
850 | AF_PUP -- pup protocols: e.g. BSP
851 | AF_CHAOS -- mit CHAOS protocols
852 | AF_NS -- XEROX NS protocols
853 | AF_ISO -- ISO protocols
854 -- | AF_OSI is the same as AF_ISO on AIX
855 | AF_ECMA -- european computer manufacturers
856 | AF_DATAKIT -- datakit protocols
857 | AF_CCITT -- CCITT protocols, X.25 etc
859 | AF_DECnet -- DECnet
860 | AF_DLI -- DEC Direct data link interface
862 | AF_HYLINK -- NSC Hyperchannel
863 | AF_APPLETALK -- Apple Talk
864 | AF_ROUTE -- Internal Routing Protocol
865 | AF_LINK -- Link layer interface
866 | Pseudo_AF_XTP -- eXpress Transfer Protocol (no AF)
867 | AF_INTF -- Debugging use only
868 | AF_RIF -- raw interface
872 deriving (Eq, Ord, Ix, Show)
874 packFamily = index (AF_UNSPEC, AF_MAX)
875 unpackFamily family = (range (AF_UNSPEC, AF_MAX))!!family
879 #if freebsd_TARGET_OS
882 AF_UNSPEC -- unspecified
883 | AF_UNIX -- local to host (pipes, portals)
884 | AF_INET -- internetwork: UDP, TCP, etc.
885 | AF_IMPLINK -- arpanet imp addresses
886 | AF_PUP -- pup protocols: e.g. BSP
887 | AF_CHAOS -- mit CHAOS protocols
888 | AF_NS -- XEROX NS protocols
889 | AF_ISO -- ISO protocols
890 -- | AF_OSI is the same as AF_ISO
891 | AF_ECMA -- european computer manufacturers
892 | AF_DATAKIT -- datakit protocols
893 | AF_CCITT -- CCITT protocols, X.25 etc
895 | AF_DECnet -- DECnet
896 | AF_DLI -- DEC Direct data link interface
898 | AF_HYLINK -- NSC Hyperchannel
899 | AF_APPLETALK -- Apple Talk
900 | AF_ROUTE -- Internal Routing Protocol
901 | AF_LINK -- Link layer interface
902 | Pseudo_AF_XTP -- eXpress Transfer Protocol (no AF)
903 | AF_COIP -- connection-oriented IP, aka ST II
904 | AF_CNT -- Computer Network Technology
905 | Psuedo_AF_RTIP -- Help Identify RTIP packets
906 | AF_IPX -- Novell Internet Protocol
907 | AF_SIP -- Simple Internet Protocol
908 | Pseudo_AF_PIP -- Help Identify PIP packets
909 | AF_ISDN -- Integrated Services Digital Network
910 -- | AF_E164 is the same as AF_ISDN
911 | Pseudo_AF_KEY -- Internal key-management function
914 deriving (Eq, Ord, Ix, Show)
916 packFamily = index (AF_UNSPEC, AF_MAX)
917 unpackFamily family = (range (AF_UNSPEC, AF_MAX))!!family
921 -- Alpha running OSF or a SPARC with SunOS, rather than Solaris.
923 #if osf1_TARGET_OS || osf3_TARGET_OS || sunos4_TARGET_OS || hpux_TARGET_OS || \
924 aix_TARGET_OS || freebsd_TARGET_OS
931 deriving (Eq, Ord, Ix, Show)
933 packSocketType stype = 1 + (index (Stream, SeqPacket) stype)
936 -- This is for a box running cygwin32 toolchain.
938 #if defined(cygwin32_TARGET_OS)
943 | RDM -- reliably delivered msg
946 deriving (Eq, Ord, Ix, Show)
948 packSocketType stype =
950 Stream -> ``SOCK_STREAM''
951 Datagram -> ``SOCK_DGRAM''
954 SeqPacket -> ``SOCK_SEQPACKET''
955 Packet -> ``SOCK_PACKET''
959 -- This is a Sun running Solaris rather than SunOS or SGI running IRIX
961 #if defined(solaris2_TARGET_OS) || defined(irix_TARGET_OS)
969 deriving (Eq, Ord, Ix, Show)
971 packSocketType stype = 1 + (index (Datagram, SeqPacket) stype)
983 deriving (Eq, Ord, Ix, Show)
985 packSocketType stype = 1 + (index (Stream, Packet) stype)
989 %************************************************************************
991 \subsection[Socket-Util]{Utility Functions}
993 %************************************************************************
996 aNY_PORT :: PortNumber
997 aNY_PORT = mkPortNumber 0
999 iNADDR_ANY :: HostAddress
1000 iNADDR_ANY = unsafePerformIO (_casm_ `` %r = htonl(INADDR_ANY); '')
1002 sOMAXCONN = ``SOMAXCONN''::Int
1003 maxListenQueue = sOMAXCONN
1005 -------------------------------------------------------------------------------
1011 sdownCmdToInt :: ShutdownCmd -> Int
1012 sdownCmdToInt ShutdownReceive = 0
1013 sdownCmdToInt ShutdownSend = 1
1014 sdownCmdToInt ShutdownBoth = 2
1016 shutdown :: Socket -> ShutdownCmd -> IO ()
1017 shutdown (MkSocket s _ _ _ _) stype = do
1018 let t = sdownCmdToInt stype
1019 status <- _ccall_ shutdownSocket s t
1021 -1 -> constructErrorAndFail "shutdown"
1024 -------------------------------------------------------------------------------
1026 sClose :: Socket -> IO ()
1027 sClose (MkSocket s family stype protocol status) = _ccall_ close s
1029 -------------------------------------------------------------------------------
1031 sIsConnected :: Socket -> IO Bool
1032 sIsConnected (MkSocket s family stype protocol status) = do
1033 value <- readIORef status
1034 return (value == Connected)
1036 -------------------------------------------------------------------------------
1038 sIsBound :: Socket -> IO Bool
1039 sIsBound (MkSocket s family stype protocol status) = do
1040 value <- readIORef status
1041 return (value == Bound)
1043 -------------------------------------------------------------------------------
1045 sIsListening :: Socket -> IO Bool
1046 sIsListening (MkSocket s family stype protocol status) = do
1047 value <- readIORef status
1048 return (value == Listening)
1050 -------------------------------------------------------------------------------
1052 sIsReadable :: Socket -> IO Bool
1053 sIsReadable (MkSocket s family stype protocol status) = do
1054 value <- readIORef status
1055 return (value == Listening || value == Connected)
1057 -------------------------------------------------------------------------------
1059 sIsWritable :: Socket -> IO Bool
1060 sIsWritable = sIsReadable
1062 -------------------------------------------------------------------------------
1064 sIsAcceptable :: Socket -> IO Bool
1065 #ifndef cygwin32_TARGET_OS
1066 sIsAcceptable (MkSocket s AF_UNIX Stream protocol status) = do
1067 value <- readIORef status
1068 return (value == Connected || value == Bound || value == Listening)
1069 sIsAcceptable (MkSocket s AF_UNIX _ protocol status) =
1072 sIsAcceptable (MkSocket s _ stype protocol status) = do
1073 value <- readIORef status
1074 return (value == Connected || value == Listening)
1076 -------------------------------------------------------------------------------
1079 sSetBlocking :: Socket -> Bool -> IO ()
1080 sIsBlocking :: Socket -> IO Bool
1085 Internet address manipulation routines:
1088 inet_addr :: String -> IO HostAddress
1089 inet_addr ipstr = do
1090 had <- _ccall_ inet_addr ipstr
1091 if had == (W# (int2Word# (negateInt# 1#))) -- hack to avoid depending on Int.intToWord here.
1092 then fail (userError ("inet_addr: Malformed address: " ++ ipstr))
1093 else return had -- network byte order
1095 inet_ntoa :: HostAddress -> IO String
1096 inet_ntoa haddr = do
1097 pstr <- _casm_ ``struct in_addr addr;
1099 %r = inet_ntoa (addr);'' haddr
1100 -- unpack straight away, since pstr points to static buffer.
1101 unpackCStringIO pstr
1105 Marshaling and allocation helper functions:
1108 -------------------------------------------------------------------------------
1110 allocSockAddr :: Family -> IO (MutableByteArray RealWorld Int, Int)
1112 #ifndef cygwin32_TARGET_OS
1113 allocSockAddr AF_UNIX = do
1114 ptr <- stToIO (newCharArray (0,``sizeof(struct sockaddr_un)''))
1115 let (_,sz) = boundsOfByteArray ptr
1119 allocSockAddr AF_INET = do
1120 ptr <- stToIO (newCharArray (0,``sizeof(struct sockaddr_in)''))
1121 let (_,sz) = boundsOfByteArray ptr
1124 -------------------------------------------------------------------------------
1126 unpackSockAddr :: MutableByteArray RealWorld Int -> Int -> IO SockAddr
1127 unpackSockAddr arr len = do
1128 fam <- _casm_ ``%r = ((struct sockaddr*)%0)->sa_family;'' arr
1129 case unpackFamily fam of
1130 #ifndef cygwin32_TARGET_OS
1131 AF_UNIX -> unpackSockAddrUnix arr (len - ``sizeof(short)'')
1133 AF_INET -> unpackSockAddrInet arr
1135 -------------------------------------------------------------------------------
1137 #ifndef cygwin32_TARGET_OS
1140 sun_path is *not* NULL terminated, hence we *do* need to know the
1143 unpackSockAddrUnix :: (MutableByteArray RealWorld Int) -> Int -> IO SockAddr
1144 unpackSockAddrUnix ptr len = do
1145 char_star <- _casm_ ``%r = ((struct sockaddr_un*)%0)->sun_path;'' ptr
1146 path <- unpackCStringLenIO char_star len
1147 return (SockAddrUnix path)
1151 -------------------------------------------------------------------------------
1153 unpackSockAddrInet :: (MutableByteArray RealWorld Int) -> IO SockAddr
1154 unpackSockAddrInet ptr = do
1155 port <- _casm_ ``%r = ((struct sockaddr_in*)%0)->sin_port;'' ptr
1156 addr <- _casm_ ``%r = ((struct sockaddr_in*)%0)->sin_addr.s_addr;'' ptr
1157 return (SockAddrInet (PNum port) addr)
1159 -------------------------------------------------------------------------------
1162 packSockAddr :: SockAddr -> IO (MutableByteArray RealWorld Int)
1163 #ifndef cygwin32_TARGET_OS
1164 packSockAddr (SockAddrUnix path) = do
1165 (ptr,_) <- allocSockAddr AF_UNIX
1166 _casm_ ``(((struct sockaddr_un *)%0)->sun_family) = AF_UNIX;'' ptr
1167 _casm_ ``strcpy ((((struct sockaddr_un *)%0)->sun_path),%1);'' ptr path
1170 packSockAddr (SockAddrInet (PNum port) address) = do
1171 (ptr,_) <- allocSockAddr AF_INET
1172 _casm_ ``(((struct sockaddr_in *)%0)->sin_family) = AF_INET;'' ptr
1173 _casm_ ``(((struct sockaddr_in *)%0)->sin_port) = (int)%1;'' ptr port
1174 _casm_ ``(((struct sockaddr_in *)%0)->sin_addr.s_addr) = %1;'' ptr address
1177 -------------------------------------------------------------------------------
1180 @socketHandle@ turns a @Socket@ into a Haskell IO @Handle@. By default, the new
1181 handle will not be buffered, use @hSetBuffering@ if you want to change
1185 #ifndef __PARALLEL_HASKELL__
1186 socketToHandle :: Socket -> IOMode -> IO Handle
1188 socketToHandle (MkSocket fd family stype protocol status) m = do
1189 fo <- _ccall_ openFd fd file_mode flush_on_close
1190 fo <- makeForeignObj fo (``&freeFileObject'' :: Addr)
1191 mkBuffer__ fo 0 -- not buffered
1192 hndl <- newHandle (Handle__ fo htype NoBuffering socket_str)
1195 socket_str = "<socket: "++show fd
1196 (flush_on_close, file_mode) =
1198 AppendMode -> (1, 0)
1201 ReadWriteMode -> (1, 3)
1205 ReadMode -> ReadHandle
1206 WriteMode -> WriteHandle
1207 AppendMode -> AppendHandle
1208 ReadWriteMode -> ReadWriteHandle
1210 socketToHandle (MkSocket s family stype protocol status) m =
1211 error "socketToHandle not implemented in a parallel setup"