MissingH-1.6.0.3: src/Network/Utils.hs
{-# LANGUAGE CPP #-}
{-# LANGUAGE Trustworthy #-}
{- arch-tag: Network utilities main file
Copyright (c) 2004-2011 John Goerzen <jgoerzen@complete.org>
All rights reserved.
For license and copyright information, see the file LICENSE
-}
{- |
Module : Network.Utils
Copyright : Copyright (C) 2004-2011 John Goerzen
SPDX-License-Identifier: BSD-3-Clause
Stability : stable
Portability: systems with networking
This module provides various helpful utilities for dealing with networking
Written by John Goerzen, jgoerzen\@complete.org
-}
module Network.Utils (niceSocketsDo, connectTCP, connectTCPAddr,
listenTCPAddr, showSockAddr)
where
import Network.BSD
( getHostByName,
getProtocolNumber,
hostAddress,
HostName,
Family(AF_INET),
PortNumber )
import Network.Socket
( getNameInfo,
withSocketsDo,
bind,
connect,
listen,
socket,
close,
NameInfoFlag(NI_NUMERICHOST),
SockAddr(..),
Socket,
SocketType(Stream) )
#if !(defined(mingw32_HOST_OS) || defined(mingw32_TARGET_OS) || defined(__MINGW32__))
import qualified System.Posix.Signals
#endif
import Control.Exception (bracketOnError)
{- | Sets up the system for networking. Similar to the built-in
withSocketsDo (and actually, calls it), but also sets the SIGPIPE
handler so that signal is ignored.
Example:
> main = niceSocketsDo $ do { ... }
-}
-- FIXME integrate with WebCont.Util.UDP
niceSocketsDo :: IO a -> IO a
niceSocketsDo func = do
#if !(defined(mingw32_HOST_OS) || defined(mingw32_TARGET_OS) || defined(__MINGW32__))
-- No signals on Windows anyway
_ <- System.Posix.Signals.installHandler
System.Posix.Signals.sigPIPE
System.Posix.Signals.Ignore
Nothing
#endif
withSocketsDo func
connectTCP :: HostName -> PortNumber -> IO Socket
connectTCP host port = do
he <- getHostByName host
connectTCPAddr (SockAddrInet port (hostAddress he))
connectTCPAddr :: SockAddr -> IO Socket
connectTCPAddr addr = do
proto <- getProtocolNumber "tcp"
bracketOnError (socket AF_INET Stream proto) close
(\s -> connect s addr >> return s)
listenTCPAddr :: SockAddr -> Int -> IO Socket
listenTCPAddr addr queuelen = do
proto <- getProtocolNumber "tcp"
s <- socket AF_INET Stream proto
bind s addr
listen s queuelen
return s
showSockAddr :: SockAddr -> IO String
#if !(defined(mingw32_HOST_OS) || defined(mingw32_TARGET_OS) || defined(__MINGW32__))
showSockAddr (SockAddrUnix x) = return $ "UNIX socket at " ++ x
#endif
showSockAddr sa@(SockAddrInet port _host) =
do (Just h,_) <- getNameInfo [NI_NUMERICHOST] True False sa
return $ "IPv4 host " ++ h ++ ", port " ++ (show port)