{-# LANGUAGE ScopedTypeVariables #-} -- | This module provides convenience functions for interfacing unix-socket. -- -- This module is only exported on platforms with -- <https://en.wikipedia.org/wiki/Unix_domain_socket Unix domain socket> support. -- -- This module is intended to be imported @qualified@, e.g.: -- -- @ -- import "Data.Connection" -- import qualified "System.IO.Streams.UnixSocket" as UnixSocket -- import qualified "System.IO.Streams.TCP" as TCP -- @ -- -- @since 1.0 -- module System.IO.Streams.UnixSocket ( -- * client connect , connectSocket -- * server , bindAndListen ) where import qualified Control.Exception as E import qualified Network.Socket as N import qualified System.IO.Streams.TCP as TCP -- | Convenience function for initiating an raw TCP connection to the given -- unix-socket file. -- -- Note that sending an end-of-file to the returned 'OutputStream' will not -- close the underlying Socket connection. -- connectSocket :: String -- ^ unix-socket to connect to -> IO (N.Socket, N.SockAddr) connectSocket usock = E.bracketOnError (N.socket N.AF_UNIX N.Stream N.defaultProtocol) N.close (\sock -> do let addr = N.SockAddrUnix usock N.connect sock addr -- NoDelay causes an error for AF_UNIX, so we don't set -- default output buffer of unix socket is too small N.setSocketOption sock N.SendBuffer (TCP.defaultChunkSize * 16) return (sock, addr) ) -- | Connect to unix-socket. -- connect :: String -- ^ unix-socket to connect to -> IO TCP.TCPConnection connect usock = connectSocket usock >>= TCP.socketToConnection TCP.defaultChunkSize -- | Bind and listen on a unix-socket with a limit on connection count. -- -- Use 'TCP.accept' / 'TCP.acceptWith' to accept new unix socket connections. -- bindAndListen :: Int -> String -> IO N.Socket bindAndListen maxc usock = E.bracketOnError (N.socket N.AF_UNIX N.Stream 0) N.close (\sock -> do N.setSocketOption sock N.SendBuffer (TCP.defaultChunkSize * 16) N.bind sock (N.SockAddrUnix usock) N.listen sock maxc return sock )