    {-# INCLUDE "HsNet.h" #-}
    {-# OPTIONS_GHC -optc-DWITH_WINSOCK=1 #-}
    {-# LINE 1 "Network\Socket.hsc" #-}
    {-# OPTIONS -fglasgow-exts -cpp #-}
    {-# LINE 2 "Network\Socket.hsc" #-}
    -----------------------------------------------------------------------------
    -- |
    -- Module      :  Network.Socket
    -- Copyright   :  (c) The University of Glasgow 2001
    -- License     :  BSD-style (see the file libraries/network/LICENSE)
    --
    -- Maintainer  :  libraries@haskell.org
    -- Stability   :  provisional
    -- Portability :  portable
    --
    -- The "Network.Socket" module is for when you want full control over
    -- sockets.  Essentially the entire C socket API is exposed through
    -- this module; in general the operations follow the behaviour of the C
    -- functions of the same name (consult your favourite Unix networking book).
    --
    -- A higher level interface to networking operations is provided
    -- through the module "Network".
    --
    -----------------------------------------------------------------------------

    {-# LINE 23 "Network\Socket.hsc" #-}

    -- NOTE: ##, we want this interpreted when compiling the .hs, not by hsc2hs.
    #include "Typeable.h"

    {-# LINE 28 "Network\Socket.hsc" #-}

    {-# LINE 29 "Network\Socket.hsc" #-}

    {-# LINE 30 "Network\Socket.hsc" #-}

    {-# LINE 34 "Network\Socket.hsc" #-}

    {-# LINE 42 "Network\Socket.hsc" #-}

    -- In order to process this file, you need to have CALLCONV defined.

    module Network.Socket (

        -- * Types
        Socket(..),		-- instance Eq, Show
        Family(..),
        SocketType(..),
        SockAddr(..),
        SocketStatus(..),
        HostAddress,

    {-# LINE 59 "Network\Socket.hsc" #-}
        ShutdownCmd(..),
        ProtocolNumber,
        defaultProtocol,        -- :: ProtocolNumber
        PortNumber(..),
    	-- PortNumber is used non-abstractly in Network.BSD.  ToDo: remove
    	-- this use and make the type abstract.

        -- * Address operations

        HostName,
        ServiceName,

    {-# LINE 85 "Network\Socket.hsc" #-}

        -- * Socket Operations
        socket,		-- :: Family -> SocketType -> ProtocolNumber -> IO Socket

    {-# LINE 91 "Network\Socket.hsc" #-}
        connect,		-- :: Socket -> SockAddr -> IO ()
        bindSocket,		-- :: Socket -> SockAddr -> IO ()
        listen,		-- :: Socket -> Int -> IO ()
        accept,		-- :: Socket -> IO (Socket, SockAddr)
        getPeerName,	-- :: Socket -> IO SockAddr
        getSocketName,	-- :: Socket -> IO SockAddr

    {-# LINE 102 "Network\Socket.hsc" #-}

        socketPort,		-- :: Socket -> IO PortNumber

        socketToHandle,	-- :: Socket -> IOMode -> IO Handle

        sendTo,		-- :: Socket -> String -> SockAddr -> IO Int
        sendBufTo,          -- :: Socket -> Ptr a -> Int -> SockAddr -> IO Int

        recvFrom,		-- :: Socket -> Int -> IO (String, Int, SockAddr)
        recvBufFrom,        -- :: Socket -> Ptr a -> Int -> IO (Int, SockAddr)

        send,		-- :: Socket -> String -> IO Int
        recv,		-- :: Socket -> Int    -> IO String
        recvLen,            -- :: Socket -> Int    -> IO (String, Int)

        inet_addr,		-- :: String -> IO HostAddress
        inet_ntoa,		-- :: HostAddress -> IO String

        shutdown,		-- :: Socket -> ShutdownCmd -> IO ()
        sClose,		-- :: Socket -> IO ()

        -- ** Predicates on sockets
        sIsConnected,	-- :: Socket -> IO Bool
        sIsBound,		-- :: Socket -> IO Bool
        sIsListening,	-- :: Socket -> IO Bool
        sIsReadable,	-- :: Socket -> IO Bool
        sIsWritable,	-- :: Socket -> IO Bool

        -- * Socket options
        SocketOption(..),
        getSocketOption,     -- :: Socket -> SocketOption -> IO Int
        setSocketOption,     -- :: Socket -> SocketOption -> Int -> IO ()

        -- * File descriptor transmission

    {-# LINE 145 "Network\Socket.hsc" #-}

        -- * Special Constants
        aNY_PORT,		-- :: PortNumber
        iNADDR_ANY,		-- :: HostAddress

    {-# LINE 152 "Network\Socket.hsc" #-}
        sOMAXCONN,		-- :: Int
        sOL_SOCKET,         -- :: Int

    {-# LINE 157 "Network\Socket.hsc" #-}
        maxListenQueue,	-- :: Int

        -- * Initialisation
        withSocketsDo,	-- :: IO a -> IO a

        -- * Very low level operations
         -- in case you ever want to get at the underlying file descriptor..
        fdSocket,           -- :: Socket -> CInt
        mkSocket,           -- :: CInt   -> Family
        			-- -> SocketType
    			-- -> ProtocolNumber
    			-- -> SocketStatus
    			-- -> IO Socket

        -- * Internal

        -- | The following are exported ONLY for use in the BSD module and
        -- should not be used anywhere else.

        packFamily, unpackFamily,
        packSocketType,
        throwSocketErrorIfMinus1_

    ) where

    {-# LINE 194 "Network\Socket.hsc" #-}

    import Data.Bits
    import Data.List (foldl')
    import Data.Word ( Word8, Word16, Word32 )
    import Foreign.Ptr ( Ptr, castPtr, nullPtr, plusPtr )
    import Foreign.Storable ( Storable(..) )
    import Foreign.C.Error
    import Foreign.C.String ( CString, withCString, peekCString, peekCStringLen, castCharToCChar )
    import Foreign.C.Types ( CInt, CUInt, CChar, CSize )
    import Foreign.Marshal.Alloc ( alloca, allocaBytes )
    import Foreign.Marshal.Array ( peekArray, pokeArray0 )
    import Foreign.Marshal.Utils ( maybeWith, with )

    import System.IO
    import Control.Monad ( liftM, when )
    import Data.Ratio ( (%) )

    import qualified Control.Exception
    import Control.Concurrent.MVar
    import Data.Typeable

    {-# LINE 216 "Network\Socket.hsc" #-}
    import GHC.Conc		(threadWaitRead, threadWaitWrite)

    {-# LINE 218 "Network\Socket.hsc" #-}
    import GHC.Conc		( asyncDoProc )
    import Foreign( FunPtr )

    {-# LINE 221 "Network\Socket.hsc" #-}
    import GHC.Handle
    import GHC.IOBase
    import qualified System.Posix.Internals

    {-# LINE 227 "Network\Socket.hsc" #-}

    type HostName       = String
    type ServiceName    = String

    -----------------------------------------------------------------------------
    -- Socket types

    -- There are a few possible ways to do this.  The first is convert the
    -- structs used in the C library into an equivalent Haskell type. An
    -- other possible implementation is to keep all the internals in the C
    -- code and use an Int## and a status flag. The second method is used
    -- here since a lot of the C structures are not required to be
    -- manipulated.

    -- Originally the status was non-mutable so we had to return a new
    -- socket each time we changed the status.  This version now uses
    -- mutable variables to avoid the need to do this.  The result is a
    -- cleaner interface and better security since the application
    -- programmer now can't circumvent the status information to perform
    -- invalid operations on sockets.

    data SocketStatus
      -- Returned Status	Function called
      = NotConnected	-- socket
      | Bound		-- bindSocket
      | Listening		-- listen
      | Connected		-- connect/accept
      | ConvertedToHandle   -- is now a Handle, don't touch
        deriving (Eq, Show)

    INSTANCE_TYPEABLE0(SocketStatus,socketStatusTc,"SocketStatus")

    data Socket
      = MkSocket
    	    CInt	         -- File Descriptor
    	    Family
    	    SocketType
    	    ProtocolNumber	 -- Protocol Number
    	    (MVar SocketStatus)  -- Status Flag

    INSTANCE_TYPEABLE0(Socket,socketTc,"Socket")

    mkSocket :: CInt
    	 -> Family
    	 -> SocketType
    	 -> ProtocolNumber
    	 -> SocketStatus
    	 -> IO Socket
    mkSocket fd fam sType pNum stat = do
       mStat <- newMVar stat
       return (MkSocket fd fam sType pNum mStat)

    instance Eq Socket where
      (MkSocket _ _ _ _ m1) == (MkSocket _ _ _ _ m2) = m1 == m2

    instance Show Socket where
      showsPrec n (MkSocket fd _ _ _ _) =
    	showString "<socket: " . shows fd . showString ">"

    fdSocket :: Socket -> CInt
    fdSocket (MkSocket fd _ _ _ _) = fd

    type ProtocolNumber = CInt

    -- | This is the default protocol for a given service.
    defaultProtocol :: ProtocolNumber
    defaultProtocol = 0

    -- NOTE: HostAddresses are represented in network byte order.
    --       Functions that expect the address in machine byte order
    --       will have to perform the necessary translation.
    type HostAddress = Word32

    {-# LINE 304 "Network\Socket.hsc" #-}

    ----------------------------------------------------------------------------
    -- Port Numbers
    --
    -- newtyped to prevent accidental use of sane-looking
    -- port numbers that haven't actually been converted to
    -- network-byte-order first.
    --
    newtype PortNumber = PortNum Word16 deriving ( Eq, Ord )

    INSTANCE_TYPEABLE0(PortNumber,portNumberTc,"PortNumber")

    instance Show PortNumber where
      showsPrec p pn = showsPrec p (portNumberToInt pn)

    intToPortNumber :: Int -> PortNumber
    intToPortNumber v = PortNum (htons (fromIntegral v))

    portNumberToInt :: PortNumber -> Int
    portNumberToInt (PortNum po) = fromIntegral (ntohs po)

    foreign import CALLCONV unsafe "ntohs" ntohs :: Word16 -> Word16
    foreign import CALLCONV unsafe "htons" htons :: Word16 -> Word16
    --foreign import CALLCONV unsafe "ntohl" ntohl :: Word32 -> Word32
    foreign import CALLCONV unsafe "htonl" htonl :: Word32 -> Word32

    instance Enum PortNumber where
        toEnum   = intToPortNumber
        fromEnum = portNumberToInt

    instance Num PortNumber where
       fromInteger i = intToPortNumber (fromInteger i)
        -- for completeness.
       (+) x y   = intToPortNumber (portNumberToInt x + portNumberToInt y)
       (-) x y   = intToPortNumber (portNumberToInt x - portNumberToInt y)
       negate x  = intToPortNumber (-portNumberToInt x)
       (*) x y   = intToPortNumber (portNumberToInt x * portNumberToInt y)
       abs n     = intToPortNumber (abs (portNumberToInt n))
       signum n  = intToPortNumber (signum (portNumberToInt n))

    instance Real PortNumber where
        toRational x = toInteger x % 1

    instance Integral PortNumber where
        quotRem a b = let (c,d) = quotRem (portNumberToInt a) (portNumberToInt b) in
    		  (intToPortNumber c, intToPortNumber d)
        toInteger a = toInteger (portNumberToInt a)

    instance Storable PortNumber where
       sizeOf    _ = sizeOf    (undefined :: Word16)
       alignment _ = alignment (undefined :: Word16)
       poke p (PortNum po) = poke (castPtr p) po
       peek p = PortNum `liftM` peek (castPtr p)

    -----------------------------------------------------------------------------
    -- SockAddr

    -- The scheme used for addressing sockets is somewhat quirky. The
    -- calls in the BSD socket API that need to know the socket address
    -- all operate in terms of struct sockaddr, a `virtual' type of
    -- socket address.

    -- The Internet family of sockets are addressed as struct sockaddr_in,
    -- so when calling functions that operate on struct sockaddr, we have
    -- to type cast the Internet socket address into a struct sockaddr.
    -- Instances of the structure for different families might *not* be
    -- the same size. Same casting is required of other families of
    -- sockets such as Xerox NS. Similarly for Unix domain sockets.

    -- To represent these socket addresses in Haskell-land, we do what BSD
    -- didn't do, and use a union/algebraic type for the different
    -- families. Currently only Unix domain sockets and the Internet
    -- families are supported.

    {-# LINE 382 "Network\Socket.hsc" #-}

    data SockAddr		-- C Names
      = SockAddrInet
    	PortNumber	-- sin_port  (network byte order)
    	HostAddress	-- sin_addr  (ditto)

    {-# LINE 394 "Network\Socket.hsc" #-}

    {-# LINE 398 "Network\Socket.hsc" #-}
      deriving (Eq)

    INSTANCE_TYPEABLE0(SockAddr,sockAddrTc,"SockAddr")

    {-# LINE 403 "Network\Socket.hsc" #-}
    type CSaFamily = (Word16)
    {-# LINE 404 "Network\Socket.hsc" #-}

    {-# LINE 409 "Network\Socket.hsc" #-}

    instance Show SockAddr where

    {-# LINE 414 "Network\Socket.hsc" #-}
      showsPrec _ (SockAddrInet port ha)
       = showString (unsafePerformIO (inet_ntoa ha))
       . showString ":"
       . shows port

    {-# LINE 474 "Network\Socket.hsc" #-}

    -- we can't write an instance of Storable for SockAddr, because the Storable
    -- class can't easily handle alternatives. Also note that on Darwin, the
    -- sockaddr structure must be zeroed before use.

    {-# LINE 488 "Network\Socket.hsc" #-}
    pokeSockAddr p (SockAddrInet (PortNum port) addr) = do

    {-# LINE 492 "Network\Socket.hsc" #-}
    	((\hsc_ptr -> pokeByteOff hsc_ptr 0)) p ((2) :: CSaFamily)
    {-# LINE 493 "Network\Socket.hsc" #-}
    	((\hsc_ptr -> pokeByteOff hsc_ptr 2)) p port
    {-# LINE 494 "Network\Socket.hsc" #-}
    	((\hsc_ptr -> pokeByteOff hsc_ptr 4)) p addr
    {-# LINE 495 "Network\Socket.hsc" #-}

    {-# LINE 506 "Network\Socket.hsc" #-}

    peekSockAddr :: Ptr SockAddr -> IO SockAddr

    peekSockAddr p = do
      family <- ((\hsc_ptr -> peekByteOff hsc_ptr 0)) p
    {-# LINE 511 "Network\Socket.hsc" #-}
      case family :: CSaFamily of

    {-# LINE 517 "Network\Socket.hsc" #-}
    	(2) -> do
    {-# LINE 518 "Network\Socket.hsc" #-}
    		addr <- ((\hsc_ptr -> peekByteOff hsc_ptr 4)) p
    {-# LINE 519 "Network\Socket.hsc" #-}
    		port <- ((\hsc_ptr -> peekByteOff hsc_ptr 2)) p
    {-# LINE 520 "Network\Socket.hsc" #-}
    		return (SockAddrInet (PortNum port) addr)

    {-# LINE 529 "Network\Socket.hsc" #-}

    -- helper function used to zero a structure
    zeroMemory :: Ptr a -> CSize -> IO ()
    zeroMemory dest nbytes = memset dest 0 (fromIntegral nbytes)
    foreign import ccall unsafe "string.h" memset :: Ptr a -> CInt -> CSize -> IO ()

    -- size of struct sockaddr by family

    {-# LINE 539 "Network\Socket.hsc" #-}

    {-# LINE 542 "Network\Socket.hsc" #-}
    sizeOfSockAddr_Family AF_INET = 16
    {-# LINE 543 "Network\Socket.hsc" #-}

    -- size of struct sockaddr by SockAddr

    {-# LINE 548 "Network\Socket.hsc" #-}
    sizeOfSockAddr (SockAddrInet _ _) = 16
    {-# LINE 549 "Network\Socket.hsc" #-}

    {-# LINE 552 "Network\Socket.hsc" #-}

    withSockAddr :: SockAddr -> (Ptr SockAddr -> Int -> IO a) -> IO a
    withSockAddr addr f = do
     let sz = sizeOfSockAddr addr
     allocaBytes sz $ \p -> pokeSockAddr p addr >> f (castPtr p) sz

    withNewSockAddr :: Family -> (Ptr SockAddr -> Int -> IO a) -> IO a
    withNewSockAddr family f = do
     let sz = sizeOfSockAddr_Family family
     allocaBytes sz $ \ptr -> f ptr sz

    -----------------------------------------------------------------------------
    -- Connection Functions

    -- In the following connection and binding primitives.  The names of
    -- the equivalent C functions have been preserved where possible. It
    -- should be noted that some of these names used in the C library,
    -- \tr{bind} in particular, have a different meaning to many Haskell
    -- programmers and have thus been renamed by appending the prefix
    -- Socket.

    -- Create an unconnected socket of the given family, type and
    -- protocol.  The most common invocation of $socket$ is the following:
    --    ...
    --    my_socket <- socket AF_INET Stream 6
    --    ...

    socket :: Family 	 -- Family Name (usually AF_INET)
           -> SocketType 	 -- Socket Type (usually Stream)
           -> ProtocolNumber -- Protocol Number (getProtocolByName to find value)
           -> IO Socket	 -- Unconnected Socket

    socket family stype protocol = do
        fd <- throwSocketErrorIfMinus1Retry "socket" $
    		c_socket (packFamily family) (packSocketType stype) protocol

    {-# LINE 588 "Network\Socket.hsc" #-}
        System.Posix.Internals.setNonBlockingFD fd

    {-# LINE 590 "Network\Socket.hsc" #-}
        socket_status <- newMVar NotConnected
        return (MkSocket fd family stype protocol socket_status)

    -- Create an unnamed pair of connected sockets, given family, type and
    -- protocol. Differs from a normal pipe in being a bi-directional channel
    -- of communication.

    {-# LINE 623 "Network\Socket.hsc" #-}

    -----------------------------------------------------------------------------
    -- Binding a socket
    --
    -- Given a port number this {\em binds} the socket to that port. This
    -- means that the programmer is only interested in data being sent to
    -- that port number. The $Family$ passed to $bindSocket$ must
    -- be the same as that passed to $socket$.	 If the special port
    -- number $aNY\_PORT$ is passed then the system assigns the next
    -- available use port.
    --
    -- Port numbers for standard unix services can be found by calling
    -- $getServiceEntry$.  These are traditionally port numbers below
    -- 1000; although there are afew, namely NFS and IRC, which used higher
    -- numbered ports.
    --
    -- The port number allocated to a socket bound by using $aNY\_PORT$ can be
    -- found by calling $port$

    bindSocket :: Socket	-- Unconnected Socket
    	   -> SockAddr	-- Address to Bind to
    	   -> IO ()

    bindSocket (MkSocket s _family _stype _protocol socketStatus) addr = do
     modifyMVar_ socketStatus $ \ status -> do
     if status /= NotConnected
      then
       ioError (userError ("bindSocket: can't peform bind on socket in status " ++
    	 show status))
      else do
       withSockAddr addr $ \p_addr sz -> do
       status <- throwSocketErrorIfMinus1Retry "bind" $ c_bind s p_addr (fromIntegral sz)
       return Bound

    -----------------------------------------------------------------------------
    -- Connecting a socket
    --
    -- Make a connection to an already opened socket on a given machine
    -- and port.  assumes that we have already called createSocket,
    -- otherwise it will fail.
    --
    -- This is the dual to $bindSocket$.  The {\em server} process will
    -- usually bind to a port number, the {\em client} will then connect
    -- to the same port number.  Port numbers of user applications are
    -- normally agreed in advance, otherwise we must rely on some meta
    -- protocol for telling the other side what port number we have been
    -- allocated.

    connect :: Socket	-- Unconnected Socket
    	-> SockAddr 	-- Socket address stuff
    	-> IO ()

    connect sock@(MkSocket s _family _stype _protocol socketStatus) addr = do
     modifyMVar_ socketStatus $ \currentStatus -> do
     if currentStatus /= NotConnected
      then
       ioError (userError ("connect: can't peform connect on socket in status " ++
             show currentStatus))
      else do
       withSockAddr addr $ \p_addr sz -> do

       let  connectLoop = do
           	   r <- c_connect s p_addr (fromIntegral sz)
           	   if r == -1
           	       then do

    {-# LINE 696 "Network\Socket.hsc" #-}
    		       rc <- c_getLastError
    		       case rc of
    		         10093 -> do -- WSANOTINITIALISED
    			   withSocketsDo (return ())
    	       	           r <- c_connect s p_addr (fromIntegral sz)
    	       	           if r == -1
    			    then (c_getLastError >>= throwSocketError "connect")
    			    else return r
    			 _ -> throwSocketError "connect" rc

    {-# LINE 706 "Network\Socket.hsc" #-}
           	       else return r

    	connectBlocked = do

    {-# LINE 710 "Network\Socket.hsc" #-}
    	   threadWaitWrite (fromIntegral s)

    {-# LINE 712 "Network\Socket.hsc" #-}
    	   err <- getSocketOption sock SoError
    	   if (err == 0)
    	   	then return 0
    	   	else do ioError (errnoToIOError "connect"
    	   			(Errno (fromIntegral err))
    	   			Nothing Nothing)

       connectLoop
       return Connected

    -----------------------------------------------------------------------------
    -- Listen
    --
    -- The programmer must call $listen$ to tell the system software that
    -- they are now interested in receiving data on this port.  This must
    -- be called on the bound socket before any calls to read or write
    -- data are made.

    -- The programmer also gives a number which indicates the length of
    -- the incoming queue of unread messages for this socket. On most
    -- systems the maximum queue length is around 5.  To remove a message
    -- from the queue for processing a call to $accept$ should be made.

    listen :: Socket  -- Connected & Bound Socket
           -> Int 	  -- Queue Length
           -> IO ()

    listen (MkSocket s _family _stype _protocol socketStatus) backlog = do
     modifyMVar_ socketStatus $ \ status -> do
     if status /= Bound
       then
        ioError (userError ("listen: can't peform listen on socket in status " ++
              show status))
       else do
        throwSocketErrorIfMinus1Retry "listen" (c_listen s (fromIntegral backlog))
        return Listening

    -----------------------------------------------------------------------------
    -- Accept
    --
    -- A call to `accept' only returns when data is available on the given
    -- socket, unless the socket has been set to non-blocking.  It will
    -- return a new socket which should be used to read the incoming data and
    -- should then be closed. Using the socket returned by `accept' allows
    -- incoming requests to be queued on the original socket.

    accept :: Socket			-- Queue Socket
           -> IO (Socket,			-- Readable Socket
    	      SockAddr)			-- Peer details

    accept sock@(MkSocket s family stype protocol status) = do
     currentStatus <- readMVar status
     okay <- sIsAcceptable sock
     if not okay
       then
         ioError (userError ("accept: can't perform accept on socket (" ++ (show (family,stype,protocol)) ++") in status " ++
    	 show currentStatus))
       else do
         let sz = sizeOfSockAddr_Family family
         allocaBytes sz $ \ sockaddr -> do

    {-# LINE 773 "Network\Socket.hsc" #-}
         new_sock <-
    	if threaded
    	   then with (fromIntegral sz) $ \ ptr_len ->
    		  throwErrnoIfMinus1Retry "Network.Socket.accept" $
    		    c_accept_safe s sockaddr ptr_len
    	   else do
         		paramData <- c_newAcceptParams s (fromIntegral sz) sockaddr
         		rc        <- asyncDoProc c_acceptDoProc paramData
         		new_sock  <- c_acceptNewSock    paramData
         		c_free paramData
         		when (rc /= 0)
         		     (ioError (errnoToIOError "Network.Socket.accept" (Errno (fromIntegral rc)) Nothing Nothing))
    		return new_sock

    {-# LINE 798 "Network\Socket.hsc" #-}
         addr <- peekSockAddr sockaddr
         new_status <- newMVar Connected
         return ((MkSocket new_sock family stype protocol new_status), addr)

    {-# LINE 803 "Network\Socket.hsc" #-}
    foreign import ccall unsafe "HsNet.h acceptNewSock"
      c_acceptNewSock :: Ptr () -> IO CInt
    foreign import ccall unsafe "HsNet.h newAcceptParams"
      c_newAcceptParams :: CInt -> CInt -> Ptr a -> IO (Ptr ())
    foreign import ccall unsafe "HsNet.h &acceptDoProc"
      c_acceptDoProc :: FunPtr (Ptr () -> IO Int)
    foreign import ccall unsafe "free"
      c_free:: Ptr a -> IO ()

    {-# LINE 812 "Network\Socket.hsc" #-}

    -----------------------------------------------------------------------------
    -- sendTo & recvFrom

    sendTo :: Socket	-- (possibly) bound/connected Socket
           -> String	-- Data to send
           -> SockAddr
           -> IO Int	-- Number of Bytes sent

    sendTo sock xs addr = do
     withCString xs $ \str -> do
       sendBufTo sock str (length xs) addr

    sendBufTo :: Socket	      -- (possibly) bound/connected Socket
              -> Ptr a -> Int     -- Data to send
              -> SockAddr
              -> IO Int	      -- Number of Bytes sent

    sendBufTo (MkSocket s _family _stype _protocol status) ptr nbytes addr = do
     withSockAddr addr $ \p_addr sz -> do
       liftM fromIntegral $

    {-# LINE 834 "Network\Socket.hsc" #-}
         throwErrnoIfMinus1Retry_repeatOnBlock "sendTo"
    	(threadWaitWrite (fromIntegral s)) $

    {-# LINE 837 "Network\Socket.hsc" #-}
    	c_sendto s ptr (fromIntegral $ nbytes) 0{-flags-}
    			p_addr (fromIntegral sz)

    recvFrom :: Socket -> Int -> IO (String, Int, SockAddr)
    recvFrom sock nbytes =
      allocaBytes nbytes $ \ptr -> do
        (len, sockaddr) <- recvBufFrom sock ptr nbytes
        str <- peekCStringLen (ptr, len)
        return (str, len, sockaddr)

    recvBufFrom :: Socket -> Ptr a -> Int -> IO (Int, SockAddr)
    recvBufFrom sock@(MkSocket s family _stype _protocol status) ptr nbytes
     | nbytes <= 0 = ioError (mkInvalidRecvArgError "Network.Socket.recvFrom")
     | otherwise   =
        withNewSockAddr family $ \ptr_addr sz -> do
          alloca $ \ptr_len -> do
          	poke ptr_len (fromIntegral sz)
            len <-

    {-# LINE 856 "Network\Socket.hsc" #-}
    	       throwErrnoIfMinus1Retry_repeatOnBlock "recvFrom"
            	   (threadWaitRead (fromIntegral s)) $

    {-# LINE 859 "Network\Socket.hsc" #-}
            	   c_recvfrom s ptr (fromIntegral nbytes) 0{-flags-}
    				ptr_addr ptr_len
            let len' = fromIntegral len
    	if len' == 0
    	 then ioError (mkEOFError "Network.Socket.recvFrom")
    	 else do
       	   flg <- sIsConnected sock
    	     -- For at least one implementation (WinSock 2), recvfrom() ignores
    	     -- filling in the sockaddr for connected TCP sockets. Cope with
    	     -- this by using getPeerName instead.
    	   sockaddr <-
    		if flg then
    		   getPeerName sock
    		else
    		   peekSockAddr ptr_addr
               return (len', sockaddr)

    -----------------------------------------------------------------------------
    -- send & recv

    send :: Socket	-- Bound/Connected Socket
         -> String	-- Data to send
         -> IO Int	-- Number of Bytes sent
    send (MkSocket s _family _stype _protocol status) xs = do
     let len = length xs
     withCString xs $ \str -> do
       liftM fromIntegral $

    {-# LINE 887 "Network\Socket.hsc" #-}
          writeRawBufferPtr "Network.Socket.send" (fromIntegral s) True str 0
    		(fromIntegral len)

    {-# LINE 896 "Network\Socket.hsc" #-}

    recv :: Socket -> Int -> IO String
    recv sock l = recvLen sock l >>= \ (s,_) -> return s

    recvLen :: Socket -> Int -> IO (String, Int)
    recvLen sock@(MkSocket s _family _stype _protocol status) nbytes
     | nbytes <= 0 = ioError (mkInvalidRecvArgError "Network.Socket.recv")
     | otherwise   = do
         allocaBytes nbytes $ \ptr -> do
            len <-

    {-# LINE 907 "Network\Socket.hsc" #-}
    	  readRawBufferPtr "Network.Socket.recvLen" (fromIntegral s) True ptr 0
    		 (fromIntegral nbytes)

    {-# LINE 916 "Network\Socket.hsc" #-}
            let len' = fromIntegral len
    	if len' == 0
    	 then ioError (mkEOFError "Network.Socket.recv")
    	 else do
    	   s <- peekCStringLen (ptr,len')
    	   return (s, len')

    -- ---------------------------------------------------------------------------
    -- socketPort
    --
    -- The port number the given socket is currently connected to can be
    -- determined by calling $port$, is generally only useful when bind
    -- was given $aNY\_PORT$.

    socketPort :: Socket		-- Connected & Bound Socket
    	   -> IO PortNumber	-- Port Number of Socket
    socketPort sock@(MkSocket _ AF_INET _ _ _) = do
        (SockAddrInet port _) <- getSocketName sock
        return port

    {-# LINE 940 "Network\Socket.hsc" #-}
    socketPort (MkSocket _ family _ _ _) =
        ioError (userError ("socketPort: not supported for Family " ++ show family))

    -- ---------------------------------------------------------------------------
    -- getPeerName

    -- Calling $getPeerName$ returns the address details of the machine,
    -- other than the local one, which is connected to the socket. This is
    -- used in programs such as FTP to determine where to send the
    -- returning data.  The corresponding call to get the details of the
    -- local machine is $getSocketName$.

    getPeerName   :: Socket -> IO SockAddr
    getPeerName (MkSocket s family _ _ _) = do
     withNewSockAddr family $ \ptr sz -> do
       with (fromIntegral sz) $ \int_star -> do
       throwSocketErrorIfMinus1Retry "getPeerName" $ c_getpeername s ptr int_star
       sz <- peek int_star
       peekSockAddr ptr

    getSocketName :: Socket -> IO SockAddr
    getSocketName (MkSocket s family _ _ _) = do
     withNewSockAddr family $ \ptr sz -> do
       with (fromIntegral sz) $ \int_star -> do
       throwSocketErrorIfMinus1Retry "getSocketName" $ c_getsockname s ptr int_star
       peekSockAddr ptr

    -----------------------------------------------------------------------------
    -- Socket Properties

    data SocketOption
        = DummySocketOption__

    {-# LINE 974 "Network\Socket.hsc" #-}
        | Debug         {- SO_DEBUG     -}

    {-# LINE 976 "Network\Socket.hsc" #-}

    {-# LINE 977 "Network\Socket.hsc" #-}
        | ReuseAddr     {- SO_REUSEADDR -}

    {-# LINE 979 "Network\Socket.hsc" #-}

    {-# LINE 980 "Network\Socket.hsc" #-}
        | Type          {- SO_TYPE      -}

    {-# LINE 982 "Network\Socket.hsc" #-}

    {-# LINE 983 "Network\Socket.hsc" #-}
        | SoError       {- SO_ERROR     -}

    {-# LINE 985 "Network\Socket.hsc" #-}

    {-# LINE 986 "Network\Socket.hsc" #-}
        | DontRoute     {- SO_DONTROUTE -}

    {-# LINE 988 "Network\Socket.hsc" #-}

    {-# LINE 989 "Network\Socket.hsc" #-}
        | Broadcast     {- SO_BROADCAST -}

    {-# LINE 991 "Network\Socket.hsc" #-}

    {-# LINE 992 "Network\Socket.hsc" #-}
        | SendBuffer    {- SO_SNDBUF    -}

    {-# LINE 994 "Network\Socket.hsc" #-}

    {-# LINE 995 "Network\Socket.hsc" #-}
        | RecvBuffer    {- SO_RCVBUF    -}

    {-# LINE 997 "Network\Socket.hsc" #-}

    {-# LINE 998 "Network\Socket.hsc" #-}
        | KeepAlive     {- SO_KEEPALIVE -}

    {-# LINE 1000 "Network\Socket.hsc" #-}

    {-# LINE 1001 "Network\Socket.hsc" #-}
        | OOBInline     {- SO_OOBINLINE -}

    {-# LINE 1003 "Network\Socket.hsc" #-}

    {-# LINE 1006 "Network\Socket.hsc" #-}

    {-# LINE 1009 "Network\Socket.hsc" #-}

    {-# LINE 1010 "Network\Socket.hsc" #-}
        | NoDelay       {- TCP_NODELAY  -}

    {-# LINE 1012 "Network\Socket.hsc" #-}

    {-# LINE 1013 "Network\Socket.hsc" #-}
        | Linger        {- SO_LINGER    -}

    {-# LINE 1015 "Network\Socket.hsc" #-}

    {-# LINE 1018 "Network\Socket.hsc" #-}

    {-# LINE 1019 "Network\Socket.hsc" #-}
        | RecvLowWater  {- SO_RCVLOWAT  -}

    {-# LINE 1021 "Network\Socket.hsc" #-}

    {-# LINE 1022 "Network\Socket.hsc" #-}
        | SendLowWater  {- SO_SNDLOWAT  -}

    {-# LINE 1024 "Network\Socket.hsc" #-}

    {-# LINE 1025 "Network\Socket.hsc" #-}
        | RecvTimeOut   {- SO_RCVTIMEO  -}

    {-# LINE 1027 "Network\Socket.hsc" #-}

    {-# LINE 1028 "Network\Socket.hsc" #-}
        | SendTimeOut   {- SO_SNDTIMEO  -}

    {-# LINE 1030 "Network\Socket.hsc" #-}

    {-# LINE 1031 "Network\Socket.hsc" #-}
        | UseLoopBack   {- SO_USELOOPBACK -}

    {-# LINE 1033 "Network\Socket.hsc" #-}

    INSTANCE_TYPEABLE0(SocketOption,socketOptionTc,"SocketOption")

    socketOptLevel :: SocketOption -> CInt
    socketOptLevel so =
      case so of

    {-# LINE 1042 "Network\Socket.hsc" #-}

    {-# LINE 1045 "Network\Socket.hsc" #-}

    {-# LINE 1046 "Network\Socket.hsc" #-}
        NoDelay      -> 6
    {-# LINE 1047 "Network\Socket.hsc" #-}

    {-# LINE 1048 "Network\Socket.hsc" #-}
        _            -> 65535
    {-# LINE 1049 "Network\Socket.hsc" #-}

    packSocketOption :: SocketOption -> CInt
    packSocketOption so =
      case so of

    {-# LINE 1054 "Network\Socket.hsc" #-}
        Debug         -> 1
    {-# LINE 1055 "Network\Socket.hsc" #-}

    {-# LINE 1056 "Network\Socket.hsc" #-}

    {-# LINE 1057 "Network\Socket.hsc" #-}
        ReuseAddr     -> 4
    {-# LINE 1058 "Network\Socket.hsc" #-}

    {-# LINE 1059 "Network\Socket.hsc" #-}

    {-# LINE 1060 "Network\Socket.hsc" #-}
        Type          -> 4104
    {-# LINE 1061 "Network\Socket.hsc" #-}

    {-# LINE 1062 "Network\Socket.hsc" #-}

    {-# LINE 1063 "Network\Socket.hsc" #-}
        SoError       -> 4103
    {-# LINE 1064 "Network\Socket.hsc" #-}

    {-# LINE 1065 "Network\Socket.hsc" #-}

    {-# LINE 1066 "Network\Socket.hsc" #-}
        DontRoute     -> 16
    {-# LINE 1067 "Network\Socket.hsc" #-}

    {-# LINE 1068 "Network\Socket.hsc" #-}

    {-# LINE 1069 "Network\Socket.hsc" #-}
        Broadcast     -> 32
    {-# LINE 1070 "Network\Socket.hsc" #-}

    {-# LINE 1071 "Network\Socket.hsc" #-}

    {-# LINE 1072 "Network\Socket.hsc" #-}
        SendBuffer    -> 4097
    {-# LINE 1073 "Network\Socket.hsc" #-}

    {-# LINE 1074 "Network\Socket.hsc" #-}

    {-# LINE 1075 "Network\Socket.hsc" #-}
        RecvBuffer    -> 4098
    {-# LINE 1076 "Network\Socket.hsc" #-}

    {-# LINE 1077 "Network\Socket.hsc" #-}

    {-# LINE 1078 "Network\Socket.hsc" #-}
        KeepAlive     -> 8
    {-# LINE 1079 "Network\Socket.hsc" #-}

    {-# LINE 1080 "Network\Socket.hsc" #-}

    {-# LINE 1081 "Network\Socket.hsc" #-}
        OOBInline     -> 256
    {-# LINE 1082 "Network\Socket.hsc" #-}

    {-# LINE 1083 "Network\Socket.hsc" #-}

    {-# LINE 1086 "Network\Socket.hsc" #-}

    {-# LINE 1089 "Network\Socket.hsc" #-}

    {-# LINE 1090 "Network\Socket.hsc" #-}
        NoDelay       -> 1
    {-# LINE 1091 "Network\Socket.hsc" #-}

    {-# LINE 1092 "Network\Socket.hsc" #-}

    {-# LINE 1093 "Network\Socket.hsc" #-}
        Linger	  -> 128
    {-# LINE 1094 "Network\Socket.hsc" #-}

    {-# LINE 1095 "Network\Socket.hsc" #-}

    {-# LINE 1098 "Network\Socket.hsc" #-}

    {-# LINE 1099 "Network\Socket.hsc" #-}
        RecvLowWater  -> 4100
    {-# LINE 1100 "Network\Socket.hsc" #-}

    {-# LINE 1101 "Network\Socket.hsc" #-}

    {-# LINE 1102 "Network\Socket.hsc" #-}
        SendLowWater  -> 4099
    {-# LINE 1103 "Network\Socket.hsc" #-}

    {-# LINE 1104 "Network\Socket.hsc" #-}

    {-# LINE 1105 "Network\Socket.hsc" #-}
        RecvTimeOut   -> 4102
    {-# LINE 1106 "Network\Socket.hsc" #-}

    {-# LINE 1107 "Network\Socket.hsc" #-}

    {-# LINE 1108 "Network\Socket.hsc" #-}
        SendTimeOut   -> 4101
    {-# LINE 1109 "Network\Socket.hsc" #-}

    {-# LINE 1110 "Network\Socket.hsc" #-}

    {-# LINE 1111 "Network\Socket.hsc" #-}
        UseLoopBack   -> 64
    {-# LINE 1112 "Network\Socket.hsc" #-}

    {-# LINE 1113 "Network\Socket.hsc" #-}

    setSocketOption :: Socket
    		-> SocketOption -- Option Name
    		-> Int		-- Option Value
    		-> IO ()
    setSocketOption (MkSocket s _ _ _ _) so v = do
       with (fromIntegral v) $ \ptr_v -> do
       throwErrnoIfMinus1_ "setSocketOption" $
           c_setsockopt s (socketOptLevel so) (packSocketOption so) ptr_v
    	  (fromIntegral (sizeOf v))
       return ()

    getSocketOption :: Socket
    		-> SocketOption  -- Option Name
    		-> IO Int	 -- Option Value
    getSocketOption (MkSocket s _ _ _ _) so = do
       alloca $ \ptr_v ->
         with (fromIntegral (sizeOf (undefined :: CInt))) $ \ptr_sz -> do
           throwErrnoIfMinus1 "getSocketOption" $
    	 c_getsockopt s (socketOptLevel so) (packSocketOption so) ptr_v ptr_sz
           fromIntegral `liftM` peek ptr_v

    {-# LINE 1155 "Network\Socket.hsc" #-}

    {-# LINE 1236 "Network\Socket.hsc" #-}

    {-
    A calling sequence table for the main functions is shown in the table below.

    \begin{figure}[h]
    \begin{center}
    \begin{tabular}{|l|c|c|c|c|c|c|c|}d
    \hline
    {\bf A Call to} & socket & connect & bindSocket & listen & accept & read & write \\
    \hline
    {\bf Precedes} & & & & & & & \\
    \hline
    socket &	&	  &	       &	&	 &	& \\
    \hline
    connect & +	&	  &	       &	&	 &	& \\
    \hline
    bindSocket & +	&	  &	       &	&	 &	& \\
    \hline
    listen &	&	  & +	       &	&	 &	& \\
    \hline
    accept &	&	  &	       &  +	&	 &	& \\
    \hline
    read   &	&   +	  &	       &  +	&  +	 &  +	& + \\
    \hline
    write  &	&   +	  &	       &  +	&  +	 &  +	& + \\
    \hline
    \end{tabular}
    \caption{Sequence Table for Major functions of Socket}
    \label{tab:api-seq}
    \end{center}
    \end{figure}
    -}

    -- ---------------------------------------------------------------------------
    -- OS Dependent Definitions

    unpackFamily	:: CInt -> Family
    packFamily	:: Family -> CInt

    packSocketType	:: SocketType -> CInt
    unpackSocketType:: CInt -> SocketType

    -- | Address Families.
    --
    -- This data type might have different constructors depending on what is
    -- supported by the operating system.
    data Family
    	= AF_UNSPEC	-- unspecified

    {-# LINE 1286 "Network\Socket.hsc" #-}
    	| AF_UNIX	-- local to host (pipes, portals

    {-# LINE 1288 "Network\Socket.hsc" #-}

    {-# LINE 1289 "Network\Socket.hsc" #-}
    	| AF_INET	-- internetwork: UDP, TCP, etc

    {-# LINE 1291 "Network\Socket.hsc" #-}

    {-# LINE 1292 "Network\Socket.hsc" #-}
            | AF_INET6	-- Internet Protocol version 6

    {-# LINE 1294 "Network\Socket.hsc" #-}

    {-# LINE 1295 "Network\Socket.hsc" #-}
    	| AF_IMPLINK	-- arpanet imp addresses

    {-# LINE 1297 "Network\Socket.hsc" #-}

    {-# LINE 1298 "Network\Socket.hsc" #-}
    	| AF_PUP	-- pup protocols: e.g. BSP

    {-# LINE 1300 "Network\Socket.hsc" #-}

    {-# LINE 1301 "Network\Socket.hsc" #-}
    	| AF_CHAOS	-- mit CHAOS protocols

    {-# LINE 1303 "Network\Socket.hsc" #-}

    {-# LINE 1304 "Network\Socket.hsc" #-}
    	| AF_NS		-- XEROX NS protocols

    {-# LINE 1306 "Network\Socket.hsc" #-}

    {-# LINE 1309 "Network\Socket.hsc" #-}

    {-# LINE 1310 "Network\Socket.hsc" #-}
    	| AF_ECMA	-- european computer manufacturers

    {-# LINE 1312 "Network\Socket.hsc" #-}

    {-# LINE 1313 "Network\Socket.hsc" #-}
    	| AF_DATAKIT	-- datakit protocols

    {-# LINE 1315 "Network\Socket.hsc" #-}

    {-# LINE 1316 "Network\Socket.hsc" #-}
    	| AF_CCITT	-- CCITT protocols, X.25 etc

    {-# LINE 1318 "Network\Socket.hsc" #-}

    {-# LINE 1319 "Network\Socket.hsc" #-}
    	| AF_SNA	-- IBM SNA

    {-# LINE 1321 "Network\Socket.hsc" #-}

    {-# LINE 1322 "Network\Socket.hsc" #-}
    	| AF_DECnet	-- DECnet

    {-# LINE 1324 "Network\Socket.hsc" #-}

    {-# LINE 1325 "Network\Socket.hsc" #-}
    	| AF_DLI	-- Direct data link interface

    {-# LINE 1327 "Network\Socket.hsc" #-}

    {-# LINE 1328 "Network\Socket.hsc" #-}
    	| AF_LAT	-- LAT

    {-# LINE 1330 "Network\Socket.hsc" #-}

    {-# LINE 1331 "Network\Socket.hsc" #-}
    	| AF_HYLINK	-- NSC Hyperchannel

    {-# LINE 1333 "Network\Socket.hsc" #-}

    {-# LINE 1334 "Network\Socket.hsc" #-}
    	| AF_APPLETALK	-- Apple Talk

    {-# LINE 1336 "Network\Socket.hsc" #-}

    {-# LINE 1339 "Network\Socket.hsc" #-}

    {-# LINE 1340 "Network\Socket.hsc" #-}
    	| AF_NETBIOS	-- NetBios-style addresses

    {-# LINE 1342 "Network\Socket.hsc" #-}

    {-# LINE 1345 "Network\Socket.hsc" #-}

    {-# LINE 1348 "Network\Socket.hsc" #-}

    {-# LINE 1349 "Network\Socket.hsc" #-}
    	| AF_ISO	-- ISO protocols

    {-# LINE 1351 "Network\Socket.hsc" #-}

    {-# LINE 1352 "Network\Socket.hsc" #-}
    	| AF_OSI	-- umbrella of all families used by OSI

    {-# LINE 1354 "Network\Socket.hsc" #-}

    {-# LINE 1357 "Network\Socket.hsc" #-}

    {-# LINE 1360 "Network\Socket.hsc" #-}

    {-# LINE 1363 "Network\Socket.hsc" #-}

    {-# LINE 1366 "Network\Socket.hsc" #-}

    {-# LINE 1369 "Network\Socket.hsc" #-}

    {-# LINE 1370 "Network\Socket.hsc" #-}
    	| AF_IPX	-- Novell Internet Protocol

    {-# LINE 1372 "Network\Socket.hsc" #-}

    {-# LINE 1375 "Network\Socket.hsc" #-}

    {-# LINE 1378 "Network\Socket.hsc" #-}

    {-# LINE 1381 "Network\Socket.hsc" #-}

    {-# LINE 1384 "Network\Socket.hsc" #-}

    {-# LINE 1387 "Network\Socket.hsc" #-}

    {-# LINE 1390 "Network\Socket.hsc" #-}

    {-# LINE 1393 "Network\Socket.hsc" #-}

    {-# LINE 1396 "Network\Socket.hsc" #-}

    {-# LINE 1399 "Network\Socket.hsc" #-}

    {-# LINE 1402 "Network\Socket.hsc" #-}

    {-# LINE 1405 "Network\Socket.hsc" #-}

    {-# LINE 1408 "Network\Socket.hsc" #-}

    {-# LINE 1411 "Network\Socket.hsc" #-}

    {-# LINE 1414 "Network\Socket.hsc" #-}

    {-# LINE 1417 "Network\Socket.hsc" #-}

    {-# LINE 1420 "Network\Socket.hsc" #-}

    {-# LINE 1423 "Network\Socket.hsc" #-}

    {-# LINE 1426 "Network\Socket.hsc" #-}

    {-# LINE 1429 "Network\Socket.hsc" #-}

    {-# LINE 1432 "Network\Socket.hsc" #-}

    {-# LINE 1435 "Network\Socket.hsc" #-}

    {-# LINE 1438 "Network\Socket.hsc" #-}

    {-# LINE 1441 "Network\Socket.hsc" #-}

    {-# LINE 1444 "Network\Socket.hsc" #-}

    {-# LINE 1447 "Network\Socket.hsc" #-}

    {-# LINE 1450 "Network\Socket.hsc" #-}

    {-# LINE 1453 "Network\Socket.hsc" #-}

    {-# LINE 1456 "Network\Socket.hsc" #-}

    {-# LINE 1459 "Network\Socket.hsc" #-}

    {-# LINE 1462 "Network\Socket.hsc" #-}

    {-# LINE 1465 "Network\Socket.hsc" #-}

    {-# LINE 1468 "Network\Socket.hsc" #-}

    {-# LINE 1471 "Network\Socket.hsc" #-}

    {-# LINE 1474 "Network\Socket.hsc" #-}

    {-# LINE 1477 "Network\Socket.hsc" #-}
    	deriving (Eq, Ord, Read, Show)

    ------ ------

    packFamily f = case f of
    	AF_UNSPEC -> 0
    {-# LINE 1483 "Network\Socket.hsc" #-}

    {-# LINE 1484 "Network\Socket.hsc" #-}
    	AF_UNIX -> 1
    {-# LINE 1485 "Network\Socket.hsc" #-}

    {-# LINE 1486 "Network\Socket.hsc" #-}

    {-# LINE 1487 "Network\Socket.hsc" #-}
    	AF_INET -> 2
    {-# LINE 1488 "Network\Socket.hsc" #-}

    {-# LINE 1489 "Network\Socket.hsc" #-}

    {-# LINE 1490 "Network\Socket.hsc" #-}
            AF_INET6 -> 23
    {-# LINE 1491 "Network\Socket.hsc" #-}

    {-# LINE 1492 "Network\Socket.hsc" #-}

    {-# LINE 1493 "Network\Socket.hsc" #-}
    	AF_IMPLINK -> 3
    {-# LINE 1494 "Network\Socket.hsc" #-}

    {-# LINE 1495 "Network\Socket.hsc" #-}

    {-# LINE 1496 "Network\Socket.hsc" #-}
    	AF_PUP -> 4
    {-# LINE 1497 "Network\Socket.hsc" #-}

    {-# LINE 1498 "Network\Socket.hsc" #-}

    {-# LINE 1499 "Network\Socket.hsc" #-}
    	AF_CHAOS -> 5
    {-# LINE 1500 "Network\Socket.hsc" #-}

    {-# LINE 1501 "Network\Socket.hsc" #-}

    {-# LINE 1502 "Network\Socket.hsc" #-}
    	AF_NS -> 6
    {-# LINE 1503 "Network\Socket.hsc" #-}

    {-# LINE 1504 "Network\Socket.hsc" #-}

    {-# LINE 1507 "Network\Socket.hsc" #-}

    {-# LINE 1508 "Network\Socket.hsc" #-}
    	AF_ECMA -> 8
    {-# LINE 1509 "Network\Socket.hsc" #-}

    {-# LINE 1510 "Network\Socket.hsc" #-}

    {-# LINE 1511 "Network\Socket.hsc" #-}
    	AF_DATAKIT -> 9
    {-# LINE 1512 "Network\Socket.hsc" #-}

    {-# LINE 1513 "Network\Socket.hsc" #-}

    {-# LINE 1514 "Network\Socket.hsc" #-}
    	AF_CCITT -> 10
    {-# LINE 1515 "Network\Socket.hsc" #-}

    {-# LINE 1516 "Network\Socket.hsc" #-}

    {-# LINE 1517 "Network\Socket.hsc" #-}
    	AF_SNA -> 11
    {-# LINE 1518 "Network\Socket.hsc" #-}

    {-# LINE 1519 "Network\Socket.hsc" #-}

    {-# LINE 1520 "Network\Socket.hsc" #-}
    	AF_DECnet -> 12
    {-# LINE 1521 "Network\Socket.hsc" #-}

    {-# LINE 1522 "Network\Socket.hsc" #-}

    {-# LINE 1523 "Network\Socket.hsc" #-}
    	AF_DLI -> 13
    {-# LINE 1524 "Network\Socket.hsc" #-}

    {-# LINE 1525 "Network\Socket.hsc" #-}

    {-# LINE 1526 "Network\Socket.hsc" #-}
    	AF_LAT -> 14
    {-# LINE 1527 "Network\Socket.hsc" #-}

    {-# LINE 1528 "Network\Socket.hsc" #-}

    {-# LINE 1529 "Network\Socket.hsc" #-}
    	AF_HYLINK -> 15
    {-# LINE 1530 "Network\Socket.hsc" #-}

    {-# LINE 1531 "Network\Socket.hsc" #-}

    {-# LINE 1532 "Network\Socket.hsc" #-}
    	AF_APPLETALK -> 16
    {-# LINE 1533 "Network\Socket.hsc" #-}

    {-# LINE 1534 "Network\Socket.hsc" #-}

    {-# LINE 1537 "Network\Socket.hsc" #-}

    {-# LINE 1538 "Network\Socket.hsc" #-}
    	AF_NETBIOS -> 17
    {-# LINE 1539 "Network\Socket.hsc" #-}

    {-# LINE 1540 "Network\Socket.hsc" #-}

    {-# LINE 1543 "Network\Socket.hsc" #-}

    {-# LINE 1546 "Network\Socket.hsc" #-}

    {-# LINE 1547 "Network\Socket.hsc" #-}
    	AF_ISO -> 7
    {-# LINE 1548 "Network\Socket.hsc" #-}

    {-# LINE 1549 "Network\Socket.hsc" #-}

    {-# LINE 1550 "Network\Socket.hsc" #-}
    	AF_OSI -> 7
    {-# LINE 1551 "Network\Socket.hsc" #-}

    {-# LINE 1552 "Network\Socket.hsc" #-}

    {-# LINE 1555 "Network\Socket.hsc" #-}

    {-# LINE 1558 "Network\Socket.hsc" #-}

    {-# LINE 1561 "Network\Socket.hsc" #-}

    {-# LINE 1564 "Network\Socket.hsc" #-}

    {-# LINE 1567 "Network\Socket.hsc" #-}

    {-# LINE 1568 "Network\Socket.hsc" #-}
    	AF_IPX -> 6
    {-# LINE 1569 "Network\Socket.hsc" #-}

    {-# LINE 1570 "Network\Socket.hsc" #-}

    {-# LINE 1573 "Network\Socket.hsc" #-}

    {-# LINE 1576 "Network\Socket.hsc" #-}

    {-# LINE 1579 "Network\Socket.hsc" #-}

    {-# LINE 1582 "Network\Socket.hsc" #-}

    {-# LINE 1585 "Network\Socket.hsc" #-}

    {-# LINE 1588 "Network\Socket.hsc" #-}

    {-# LINE 1591 "Network\Socket.hsc" #-}

    {-# LINE 1594 "Network\Socket.hsc" #-}

    {-# LINE 1597 "Network\Socket.hsc" #-}

    {-# LINE 1600 "Network\Socket.hsc" #-}

    {-# LINE 1603 "Network\Socket.hsc" #-}

    {-# LINE 1606 "Network\Socket.hsc" #-}

    {-# LINE 1609 "Network\Socket.hsc" #-}

    {-# LINE 1612 "Network\Socket.hsc" #-}

    {-# LINE 1615 "Network\Socket.hsc" #-}

    {-# LINE 1618 "Network\Socket.hsc" #-}

    {-# LINE 1621 "Network\Socket.hsc" #-}

    {-# LINE 1624 "Network\Socket.hsc" #-}

    {-# LINE 1627 "Network\Socket.hsc" #-}

    {-# LINE 1630 "Network\Socket.hsc" #-}

    {-# LINE 1633 "Network\Socket.hsc" #-}

    {-# LINE 1636 "Network\Socket.hsc" #-}

    {-# LINE 1639 "Network\Socket.hsc" #-}

    {-# LINE 1642 "Network\Socket.hsc" #-}

    {-# LINE 1645 "Network\Socket.hsc" #-}

    {-# LINE 1648 "Network\Socket.hsc" #-}

    {-# LINE 1651 "Network\Socket.hsc" #-}

    {-# LINE 1654 "Network\Socket.hsc" #-}

    {-# LINE 1657 "Network\Socket.hsc" #-}

    {-# LINE 1660 "Network\Socket.hsc" #-}

    {-# LINE 1663 "Network\Socket.hsc" #-}

    {-# LINE 1666 "Network\Socket.hsc" #-}

    {-# LINE 1669 "Network\Socket.hsc" #-}

    {-# LINE 1672 "Network\Socket.hsc" #-}

    {-# LINE 1675 "Network\Socket.hsc" #-}

    --------- ----------

    unpackFamily f = case f of
    	(0) -> AF_UNSPEC
    {-# LINE 1680 "Network\Socket.hsc" #-}

    {-# LINE 1681 "Network\Socket.hsc" #-}
    	(1) -> AF_UNIX
    {-# LINE 1682 "Network\Socket.hsc" #-}

    {-# LINE 1683 "Network\Socket.hsc" #-}

    {-# LINE 1684 "Network\Socket.hsc" #-}
    	(2) -> AF_INET
    {-# LINE 1685 "Network\Socket.hsc" #-}

    {-# LINE 1686 "Network\Socket.hsc" #-}

    {-# LINE 1687 "Network\Socket.hsc" #-}
            (23) -> AF_INET6
    {-# LINE 1688 "Network\Socket.hsc" #-}

    {-# LINE 1689 "Network\Socket.hsc" #-}

    {-# LINE 1690 "Network\Socket.hsc" #-}
    	(3) -> AF_IMPLINK
    {-# LINE 1691 "Network\Socket.hsc" #-}

    {-# LINE 1692 "Network\Socket.hsc" #-}

    {-# LINE 1693 "Network\Socket.hsc" #-}
    	(4) -> AF_PUP
    {-# LINE 1694 "Network\Socket.hsc" #-}

    {-# LINE 1695 "Network\Socket.hsc" #-}

    {-# LINE 1696 "Network\Socket.hsc" #-}
    	(5) -> AF_CHAOS
    {-# LINE 1697 "Network\Socket.hsc" #-}

    {-# LINE 1698 "Network\Socket.hsc" #-}

    {-# LINE 1699 "Network\Socket.hsc" #-}
    	(6) -> AF_NS
    {-# LINE 1700 "Network\Socket.hsc" #-}

    {-# LINE 1701 "Network\Socket.hsc" #-}

    {-# LINE 1704 "Network\Socket.hsc" #-}

    {-# LINE 1705 "Network\Socket.hsc" #-}
    	(8) -> AF_ECMA
    {-# LINE 1706 "Network\Socket.hsc" #-}

    {-# LINE 1707 "Network\Socket.hsc" #-}

    {-# LINE 1708 "Network\Socket.hsc" #-}
    	(9) -> AF_DATAKIT
    {-# LINE 1709 "Network\Socket.hsc" #-}

    {-# LINE 1710 "Network\Socket.hsc" #-}

    {-# LINE 1711 "Network\Socket.hsc" #-}
    	(10) -> AF_CCITT
    {-# LINE 1712 "Network\Socket.hsc" #-}

    {-# LINE 1713 "Network\Socket.hsc" #-}

    {-# LINE 1714 "Network\Socket.hsc" #-}
    	(11) -> AF_SNA
    {-# LINE 1715 "Network\Socket.hsc" #-}

    {-# LINE 1716 "Network\Socket.hsc" #-}

    {-# LINE 1717 "Network\Socket.hsc" #-}
    	(12) -> AF_DECnet
    {-# LINE 1718 "Network\Socket.hsc" #-}

    {-# LINE 1719 "Network\Socket.hsc" #-}

    {-# LINE 1720 "Network\Socket.hsc" #-}
    	(13) -> AF_DLI
    {-# LINE 1721 "Network\Socket.hsc" #-}

    {-# LINE 1722 "Network\Socket.hsc" #-}

    {-# LINE 1723 "Network\Socket.hsc" #-}
    	(14) -> AF_LAT
    {-# LINE 1724 "Network\Socket.hsc" #-}

    {-# LINE 1725 "Network\Socket.hsc" #-}

    {-# LINE 1726 "Network\Socket.hsc" #-}
    	(15) -> AF_HYLINK
    {-# LINE 1727 "Network\Socket.hsc" #-}

    {-# LINE 1728 "Network\Socket.hsc" #-}

    {-# LINE 1729 "Network\Socket.hsc" #-}
    	(16) -> AF_APPLETALK
    {-# LINE 1730 "Network\Socket.hsc" #-}

    {-# LINE 1731 "Network\Socket.hsc" #-}

    {-# LINE 1734 "Network\Socket.hsc" #-}

    {-# LINE 1735 "Network\Socket.hsc" #-}
    	(17) -> AF_NETBIOS
    {-# LINE 1736 "Network\Socket.hsc" #-}

    {-# LINE 1737 "Network\Socket.hsc" #-}

    {-# LINE 1740 "Network\Socket.hsc" #-}

    {-# LINE 1743 "Network\Socket.hsc" #-}

    {-# LINE 1744 "Network\Socket.hsc" #-}
    	(7) -> AF_ISO
    {-# LINE 1745 "Network\Socket.hsc" #-}

    {-# LINE 1746 "Network\Socket.hsc" #-}

    {-# LINE 1747 "Network\Socket.hsc" #-}

    {-# LINE 1750 "Network\Socket.hsc" #-}

    {-# LINE 1751 "Network\Socket.hsc" #-}

    {-# LINE 1754 "Network\Socket.hsc" #-}

    {-# LINE 1757 "Network\Socket.hsc" #-}

    {-# LINE 1760 "Network\Socket.hsc" #-}

    {-# LINE 1763 "Network\Socket.hsc" #-}

    {-# LINE 1766 "Network\Socket.hsc" #-}

    {-# LINE 1767 "Network\Socket.hsc" #-}
    	(6) -> AF_IPX
    {-# LINE 1768 "Network\Socket.hsc" #-}

    {-# LINE 1769 "Network\Socket.hsc" #-}

    {-# LINE 1772 "Network\Socket.hsc" #-}

    {-# LINE 1775 "Network\Socket.hsc" #-}

    {-# LINE 1778 "Network\Socket.hsc" #-}

    {-# LINE 1781 "Network\Socket.hsc" #-}

    {-# LINE 1784 "Network\Socket.hsc" #-}

    {-# LINE 1787 "Network\Socket.hsc" #-}

    {-# LINE 1790 "Network\Socket.hsc" #-}

    {-# LINE 1793 "Network\Socket.hsc" #-}

    {-# LINE 1796 "Network\Socket.hsc" #-}

    {-# LINE 1799 "Network\Socket.hsc" #-}

    {-# LINE 1802 "Network\Socket.hsc" #-}

    {-# LINE 1805 "Network\Socket.hsc" #-}

    {-# LINE 1808 "Network\Socket.hsc" #-}

    {-# LINE 1811 "Network\Socket.hsc" #-}

    {-# LINE 1814 "Network\Socket.hsc" #-}

    {-# LINE 1817 "Network\Socket.hsc" #-}

    {-# LINE 1820 "Network\Socket.hsc" #-}

    {-# LINE 1823 "Network\Socket.hsc" #-}

    {-# LINE 1826 "Network\Socket.hsc" #-}

    {-# LINE 1829 "Network\Socket.hsc" #-}

    {-# LINE 1832 "Network\Socket.hsc" #-}

    {-# LINE 1835 "Network\Socket.hsc" #-}

    {-# LINE 1838 "Network\Socket.hsc" #-}

    {-# LINE 1841 "Network\Socket.hsc" #-}

    {-# LINE 1844 "Network\Socket.hsc" #-}

    {-# LINE 1847 "Network\Socket.hsc" #-}

    {-# LINE 1850 "Network\Socket.hsc" #-}

    {-# LINE 1853 "Network\Socket.hsc" #-}

    {-# LINE 1856 "Network\Socket.hsc" #-}

    {-# LINE 1859 "Network\Socket.hsc" #-}

    {-# LINE 1862 "Network\Socket.hsc" #-}

    {-# LINE 1865 "Network\Socket.hsc" #-}

    {-# LINE 1868 "Network\Socket.hsc" #-}

    {-# LINE 1871 "Network\Socket.hsc" #-}

    {-# LINE 1874 "Network\Socket.hsc" #-}

    -- Socket Types.

    -- | Socket Types.
    --
    -- This data type might have different constructors depending on what is
    -- supported by the operating system.
    data SocketType
    	= NoSocketType

    {-# LINE 1884 "Network\Socket.hsc" #-}
    	| Stream

    {-# LINE 1886 "Network\Socket.hsc" #-}

    {-# LINE 1887 "Network\Socket.hsc" #-}
    	| Datagram

    {-# LINE 1889 "Network\Socket.hsc" #-}

    {-# LINE 1890 "Network\Socket.hsc" #-}
    	| Raw

    {-# LINE 1892 "Network\Socket.hsc" #-}

    {-# LINE 1893 "Network\Socket.hsc" #-}
    	| RDM

    {-# LINE 1895 "Network\Socket.hsc" #-}

    {-# LINE 1896 "Network\Socket.hsc" #-}
    	| SeqPacket

    {-# LINE 1898 "Network\Socket.hsc" #-}
    	deriving (Eq, Ord, Read, Show)

    INSTANCE_TYPEABLE0(SocketType,socketTypeTc,"SocketType")

    packSocketType stype = case stype of
    	NoSocketType -> 0

    {-# LINE 1905 "Network\Socket.hsc" #-}
    	Stream -> 1
    {-# LINE 1906 "Network\Socket.hsc" #-}

    {-# LINE 1907 "Network\Socket.hsc" #-}

    {-# LINE 1908 "Network\Socket.hsc" #-}
    	Datagram -> 2
    {-# LINE 1909 "Network\Socket.hsc" #-}

    {-# LINE 1910 "Network\Socket.hsc" #-}

    {-# LINE 1911 "Network\Socket.hsc" #-}
    	Raw -> 3
    {-# LINE 1912 "Network\Socket.hsc" #-}

    {-# LINE 1913 "Network\Socket.hsc" #-}

    {-# LINE 1914 "Network\Socket.hsc" #-}
    	RDM -> 4
    {-# LINE 1915 "Network\Socket.hsc" #-}

    {-# LINE 1916 "Network\Socket.hsc" #-}

    {-# LINE 1917 "Network\Socket.hsc" #-}
    	SeqPacket -> 5
    {-# LINE 1918 "Network\Socket.hsc" #-}

    {-# LINE 1919 "Network\Socket.hsc" #-}

    unpackSocketType t = case t of
    	0 -> NoSocketType

    {-# LINE 1923 "Network\Socket.hsc" #-}
    	(1) -> Stream
    {-# LINE 1924 "Network\Socket.hsc" #-}

    {-# LINE 1925 "Network\Socket.hsc" #-}

    {-# LINE 1926 "Network\Socket.hsc" #-}
    	(2) -> Datagram
    {-# LINE 1927 "Network\Socket.hsc" #-}

    {-# LINE 1928 "Network\Socket.hsc" #-}

    {-# LINE 1929 "Network\Socket.hsc" #-}
    	(3) -> Raw
    {-# LINE 1930 "Network\Socket.hsc" #-}

    {-# LINE 1931 "Network\Socket.hsc" #-}

    {-# LINE 1932 "Network\Socket.hsc" #-}
    	(4) -> RDM
    {-# LINE 1933 "Network\Socket.hsc" #-}

    {-# LINE 1934 "Network\Socket.hsc" #-}

    {-# LINE 1935 "Network\Socket.hsc" #-}
    	(5) -> SeqPacket
    {-# LINE 1936 "Network\Socket.hsc" #-}

    {-# LINE 1937 "Network\Socket.hsc" #-}

    -- ---------------------------------------------------------------------------
    -- Utility Functions

    aNY_PORT :: PortNumber
    aNY_PORT = 0

    -- | The IPv4 wild card address.

    iNADDR_ANY :: HostAddress
    iNADDR_ANY = htonl (0)
    {-# LINE 1948 "Network\Socket.hsc" #-}

    {-# LINE 1955 "Network\Socket.hsc" #-}

    sOMAXCONN :: Int
    sOMAXCONN = 5
    {-# LINE 1958 "Network\Socket.hsc" #-}

    sOL_SOCKET :: Int
    sOL_SOCKET = 65535
    {-# LINE 1961 "Network\Socket.hsc" #-}

    {-# LINE 1966 "Network\Socket.hsc" #-}

    maxListenQueue :: Int
    maxListenQueue = sOMAXCONN

    -- -----------------------------------------------------------------------------

    data ShutdownCmd
     = ShutdownReceive
     | ShutdownSend
     | ShutdownBoth

    INSTANCE_TYPEABLE0(ShutdownCmd,shutdownCmdTc,"ShutdownCmd")

    sdownCmdToInt :: ShutdownCmd -> CInt
    sdownCmdToInt ShutdownReceive = 0
    sdownCmdToInt ShutdownSend    = 1
    sdownCmdToInt ShutdownBoth    = 2

    shutdown :: Socket -> ShutdownCmd -> IO ()
    shutdown (MkSocket s _ _ _ _) stype = do
      throwSocketErrorIfMinus1Retry "shutdown" (c_shutdown s (sdownCmdToInt stype))
      return ()

    -- -----------------------------------------------------------------------------

    -- | Closes a socket
    sClose	 :: Socket -> IO ()
    sClose (MkSocket s _ _ _ socketStatus) = do
     withMVar socketStatus $ \ status ->
       if status == ConvertedToHandle
    	then ioError (userError ("sClose: converted to a Handle, use hClose instead"))
    	else c_close s; return ()

    -- -----------------------------------------------------------------------------

    sIsConnected :: Socket -> IO Bool
    sIsConnected (MkSocket _ _ _ _ status) = do
        value <- readMVar status
        return (value == Connected)

    -- -----------------------------------------------------------------------------
    -- Socket Predicates

    sIsBound :: Socket -> IO Bool
    sIsBound (MkSocket _ _ _ _ status) = do
        value <- readMVar status
        return (value == Bound)

    sIsListening :: Socket -> IO Bool
    sIsListening (MkSocket _ _ _  _ status) = do
        value <- readMVar status
        return (value == Listening)

    sIsReadable  :: Socket -> IO Bool
    sIsReadable (MkSocket _ _ _ _ status) = do
        value <- readMVar status
        return (value == Listening || value == Connected)

    sIsWritable  :: Socket -> IO Bool
    sIsWritable = sIsReadable -- sort of.

    sIsAcceptable :: Socket -> IO Bool

    {-# LINE 2034 "Network\Socket.hsc" #-}
    sIsAcceptable (MkSocket _ _ _ _ status) = do
        value <- readMVar status
        return (value == Connected || value == Listening)

    -- -----------------------------------------------------------------------------
    -- Internet address manipulation routines:

    inet_addr :: String -> IO HostAddress
    inet_addr ipstr = do
       withCString ipstr $ \str -> do
       had <- c_inet_addr str
       if had == -1
        then ioError (userError ("inet_addr: Malformed address: " ++ ipstr))
        else return had  -- network byte order

    inet_ntoa :: HostAddress -> IO String
    inet_ntoa haddr = do
      pstr <- c_inet_ntoa haddr
      peekCString pstr

    -- | turns a Socket into an 'Handle'. By default, the new handle is
    -- unbuffered. Use 'System.IO.hSetBuffering' to change the buffering.
    --
    -- Note that since a 'Handle' is automatically closed by a finalizer
    -- when it is no longer referenced, you should avoid doing any more
    -- operations on the 'Socket' after calling 'socketToHandle'.  To
    -- close the 'Socket' after 'socketToHandle', call 'System.IO.hClose'
    -- on the 'Handle'.

    {-# LINE 2064 "Network\Socket.hsc" #-}
    socketToHandle :: Socket -> IOMode -> IO Handle
    socketToHandle s@(MkSocket fd _ _ _ socketStatus) mode = do
     modifyMVar socketStatus $ \ status ->
        if status == ConvertedToHandle
    	then ioError (userError ("socketToHandle: already a Handle"))
    	else do

    {-# LINE 2071 "Network\Socket.hsc" #-}
        h <- fdToHandle' (fromIntegral fd) (Just System.Posix.Internals.Stream) True (show s) mode True{-bin-}

    {-# LINE 2077 "Network\Socket.hsc" #-}
        return (ConvertedToHandle, h)

    {-# LINE 2082 "Network\Socket.hsc" #-}

    -- | Pack a list of values into a bitmask.  The possible mappings from
    -- value to bit-to-set are given as the first argument.  We assume
    -- that each value can cause exactly one bit to be set; unpackBits will
    -- break if this property is not true.

    packBits :: (Eq a, Bits b) => [(a, b)] -> [a] -> b

    packBits mapping xs = foldl' pack 0 mapping
        where pack acc (k, v) | k `elem` xs = acc .|. v
                              | otherwise   = acc

    -- | Unpack a bitmask into a list of values.

    unpackBits :: Bits b => [(a, b)] -> b -> [a]

    unpackBits [] 0    = []
    unpackBits [] r    = error ("unpackBits: unhandled bits set: " ++ show r)
    unpackBits ((k,v):xs) r
        | r .&. v /= 0 = k : unpackBits xs (r .&. complement v)
        | otherwise    = unpackBits xs r

    -----------------------------------------------------------------------------
    -- Address and service lookups

    {-# LINE 2440 "Network\Socket.hsc" #-}

    mkInvalidRecvArgError :: String -> IOError
    mkInvalidRecvArgError loc = IOError Nothing

    {-# LINE 2444 "Network\Socket.hsc" #-}
    				    InvalidArgument

    {-# LINE 2448 "Network\Socket.hsc" #-}
    				    loc "non-positive length" Nothing

    mkEOFError :: String -> IOError
    mkEOFError loc = IOError Nothing EOF loc "end of file" Nothing

    -- ---------------------------------------------------------------------------
    -- WinSock support

    {-| On Windows operating systems, the networking subsystem has to be
    initialised using 'withSocketsDo' before any networking operations can
    be used.  eg.

    > main = withSocketsDo $ do {...}

    Although this is only strictly necessary on Windows platforms, it is
    harmless on other platforms, so for portability it is good practice to
    use it all the time.
    -}
    withSocketsDo :: IO a -> IO a

    {-# LINE 2470 "Network\Socket.hsc" #-}
    withSocketsDo act = do
       x <- initWinSock
       if ( x /= 0 ) then
         ioError (userError "Failed to initialise WinSock")
        else do
          act `Control.Exception.finally` shutdownWinSock

    foreign import ccall unsafe "initWinSock" initWinSock :: IO Int
    foreign import ccall unsafe "shutdownWinSock" shutdownWinSock :: IO ()

    {-# LINE 2481 "Network\Socket.hsc" #-}

    -- ---------------------------------------------------------------------------
    -- foreign imports from the C library

    foreign import ccall unsafe "my_inet_ntoa"
      c_inet_ntoa :: HostAddress -> IO (Ptr CChar)

    foreign import CALLCONV unsafe "inet_addr"
      c_inet_addr :: Ptr CChar -> IO HostAddress

    foreign import CALLCONV unsafe "shutdown"
      c_shutdown :: CInt -> CInt -> IO CInt

    {-# LINE 2498 "Network\Socket.hsc" #-}
    foreign import stdcall unsafe "closesocket"
      c_close :: CInt -> IO CInt

    {-# LINE 2501 "Network\Socket.hsc" #-}

    foreign import CALLCONV unsafe "socket"
      c_socket :: CInt -> CInt -> CInt -> IO CInt
    foreign import CALLCONV unsafe "bind"
      c_bind :: CInt -> Ptr SockAddr -> CInt{-CSockLen???-} -> IO CInt
    foreign import CALLCONV unsafe "connect"
      c_connect :: CInt -> Ptr SockAddr -> CInt{-CSockLen???-} -> IO CInt
    foreign import CALLCONV unsafe "accept"
      c_accept :: CInt -> Ptr SockAddr -> Ptr CInt{-CSockLen???-} -> IO CInt
    foreign import CALLCONV safe "accept"
      c_accept_safe :: CInt -> Ptr SockAddr -> Ptr CInt{-CSockLen???-} -> IO CInt
    foreign import CALLCONV unsafe "listen"
      c_listen :: CInt -> CInt -> IO CInt

    {-# LINE 2516 "Network\Socket.hsc" #-}
    foreign import ccall "rtsSupportsBoundThreads" threaded :: Bool

    {-# LINE 2518 "Network\Socket.hsc" #-}

    foreign import CALLCONV unsafe "send"
      c_send :: CInt -> Ptr a -> CSize -> CInt -> IO CInt
    foreign import CALLCONV unsafe "sendto"
      c_sendto :: CInt -> Ptr a -> CSize -> CInt -> Ptr SockAddr -> CInt -> IO CInt
    foreign import CALLCONV unsafe "recv"
      c_recv :: CInt -> Ptr CChar -> CSize -> CInt -> IO CInt
    foreign import CALLCONV unsafe "recvfrom"
      c_recvfrom :: CInt -> Ptr a -> CSize -> CInt -> Ptr SockAddr -> Ptr CInt -> IO CInt
    foreign import CALLCONV unsafe "getpeername"
      c_getpeername :: CInt -> Ptr SockAddr -> Ptr CInt -> IO CInt
    foreign import CALLCONV unsafe "getsockname"
      c_getsockname :: CInt -> Ptr SockAddr -> Ptr CInt -> IO CInt

    foreign import CALLCONV unsafe "getsockopt"
      c_getsockopt :: CInt -> CInt -> CInt -> Ptr CInt -> Ptr CInt -> IO CInt
    foreign import CALLCONV unsafe "setsockopt"
      c_setsockopt :: CInt -> CInt -> CInt -> Ptr CInt -> CInt -> IO CInt

    -----------------------------------------------------------------------------
    -- Support for thread-safe blocking operations in GHC.

    {-# LINE 2569 "Network\Socket.hsc" #-}

    throwErrnoIfMinus1Retry_mayBlock name _ act
      = throwSocketErrorIfMinus1Retry name act

    throwErrnoIfMinus1Retry_repeatOnBlock name _ act
      = throwSocketErrorIfMinus1Retry name act

    throwSocketErrorIfMinus1_ :: Num a => String -> IO a -> IO ()
    throwSocketErrorIfMinus1_ name act = do
      throwSocketErrorIfMinus1Retry name act
      return ()

    {-# LINE 2582 "Network\Socket.hsc" #-}
    throwSocketErrorIfMinus1Retry name act = do
      r <- act
      if (r == -1)
       then do
        rc   <- c_getLastError
        case rc of
          10093 -> do -- WSANOTINITIALISED
            withSocketsDo (return ())
    	r <- act
    	if (r == -1)
    	 then (c_getLastError >>= throwSocketError name)
    	 else return r
          _ -> throwSocketError name rc
       else return r

    throwSocketError name rc = do
        pstr <- c_getWSError rc
        str  <- peekCString pstr

    {-# LINE 2601 "Network\Socket.hsc" #-}
        ioError (IOError Nothing OtherError name str Nothing)

    {-# LINE 2605 "Network\Socket.hsc" #-}
    foreign import CALLCONV unsafe "WSAGetLastError"
      c_getLastError :: IO CInt

    foreign import ccall unsafe "getWSErrorDescr"
      c_getWSError :: CInt -> IO (Ptr CChar)

    {-# LINE 2615 "Network\Socket.hsc" #-}

    {-# LINE 2616 "Network\Socket.hsc" #-}