content: {-|
  Module      : Util.Net
  Description : Utilities for Network IO.
  
  License     : BSD3
  Maintainer  : The Idris Community.
  -}
  module Util.Net (listenOnLocalhost, listenOnLocalhostAnyPort) where
  
  import Control.Exception (bracketOnError)
  import Network.Socket
  -- Copied from upstream impl of listenOn
  -- bound to localhost interface instead of iNADDR_ANY
  listenOnLocalhost :: PortNumber -> IO Socket
  listenOnLocalhost port = do
      let hints = defaultHints { addrSocketType = Stream }
      localhost:_ <- getAddrInfo (Just hints) (Just "127.0.0.1") (Just $ show port)
      bracketOnError
        (socket AF_INET Stream defaultProtocol)
        (close)
        (\sock -> do
            setSocketOption sock ReuseAddr 1
            bind sock (addrAddress localhost)
            listen sock maxListenQueue
            return sock
        )
  
  listenOnLocalhostAnyPort :: IO (Socket, PortNumber)
  listenOnLocalhostAnyPort = do
      let hints = defaultHints { addrSocketType = Stream }
      localhost:_ <- getAddrInfo (Just hints) (Just "127.0.0.1") (Just "0")
      bracketOnError
        (socket AF_INET Stream defaultProtocol)
        (close)
        (\sock -> do
            setSocketOption sock ReuseAddr 1
            bind sock (addrAddress localhost)
            listen sock maxListenQueue
            port <- socketPort sock
            return (sock, port)
        )
  