{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE ImpredicativeTypes #-}
{-|
Module      : Netw.Socket
Description : Core functions
Portabilty  : Linux

This module contains all the functions required to create and use sockets.
-}
module Netw.Socket 
( Socket (..)
, socket, closeSocket
, bind, listen, getsockname
, accept, accept_
, connect

, sendall, send, send'
, sendallto, sendto, sendto'
, sendmsg, sendmsg'

, recvsome, recv, recv'
, recvfrom, recvfrom', recvsomefrom
, recvmsg, recvmsg_

, shutdown
, module Netw.Internal.Enum
) where
import qualified Netw.Internal.Socket as I
import Netw.Internal.Enum
import Netw.Internal.Type
import Netw.Internal.Cmsg (newCmsgBuffer)

import Netw.SockAddr
import Netw.Ancillary

import Control.Monad
import Control.Monad.ST
import Control.Monad.Primitive

import Data.Function
import Data.Functor
import Data.Primitive
import Data.Word

import Foreign
import Foreign.C.Types

import System.Posix.Types
import System.Posix.IO

import GHC.Exts

-- |
-- A file descriptor that is a socket.
-- All socket used by this library is in nonblocking mode (O_NONBLOCK)
newtype Socket = MkSocket { Socket -> Fd
unSocket :: Fd }

-- | Create a new socket (see `man 3 socket`)
socket :: ProtocolFamily -> SocketType -> Protocol -> IO Socket
socket :: ProtocolFamily -> SocketType -> Protocol -> IO Socket
socket ProtocolFamily
domain   -- ^ The protocol family of the address (an PF_* value)
       SocketType
stype    -- ^ The socket types (SOCK_STREAM, SOCK_RAW, etc)
       Protocol
protocol -- ^ The protocol. Usually passing DefaultProtocol work.
  = Fd -> Socket
MkSocket (Fd -> Socket) -> IO Fd -> IO Socket
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ProtocolFamily -> SocketType -> Protocol -> IO Fd
I.socket ProtocolFamily
domain SocketType
stype Protocol
protocol

-- | Close a socket (see `man 3 close`)
closeSocket :: Socket -> IO ()
closeSocket :: Socket -> IO ()
closeSocket = Fd -> IO ()
closeFd (Fd -> IO ()) -> (Socket -> Fd) -> Socket -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Socket -> Fd
unSocket

-- | Bind a socket to an address (see `man 3 bind`)
bind :: SockAddr a => Socket -> a -> IO ()
bind :: forall a. SockAddr a => Socket -> a -> IO ()
bind (Socket -> Fd
unSocket -> Fd
sock) sockaddr :: a
sockaddr@(a -> ByteArray
forall a. SockAddr a => a -> ByteArray
sockAddrToByteArray -> addr :: ByteArray
addr@(ByteArray ByteArray#
addr#))
  | a -> Int
forall a. SockAddr a => a -> Int
sockAddrSize a
sockaddr Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 = Fd -> ByteArray# -> CSocklen -> IO ()
I.bind# Fd
sock ByteArray#
addr# (Int -> CSocklen
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> CSocklen) -> Int -> CSocklen
forall a b. (a -> b) -> a -> b
$ ByteArray -> Int
sizeofByteArray ByteArray
addr)
  | Bool
otherwise                 = Fd -> Ptr () -> CSocklen -> IO ()
I.bind  Fd
sock Ptr ()
forall a. Ptr a
nullPtr CSocklen
0

-- | Mark a socket as accepting connection (see `man 3 listen`)
listen :: Socket -> Int -> IO ()
listen :: Socket -> Int -> IO ()
listen (Socket -> Fd
unSocket -> Fd
sock) (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral -> CInt
backlog) =
  Fd -> CInt -> IO ()
I.listen Fd
sock CInt
backlog

-- | Retrieve the name of the socket (see `man 3 getsockname`)
getsockname :: Socket -> IO Addr
getsockname :: Socket -> IO Addr
getsockname (Socket -> Fd
unSocket -> Fd
sock) = 
  CSocklen -> (Ptr CSocklen -> IO Addr) -> IO Addr
forall a b. Storable a => a -> (Ptr a -> IO b) -> IO b
with CSocklen
0 ((Ptr CSocklen -> IO Addr) -> IO Addr)
-> (Ptr CSocklen -> IO Addr) -> IO Addr
forall a b. (a -> b) -> a -> b
$ \ Ptr CSocklen
sockaddrLen -> do
    Fd -> Ptr () -> Ptr CSocklen -> IO ()
I.getsockname Fd
sock Ptr ()
forall a. Ptr a
nullPtr Ptr CSocklen
sockaddrLen
    sockaddr :: MutableByteArray RealWorld
sockaddr@(MutableByteArray MutableByteArray# RealWorld
sockaddr#) <- Int -> IO (MutableByteArray (PrimState IO))
forall (m :: * -> *).
PrimMonad m =>
Int -> m (MutableByteArray (PrimState m))
newByteArray (Int -> IO (MutableByteArray (PrimState IO)))
-> (CSocklen -> Int)
-> CSocklen
-> IO (MutableByteArray (PrimState IO))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CSocklen -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CSocklen -> IO (MutableByteArray (PrimState IO)))
-> IO CSocklen -> IO (MutableByteArray (PrimState IO))
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr CSocklen -> IO CSocklen
forall a. Storable a => Ptr a -> IO a
peek Ptr CSocklen
sockaddrLen
    Fd -> MutableByteArray# RealWorld -> Ptr CSocklen -> IO ()
I.getsockname# Fd
sock MutableByteArray# RealWorld
sockaddr# Ptr CSocklen
sockaddrLen
    ByteArray -> Addr
mkAddr (ByteArray -> Addr) -> IO ByteArray -> IO Addr
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MutableByteArray (PrimState IO) -> IO ByteArray
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> m ByteArray
unsafeFreezeByteArray MutableByteArray RealWorld
MutableByteArray (PrimState IO)
sockaddr

-- | Extract the first connection on the pending connection queue (see `man 3 accept`). This function blocks the calling thread until a connection is made.
accept :: Socket -> IO (Socket, Addr)
accept :: Socket -> IO (Socket, Addr)
accept (Socket -> Fd
unSocket -> Fd
sock) = 
  CSocklen
-> (Ptr CSocklen -> IO (Socket, Addr)) -> IO (Socket, Addr)
forall a b. Storable a => a -> (Ptr a -> IO b) -> IO b
with CSocklen
sockaddrLenGuess ((Ptr CSocklen -> IO (Socket, Addr)) -> IO (Socket, Addr))
-> (Ptr CSocklen -> IO (Socket, Addr)) -> IO (Socket, Addr)
forall a b. (a -> b) -> a -> b
$ \ Ptr CSocklen
sockaddrLen -> do -- TODO: Check the doc if the address returned from accept is the same as getsockname
    sockaddr :: MutableByteArray RealWorld
sockaddr@(MutableByteArray MutableByteArray# RealWorld
sockaddr#) <- Int -> IO (MutableByteArray (PrimState IO))
forall (m :: * -> *).
PrimMonad m =>
Int -> m (MutableByteArray (PrimState m))
newByteArray (CSocklen -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSocklen
sockaddrLenGuess)
    Socket
peer <- Fd -> Socket
MkSocket (Fd -> Socket) -> IO Fd -> IO Socket
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Fd -> MutableByteArray# RealWorld -> Ptr CSocklen -> IO Fd
I.accept# Fd
sock MutableByteArray# RealWorld
sockaddr# Ptr CSocklen
sockaddrLen
    CSocklen
len  <- Ptr CSocklen -> IO CSocklen
forall a. Storable a => Ptr a -> IO a
peek Ptr CSocklen
sockaddrLen
    (Socket
peer, ) (Addr -> (Socket, Addr)) -> IO Addr -> IO (Socket, Addr)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
      if CSocklen
len CSocklen -> CSocklen -> Bool
forall a. Ord a => a -> a -> Bool
> CSocklen
sockaddrLenGuess
      then do
        addr :: MutableByteArray RealWorld
addr@(MutableByteArray MutableByteArray# RealWorld
addr#) <- Int -> IO (MutableByteArray (PrimState IO))
forall (m :: * -> *).
PrimMonad m =>
Int -> m (MutableByteArray (PrimState m))
newByteArray (CSocklen -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSocklen
len)
        Fd -> MutableByteArray# RealWorld -> Ptr CSocklen -> IO ()
I.getsockname# (Socket -> Fd
unSocket Socket
peer) MutableByteArray# RealWorld
addr# Ptr CSocklen
sockaddrLen
        ByteArray -> Addr
mkAddr (ByteArray -> Addr) -> IO ByteArray -> IO Addr
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MutableByteArray (PrimState IO) -> IO ByteArray
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> m ByteArray
unsafeFreezeByteArray MutableByteArray RealWorld
MutableByteArray (PrimState IO)
addr
      else do
        ByteArray -> Addr
mkAddr (ByteArray -> Addr) -> IO ByteArray -> IO Addr
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (MutableByteArray (PrimState IO) -> IO ByteArray
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> m ByteArray
unsafeFreezeByteArray (MutableByteArray (PrimState IO) -> IO ByteArray)
-> IO (MutableByteArray (PrimState IO)) -> IO ByteArray
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< MutableByteArray (PrimState IO)
-> Int -> IO (MutableByteArray (PrimState IO))
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m)
-> Int -> m (MutableByteArray (PrimState m))
resizeMutableByteArray MutableByteArray RealWorld
MutableByteArray (PrimState IO)
sockaddr (CSocklen -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSocklen
len))
  where sockaddrLenGuess :: CSocklen
sockaddrLenGuess = CSocklen
128

-- | A version of `accept` which does not return the peer address
accept_ :: Socket -> IO Socket
accept_ :: Socket -> IO Socket
accept_ (Socket -> Fd
unSocket -> Fd
sock) = Fd -> Socket
MkSocket (Fd -> Socket) -> IO Fd -> IO Socket
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Fd -> Ptr () -> Ptr CSocklen -> IO Fd
I.accept Fd
sock Ptr ()
forall a. Ptr a
nullPtr Ptr CSocklen
forall a. Ptr a
nullPtr

-- | Try to connect to an address (see `man 3 connect`)
connect :: SockAddr a => Socket -> a -> IO ()
connect :: forall a. SockAddr a => Socket -> a -> IO ()
connect (Socket -> Fd
unSocket -> Fd
sock) sockaddr :: a
sockaddr@(a -> ByteArray
forall a. SockAddr a => a -> ByteArray
sockAddrToByteArray -> addr :: ByteArray
addr@(ByteArray ByteArray#
addr#))
  | a -> Int
forall a. SockAddr a => a -> Int
sockAddrSize a
sockaddr Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 = Fd -> ByteArray# -> CSocklen -> IO ()
I.connect# Fd
sock ByteArray#
addr# (Int -> CSocklen
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> CSocklen) -> Int -> CSocklen
forall a b. (a -> b) -> a -> b
$ ByteArray -> Int
sizeofByteArray ByteArray
addr)
  | Bool
otherwise                 = Fd -> Ptr () -> CSocklen -> IO ()
I.connect  Fd
sock Ptr ()
forall a. Ptr a
nullPtr CSocklen
0

-- You can shave off maybe one clock cycle if this is change to use send and not send_wrapper


-- |
-- `send socket buffer offset size flags`
-- Send a range of bytes in buffer located at offset and is size bytes long.
-- Return the number of bytes accually sent which may be less than
-- the number of bytes specified.
-- Block the current thread until some bytes are sent.
-- (see `man 3 send`)
send :: Socket -> ByteArray -> Int -> Int -> MsgFlags -> IO Int
send :: Socket -> ByteArray -> Int -> Int -> MsgFlags -> IO Int
send (Socket -> Fd
unSocket -> Fd
fd) -- ^ A connected socket
     (ByteArray ByteArray#
buf#) -- ^ Message buffer
     Int
offs             -- ^ Offset in bytes into the message buffer to start sending
     Int
size             -- ^ Number of bytes to send
     MsgFlags
flags            -- ^ Specify the type of message transmisstion (MSG_EOR, MSG_OOB, MSG_NOSIGNAL or more depend on platform)
  = CSsize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CSsize -> Int) -> IO CSsize -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Fd -> ByteArray# -> CPtrdiff -> CSize -> MsgFlags -> IO CSsize
I.send# Fd
fd ByteArray#
buf# (Int -> CPtrdiff
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
offs) (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
size) MsgFlags
flags

-- | A version of `send` that accept a pointer instead of a bytearray.
send' :: Socket -> Ptr Word8 -> Int -> MsgFlags -> IO Int
send' :: Socket -> Ptr Word8 -> Int -> MsgFlags -> IO Int
send' (Socket -> Fd
unSocket -> Fd
sockfd) -- ^ A connected socket
      Ptr Word8
buf                  -- ^ Pointer to the message buffer
      Int
len                  -- ^ Number of bytes to send
      MsgFlags
flags                -- ^ Specify the type of message transmisstion (MSG_EOR, MSG_OOB, MSG_NOSIGNAL or more depend on platform)
  = CSsize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CSsize -> Int) -> IO CSsize -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Fd -> Ptr Word8 -> CSize -> MsgFlags -> IO CSsize
I.send Fd
sockfd Ptr Word8
buf (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len) MsgFlags
flags

-- | 
-- Send the whole content of a bytearray through a socket.
-- Block until the entire bytearray has been sent.
sendall :: Socket -> ByteArray -> MsgFlags -> IO ()
sendall :: Socket -> ByteArray -> MsgFlags -> IO ()
sendall Socket
sock ByteArray
buf MsgFlags
flags = ((Int -> Int -> IO ()) -> Int -> Int -> IO ())
-> Int -> Int -> IO ()
forall a. (a -> a) -> a
fix (\ Int -> Int -> IO ()
resend Int
offs Int
size ->
  Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
size Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
    Int
sent <- Socket -> ByteArray -> Int -> Int -> MsgFlags -> IO Int
send Socket
sock ByteArray
buf Int
offs Int
size MsgFlags
flags
    Int -> Int -> IO ()
resend (Int
offs Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
sent) (Int
size Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
sent)) Int
0 (ByteArray -> Int
sizeofByteArray ByteArray
buf)

-- |
-- A version of `send` that accept the destination address (see `man 3 sendto`)
-- Return the number of bytes accually sent which may be less than
-- the number of bytes specified.
-- Block the thread until some bytes are sent.
sendto :: SockAddr a => Socket -> ByteArray -> Int -> Int -> MsgFlags -> a -> IO Int
sendto :: forall a.
SockAddr a =>
Socket -> ByteArray -> Int -> Int -> MsgFlags -> a -> IO Int
sendto (Socket -> Fd
unSocket -> Fd
fd) -- ^ A connection-mode or connectionless-mode socket
       (ByteArray ByteArray#
buf#) -- ^ The buffer containing the message
       Int
offs             -- ^ Offset in bytes into the message buffer specifying where to start sending
       Int
size             -- ^ Number of bytes to send
       MsgFlags
flags            -- ^ Transmission flags
       (a -> ByteArray
forall a. SockAddr a => a -> ByteArray
sockAddrToByteArray -> addr :: ByteArray
addr@(ByteArray ByteArray#
addr#)) -- ^ Destination address (Should be SockAddrNull if using a connected socket)
  = CSsize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CSsize -> Int) -> IO CSsize -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Fd
-> ByteArray#
-> CPtrdiff
-> CSize
-> MsgFlags
-> ByteArray#
-> CSocklen
-> IO CSsize
I.sendto# Fd
fd ByteArray#
buf# (Int -> CPtrdiff
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
offs) (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
size) MsgFlags
flags ByteArray#
addr# (Int -> CSocklen
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> CSocklen) -> Int -> CSocklen
forall a b. (a -> b) -> a -> b
$ ByteArray -> Int
sizeofByteArray ByteArray
addr)

-- | A version of `sendto` that accept a pointer instead of a bytearray
sendto' :: SockAddr a => Socket -> Ptr Word8 -> Int -> MsgFlags -> a -> IO Int
sendto' :: forall a.
SockAddr a =>
Socket -> Ptr Word8 -> Int -> MsgFlags -> a -> IO Int
sendto' (Socket -> Fd
unSocket -> Fd
sockfd)  -- ^ A connection-mode or connectionless-mode socket
        Ptr Word8
buf                   -- ^ Pointer to message buffer
        (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral -> CSize
len) -- ^ Number of bytes to send
        MsgFlags
flags                 -- ^ Transmission flags
        (a -> ByteArray
forall a. SockAddr a => a -> ByteArray
sockAddrToByteArray -> addr :: ByteArray
addr@(ByteArray ByteArray#
addr#)) -- ^ Destination address
  = CSsize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CSsize -> Int) -> IO CSsize -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Fd
-> Ptr Word8
-> CSize
-> MsgFlags
-> ByteArray#
-> CSocklen
-> IO CSsize
I.sendto Fd
sockfd Ptr Word8
buf CSize
len MsgFlags
flags ByteArray#
addr# (Int -> CSocklen
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> CSocklen) -> Int -> CSocklen
forall a b. (a -> b) -> a -> b
$ ByteArray -> Int
sizeofByteArray ByteArray
addr)

-- | Send the whole content of a bytearray
sendallto :: SockAddr a => Socket -> ByteArray -> MsgFlags -> a -> IO ()
sendallto :: forall a.
SockAddr a =>
Socket -> ByteArray -> MsgFlags -> a -> IO ()
sendallto Socket
sock ByteArray
buf MsgFlags
flag a
addr = 
  ((Int -> Int -> IO ()) -> Int -> Int -> IO ())
-> Int -> Int -> IO ()
forall a. (a -> a) -> a
fix (\ Int -> Int -> IO ()
resend Int
offs Int
size -> 
    Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
size Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
      Int
sent <- Socket -> ByteArray -> Int -> Int -> MsgFlags -> a -> IO Int
forall a.
SockAddr a =>
Socket -> ByteArray -> Int -> Int -> MsgFlags -> a -> IO Int
sendto Socket
sock ByteArray
buf Int
offs Int
size MsgFlags
flag a
addr 
      Int -> Int -> IO ()
resend (Int
offs Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
sent) (Int
size Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
sent)) Int
0 (ByteArray -> Int
sizeofByteArray ByteArray
buf)

-- lifting (TODO: Find a better more anonymous method)
data State s = State (State# s)
data ArrayByteArray = ArrayByteArray (Array# ByteArray#)
data ArrayMutableByteArray = ArrayMutableByteArray (Array# (MutableByteArray# RealWorld))

{-|
`sendmsg socket address iovecs cmsgs flags`
The iovecs argument is a list of 3-tuples of the data buffer, the offset in bytes,
and the number of bytes to send. Use SockAddrNull if no address is to be specified.
This function blocks the calling thread and return the number of bytes sent, which
may be less than the intended message size.

(See `man 3 sendmsg`)
-}
sendmsg :: SockAddr a => Socket -> a -> [(ByteArray, Int, Int)] -> [AncillaryData] -> MsgFlags -> IO Int
sendmsg :: forall a.
SockAddr a =>
Socket
-> a
-> [(ByteArray, Int, Int)]
-> [AncillaryData]
-> MsgFlags
-> IO Int
sendmsg (Socket -> Fd
unSocket -> Fd
sockfd)              -- ^ A connection-mode or connectionless-mode socket
        a
addr                              -- ^ Destination address
        ([(ByteArray, Int, Int)] -> ([ByteArray], [Int], [Int])
forall a b c. [(a, b, c)] -> ([a], [b], [c])
unzip3 -> ([ByteArray]
iovecs, [Int]
offs, [Int]
size))  -- ^ A list of message which will be send from left to right. Semantics: (Buffer, Offset(bytes), Size(bytes))
        ([AncillaryData] -> ByteArray
encodeAncillaryData -> ByteArray
control)  -- ^ Ancillary data
        MsgFlags
flags                             -- ^ Transmisstion flags
  = ByteArray -> (Ptr Word8 -> IO Int) -> IO Int
forall (m :: * -> *) a.
PrimBase m =>
ByteArray -> (Ptr Word8 -> m a) -> m a
withByteArrayContents ByteArray
control ((Ptr Word8 -> IO Int) -> IO Int)
-> (Ptr Word8 -> IO Int) -> IO Int
forall a b. (a -> b) -> a -> b
$ \ Ptr Word8
control' ->
    CSsize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CSsize -> Int) -> IO CSsize -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Fd
-> ByteArray#
-> CSocklen
-> Array# ByteArray#
-> ByteArray#
-> ByteArray#
-> CSize
-> Ptr ()
-> CSize
-> MsgFlags
-> IO CSsize
I.sendmsg# Fd
sockfd 
                                ByteArray#
addr# (Int -> CSocklen
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
addrLen)
                                Array# ByteArray#
iovecs# ByteArray#
offs# ByteArray#
size# (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
iovlen)
                                (Ptr Word8 -> Ptr ()
forall a b. Ptr a -> Ptr b
castPtr Ptr Word8
control') (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> CSize) -> Int -> CSize
forall a b. (a -> b) -> a -> b
$ ByteArray -> Int
sizeofByteArray ByteArray
control)
                                MsgFlags
flags
  where !(PrimArray ByteArray#
offs#) = [Item (PrimArray CPtrdiff)] -> PrimArray CPtrdiff
forall l. IsList l => [Item l] -> l
fromList (Int -> Item (PrimArray CPtrdiff)
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Item (PrimArray CPtrdiff))
-> [Int] -> [Item (PrimArray CPtrdiff)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Int]
offs) :: PrimArray CPtrdiff
        !(PrimArray ByteArray#
size#) = [Item (PrimArray CSize)] -> PrimArray CSize
forall l. IsList l => [Item l] -> l
fromList (Int -> Item (PrimArray CSize)
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Item (PrimArray CSize))
-> [Int] -> [Item (PrimArray CSize)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Int]
size) :: PrimArray CSize
        !(ArrayByteArray Array# ByteArray#
iovecs#) = (forall s. ST s ArrayByteArray) -> ArrayByteArray
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s ArrayByteArray) -> ArrayByteArray)
-> (forall s. ST s ArrayByteArray) -> ArrayByteArray
forall a b. (a -> b) -> a -> b
$ (State# (PrimState (ST s))
 -> (# State# (PrimState (ST s)), ArrayByteArray #))
-> ST s ArrayByteArray
forall a.
(State# (PrimState (ST s)) -> (# State# (PrimState (ST s)), a #))
-> ST s a
forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
primitive ((State# (PrimState (ST s))
  -> (# State# (PrimState (ST s)), ArrayByteArray #))
 -> ST s ArrayByteArray)
-> (State# (PrimState (ST s))
    -> (# State# (PrimState (ST s)), ArrayByteArray #))
-> ST s ArrayByteArray
forall a b. (a -> b) -> a -> b
$ \ State# (PrimState (ST s))
state0# ->
          let !(# State# (PrimState (ST s))
state1#, MutableArray# (PrimState (ST s)) ByteArray#
mutarr# #) 
                = Int#
-> ByteArray#
-> State# (PrimState (ST s))
-> (# State# (PrimState (ST s)),
      MutableArray# (PrimState (ST s)) ByteArray# #)
forall a d.
Int# -> a -> State# d -> (# State# d, MutableArray# d a #)
newArray# Int#
iovlen# ByteArray#
emptyByteArray# State# (PrimState (ST s))
state0# in
          let !(State State# s
state4#, Int
_)
                = ((State s, Int) -> ByteArray -> (State s, Int))
-> (State s, Int) -> [ByteArray] -> (State s, Int)
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl (\ (State State# s
state2#, idx :: Int
idx@(I# Int#
idx#)) (ByteArray ByteArray#
iov#) ->
                    let state3# :: State# s
state3# = MutableArray# s ByteArray#
-> Int# -> ByteArray# -> State# s -> State# s
forall d a. MutableArray# d a -> Int# -> a -> State# d -> State# d
writeArray# MutableArray# s ByteArray#
mutarr# Int#
idx# ByteArray#
iov# State# s
state2#
                    in  (State# s -> State s
forall s. State# s -> State s
State State# s
state3#, Int
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) ) (State# s -> State s
forall s. State# s -> State s
State State# s
state1#, Int
0 :: Int) [ByteArray]
iovecs in
          let !(# State# s
state5#, Array# ByteArray#
arr# #)
                = MutableArray# s ByteArray#
-> State# s -> (# State# s, Array# ByteArray# #)
forall d a.
MutableArray# d a -> State# d -> (# State# d, Array# a #)
unsafeFreezeArray# MutableArray# s ByteArray#
mutarr# State# s
state4# in
          (# State# s
State# (PrimState (ST s))
state5#, Array# ByteArray# -> ArrayByteArray
ArrayByteArray Array# ByteArray#
arr# #)
        !iovlen :: Int
iovlen@(I# Int#
iovlen#) = [ByteArray] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [ByteArray]
iovecs
        !(ByteArray ByteArray#
emptyByteArray#) = ByteArray
emptyByteArray
        !(ByteArray ByteArray#
addr#) = a -> ByteArray
forall a. SockAddr a => a -> ByteArray
sockAddrToByteArray a
addr
        addrLen :: Int
addrLen = a -> Int
forall a. SockAddr a => a -> Int
sockAddrSize a
addr

-- | A version of `sendmsg` that uses pointers instead of bytearrays
sendmsg' :: SockAddr a => Socket -> a -> [(Ptr Word8, Int)] -> [AncillaryData] -> MsgFlags -> IO Int
sendmsg' :: forall a.
SockAddr a =>
Socket
-> a -> [(Ptr Word8, Int)] -> [AncillaryData] -> MsgFlags -> IO Int
sendmsg' (Socket -> Fd
unSocket -> Fd
sockfd) a
addr [(Ptr Word8, Int)]
iovecs ([AncillaryData] -> ByteArray
encodeAncillaryData -> ByteArray
control) MsgFlags
flags =
  ByteArray -> (Ptr Word8 -> IO Int) -> IO Int
forall (m :: * -> *) a.
PrimBase m =>
ByteArray -> (Ptr Word8 -> m a) -> m a
withByteArrayContents ByteArray
control ((Ptr Word8 -> IO Int) -> IO Int)
-> (Ptr Word8 -> IO Int) -> IO Int
forall a b. (a -> b) -> a -> b
$ \ Ptr Word8
control' ->
  [Iovec] -> (Ptr Iovec -> IO Int) -> IO Int
forall a b. Storable a => [a] -> (Ptr a -> IO b) -> IO b
withArray [Iovec]
iov ((Ptr Iovec -> IO Int) -> IO Int)
-> (Ptr Iovec -> IO Int) -> IO Int
forall a b. (a -> b) -> a -> b
$ \ Ptr Iovec
iov' ->
    CSsize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CSsize -> Int) -> IO CSsize -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Fd
-> ByteArray#
-> CSocklen
-> Ptr Iovec
-> CSize
-> Ptr ()
-> CSize
-> MsgFlags
-> IO CSsize
I.sendmsg Fd
sockfd
                               ByteArray#
addr# (Int -> CSocklen
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
addrLen)
                               Ptr Iovec
iov' (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
iovlen)
                               (Ptr Word8 -> Ptr ()
forall a b. Ptr a -> Ptr b
castPtr Ptr Word8
control') (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> CSize) -> Int -> CSize
forall a b. (a -> b) -> a -> b
$ ByteArray -> Int
sizeofByteArray ByteArray
control)
                               MsgFlags
flags
  where addrLen :: Int
addrLen = a -> Int
forall a. SockAddr a => a -> Int
sockAddrSize a
addr
        !(ByteArray ByteArray#
addr#) = a -> ByteArray
forall a. SockAddr a => a -> ByteArray
sockAddrToByteArray a
addr
        iov :: [Iovec]
iov = [(Ptr Word8, Int)]
iovecs [(Ptr Word8, Int)] -> ((Ptr Word8, Int) -> Iovec) -> [Iovec]
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \ (Ptr Word8
ptr, Int
len) -> Ptr () -> CSize -> Iovec
Iovec (Ptr Word8 -> Ptr ()
forall a b. Ptr a -> Ptr b
castPtr Ptr Word8
ptr) (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len)
        iovlen :: Int
iovlen = [(Ptr Word8, Int)] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Ptr Word8, Int)]
iovecs

{-|
`recvsome socket n flags`
Receive a maximum of `n` bytes from `socket`.
Return the message as a bytearray. If the bytearray is empty (size == 0) then there is no more data to be read and the socket
should be closed.
-}
recvsome :: Socket -> Int -> MsgFlags -> IO ByteArray
recvsome :: Socket -> Int -> MsgFlags -> IO ByteArray
recvsome Socket
sock Int
maxBytesRecv MsgFlags
flags = do
  MutableByteArray RealWorld
mutarr    <- Int -> IO (MutableByteArray (PrimState IO))
forall (m :: * -> *).
PrimMonad m =>
Int -> m (MutableByteArray (PrimState m))
newByteArray Int
maxBytesRecv
  Int
bytesRecv <- Socket
-> MutableByteArray RealWorld -> Int -> Int -> MsgFlags -> IO Int
recv Socket
sock MutableByteArray RealWorld
mutarr Int
0 Int
maxBytesRecv MsgFlags
flags
  MutableByteArray (PrimState IO) -> Int -> IO ()
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> Int -> m ()
shrinkMutableByteArray MutableByteArray RealWorld
MutableByteArray (PrimState IO)
mutarr (Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
bytesRecv)
  MutableByteArray (PrimState IO) -> IO ByteArray
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> m ByteArray
unsafeFreezeByteArray MutableByteArray RealWorld
MutableByteArray (PrimState IO)
mutarr

{-|
`recv socket buffer offset size flags`
Receive a maximum of `size` bytes from `socket`, storing those bytes in `buffer` at `offset`
Return the number of bytes received. (See `man 3 recv`)
Block the calling thread until some bytes are received.
-}
recv :: Socket -> MutableByteArray RealWorld -> Int -> Int -> MsgFlags -> IO Int
recv :: Socket
-> MutableByteArray RealWorld -> Int -> Int -> MsgFlags -> IO Int
recv (Socket -> Fd
unSocket -> Fd
sockfd)    -- ^ A socket to receive messages from
     (MutableByteArray MutableByteArray# RealWorld
buf#) -- ^ Buffer to store message
     Int
offs                    -- ^ Offset in bytes into the buffer
     Int
size                    -- ^ Number of bytes allowed
     MsgFlags
flags                   -- ^ Transmission flags
  = (CSsize -> Int) -> IO CSsize -> IO Int
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap CSsize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (IO CSsize -> IO Int) -> IO CSsize -> IO Int
forall a b. (a -> b) -> a -> b
$ Fd
-> MutableByteArray# RealWorld
-> CPtrdiff
-> CSize
-> MsgFlags
-> IO CSsize
I.recv# Fd
sockfd MutableByteArray# RealWorld
buf# (Int -> CPtrdiff
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
offs) (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
size) MsgFlags
flags

-- | A version of `recv` that takes a pointer instead of a mutablebytearray
recv' :: Socket -> Ptr Word8 -> Int -> MsgFlags -> IO Int 
recv' :: Socket -> Ptr Word8 -> Int -> MsgFlags -> IO Int
recv' (Socket -> Fd
unSocket -> Fd
sockfd) Ptr Word8
buf Int
size = (CSsize -> Int) -> IO CSsize -> IO Int
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap CSsize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (IO CSsize -> IO Int)
-> (MsgFlags -> IO CSsize) -> MsgFlags -> IO Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Fd -> Ptr Word8 -> CSize -> MsgFlags -> IO CSsize
I.recv Fd
sockfd Ptr Word8
buf (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
size)

recvfromImpl :: Socket -> MutableByteArray RealWorld -> Int -> Int -> MsgFlags -> IO (Int, ByteArray)
recvfromImpl :: Socket
-> MutableByteArray RealWorld
-> Int
-> Int
-> MsgFlags
-> IO (Int, ByteArray)
recvfromImpl (Socket -> Fd
unSocket -> Fd
sockfd) (MutableByteArray MutableByteArray# RealWorld
buf#) Int
offs Int
size MsgFlags
flags = do
  addr :: MutableByteArray RealWorld
addr@(MutableByteArray MutableByteArray# RealWorld
addr#) <- IO (MutableByteArray RealWorld)
IO (MutableByteArray (PrimState IO))
forall (m :: * -> *).
PrimMonad m =>
m (MutableByteArray (PrimState m))
newSockAddrStorage
  Int
addrlen <- MutableByteArray (PrimState IO) -> IO Int
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> m Int
getSizeofMutableByteArray MutableByteArray RealWorld
MutableByteArray (PrimState IO)
addr
  CSocklen
-> (Ptr CSocklen -> IO (Int, ByteArray)) -> IO (Int, ByteArray)
forall a b. Storable a => a -> (Ptr a -> IO b) -> IO b
with (Int -> CSocklen
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
addrlen) ((Ptr CSocklen -> IO (Int, ByteArray)) -> IO (Int, ByteArray))
-> (Ptr CSocklen -> IO (Int, ByteArray)) -> IO (Int, ByteArray)
forall a b. (a -> b) -> a -> b
$ \ Ptr CSocklen
addrlen' -> do
    CSsize
bytesRecv <-
      Fd
-> MutableByteArray# RealWorld
-> CPtrdiff
-> CSize
-> MsgFlags
-> MutableByteArray# RealWorld
-> Ptr CSocklen
-> IO CSsize
I.recvfrom# Fd
sockfd
                  MutableByteArray# RealWorld
buf# (Int -> CPtrdiff
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
offs) (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
size)
                  MsgFlags
flags MutableByteArray# RealWorld
addr# Ptr CSocklen
addrlen'
    MutableByteArray (PrimState IO) -> Int -> IO ()
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> Int -> m ()
shrinkMutableByteArray MutableByteArray RealWorld
MutableByteArray (PrimState IO)
addr (Int -> IO ()) -> (CSocklen -> Int) -> CSocklen -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CSocklen -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CSocklen -> IO ()) -> IO CSocklen -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr CSocklen -> IO CSocklen
forall a. Storable a => Ptr a -> IO a
peek Ptr CSocklen
addrlen'
    (CSsize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSsize
bytesRecv,) (ByteArray -> (Int, ByteArray))
-> IO ByteArray -> IO (Int, ByteArray)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MutableByteArray (PrimState IO) -> IO ByteArray
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> m ByteArray
unsafeFreezeByteArray MutableByteArray RealWorld
MutableByteArray (PrimState IO)
addr 

{-|
`recvfrom socket buffer offset size flags`
Receive a message less than `size` bytes long and the source address.
The bytes received are stored in `buffer` at `offset`
Return the number of bytes received.

(See `man 3 recvfrom`)
-}
recvfrom :: Socket -> MutableByteArray RealWorld -> Int -> Int -> MsgFlags -> IO (Int, Addr)
recvfrom :: Socket
-> MutableByteArray RealWorld
-> Int
-> Int
-> MsgFlags
-> IO (Int, Addr)
recvfrom Socket
sock  -- ^ A socket to receive messages from
         MutableByteArray RealWorld
buf   -- ^ Buffer to store message
         Int
offs  -- ^ Offset in bytes into the buffer
         Int
size  -- ^ Number of bytes allowed
         MsgFlags
flags -- ^ Transmission flags
  = (ByteArray -> Addr) -> (Int, ByteArray) -> (Int, Addr)
forall a b. (a -> b) -> (Int, a) -> (Int, b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ByteArray -> Addr
mkAddr ((Int, ByteArray) -> (Int, Addr))
-> IO (Int, ByteArray) -> IO (Int, Addr)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Socket
-> MutableByteArray RealWorld
-> Int
-> Int
-> MsgFlags
-> IO (Int, ByteArray)
recvfromImpl Socket
sock MutableByteArray RealWorld
buf Int
offs Int
size MsgFlags
flags

-- | A version of `recvfrom` that takes a pointer
recvfrom' :: Socket -> Ptr Word8 -> Int -> MsgFlags -> IO (Int, Addr)
recvfrom' :: Socket -> Ptr Word8 -> Int -> MsgFlags -> IO (Int, Addr)
recvfrom' (Socket -> Fd
unSocket -> Fd
sockfd) Ptr Word8
buf Int
len MsgFlags
flags = (ByteArray -> Addr) -> (Int, ByteArray) -> (Int, Addr)
forall a b. (a -> b) -> (Int, a) -> (Int, b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ByteArray -> Addr
mkAddr ((Int, ByteArray) -> (Int, Addr))
-> IO (Int, ByteArray) -> IO (Int, Addr)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> do
  addr :: MutableByteArray RealWorld
addr@(MutableByteArray MutableByteArray# RealWorld
addr#) <- IO (MutableByteArray RealWorld)
IO (MutableByteArray (PrimState IO))
forall (m :: * -> *).
PrimMonad m =>
m (MutableByteArray (PrimState m))
newSockAddrStorage
  Int
addrlen <- MutableByteArray (PrimState IO) -> IO Int
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> m Int
getSizeofMutableByteArray MutableByteArray RealWorld
MutableByteArray (PrimState IO)
addr
  CSocklen
-> (Ptr CSocklen -> IO (Int, ByteArray)) -> IO (Int, ByteArray)
forall a b. Storable a => a -> (Ptr a -> IO b) -> IO b
with (Int -> CSocklen
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
addrlen) ((Ptr CSocklen -> IO (Int, ByteArray)) -> IO (Int, ByteArray))
-> (Ptr CSocklen -> IO (Int, ByteArray)) -> IO (Int, ByteArray)
forall a b. (a -> b) -> a -> b
$ \ Ptr CSocklen
addrlen' -> do
    CSsize
bytesRecv <-
      Fd
-> Ptr Word8
-> CSize
-> MsgFlags
-> MutableByteArray# RealWorld
-> Ptr CSocklen
-> IO CSsize
I.recvfrom Fd
sockfd
                 Ptr Word8
buf (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len)
                 MsgFlags
flags MutableByteArray# RealWorld
addr# Ptr CSocklen
addrlen'
    MutableByteArray (PrimState IO) -> Int -> IO ()
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> Int -> m ()
shrinkMutableByteArray MutableByteArray RealWorld
MutableByteArray (PrimState IO)
addr (Int -> IO ()) -> (CSocklen -> Int) -> CSocklen -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CSocklen -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CSocklen -> IO ()) -> IO CSocklen -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr CSocklen -> IO CSocklen
forall a. Storable a => Ptr a -> IO a
peek Ptr CSocklen
addrlen'
    (CSsize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSsize
bytesRecv,) (ByteArray -> (Int, ByteArray))
-> IO ByteArray -> IO (Int, ByteArray)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MutableByteArray (PrimState IO) -> IO ByteArray
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> m ByteArray
unsafeFreezeByteArray MutableByteArray RealWorld
MutableByteArray (PrimState IO)
addr 

-- | A version of recvfrom that automatically allocates a bytearray
recvsomefrom :: Socket -> Int -> MsgFlags -> IO (ByteArray, Addr)
recvsomefrom :: Socket -> Int -> MsgFlags -> IO (ByteArray, Addr)
recvsomefrom Socket
sock Int
size MsgFlags
flags = do
  MutableByteArray RealWorld
buf <- Int -> IO (MutableByteArray (PrimState IO))
forall (m :: * -> *).
PrimMonad m =>
Int -> m (MutableByteArray (PrimState m))
newByteArray Int
size
  (Int
bytesRecv, ByteArray
addr) <- Socket
-> MutableByteArray RealWorld
-> Int
-> Int
-> MsgFlags
-> IO (Int, ByteArray)
recvfromImpl Socket
sock MutableByteArray RealWorld
buf Int
0 Int
size MsgFlags
flags
  MutableByteArray (PrimState IO) -> Int -> IO ()
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> Int -> m ()
shrinkMutableByteArray MutableByteArray RealWorld
MutableByteArray (PrimState IO)
buf (Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
bytesRecv)
  (, ByteArray -> Addr
mkAddr ByteArray
addr) (ByteArray -> (ByteArray, Addr))
-> IO ByteArray -> IO (ByteArray, Addr)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MutableByteArray (PrimState IO) -> IO ByteArray
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> m ByteArray
unsafeFreezeByteArray MutableByteArray RealWorld
MutableByteArray (PrimState IO)
buf

{- |
Receive messages alongside ancillary data.
The elements of `iovecs` are tuples containing the storage bytearray, offset into bytearray, and
the number of bytes to write to said bytearray.

(See `man 3 recvmsg`)
-}
recvmsg :: Socket -> [(MutableByteArray RealWorld, Int, Int)] -> Int -> MsgFlags -> IO (Int, MsgFlags, [AncillaryData], Addr)
recvmsg :: Socket
-> [(MutableByteArray RealWorld, Int, Int)]
-> Int
-> MsgFlags
-> IO (Int, MsgFlags, [AncillaryData], Addr)
recvmsg (Socket -> Fd
unSocket -> Fd
sockfd) -- ^ The socket to recv message from
        ([(MutableByteArray RealWorld, Int, Int)]
-> ([MutableByteArray RealWorld], [Int], [Int])
forall a b c. [(a, b, c)] -> ([a], [b], [c])
unzip3 -> ([MutableByteArray RealWorld]
iovecs, (Int -> CPtrdiff) -> [Int] -> [CPtrdiff]
forall a b. (a -> b) -> [a] -> [b]
map Int -> CPtrdiff
forall a b. (Integral a, Num b) => a -> b
fromIntegral -> [CPtrdiff]
offs :: [CPtrdiff], (Int -> CSize) -> [Int] -> [CSize]
forall a b. (a -> b) -> [a] -> [b]
map Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral -> [CSize]
size :: [CSize])) -- ^ The storages buffers which will be filled from left to right. Semantics (Buffer, Offset(bytes), Size(Bytes))
        Int
controllen -- ^ Maximum size of ancillary data in bytes.
        MsgFlags
flags      -- ^ Transmission flags
  = do
  MutableByteArray RealWorld
control <- Int -> IO (MutableByteArray (PrimState IO))
forall (m :: * -> *).
PrimMonad m =>
Int -> m (MutableByteArray (PrimState m))
newCmsgBuffer Int
controllen
  name :: MutableByteArray RealWorld
name@(MutableByteArray MutableByteArray# RealWorld
sockaddr#) 
          <- IO (MutableByteArray RealWorld)
IO (MutableByteArray (PrimState IO))
forall (m :: * -> *).
PrimMonad m =>
m (MutableByteArray (PrimState m))
newSockAddrStorage
  Int
namelen <- MutableByteArray (PrimState IO) -> IO Int
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> m Int
getSizeofMutableByteArray MutableByteArray RealWorld
MutableByteArray (PrimState IO)
name
  (ArrayMutableByteArray Array# (MutableByteArray# RealWorld)
iov#) <- (State# (PrimState IO)
 -> (# State# (PrimState IO), ArrayMutableByteArray #))
-> IO ArrayMutableByteArray
forall a.
(State# (PrimState IO) -> (# State# (PrimState IO), a #)) -> IO a
forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
primitive ((State# (PrimState IO)
  -> (# State# (PrimState IO), ArrayMutableByteArray #))
 -> IO ArrayMutableByteArray)
-> (State# (PrimState IO)
    -> (# State# (PrimState IO), ArrayMutableByteArray #))
-> IO ArrayMutableByteArray
forall a b. (a -> b) -> a -> b
$ \ State# (PrimState IO)
state0# -> 
    let !(# State# (PrimState IO)
state1#, MutableByteArray# (PrimState IO)
dummy# #) 
          = Int#
-> State# (PrimState IO)
-> (# State# (PrimState IO), MutableByteArray# (PrimState IO) #)
forall d. Int# -> State# d -> (# State# d, MutableByteArray# d #)
newByteArray# Int#
_0# State# (PrimState IO)
state0# in
    let !(# State# RealWorld
state2#, MutableArray# RealWorld (MutableByteArray# RealWorld)
mutarr# #)
          = Int#
-> MutableByteArray# RealWorld
-> State# RealWorld
-> (# State# RealWorld,
      MutableArray# RealWorld (MutableByteArray# RealWorld) #)
forall a d.
Int# -> a -> State# d -> (# State# d, MutableArray# d a #)
newArray# Int#
iovlen# MutableByteArray# RealWorld
dummy# State# RealWorld
state1# in
    let !(State State# RealWorld
state4#, Int
_)
          = ((State RealWorld, Int)
 -> MutableByteArray RealWorld -> (State RealWorld, Int))
-> (State RealWorld, Int)
-> [MutableByteArray RealWorld]
-> (State RealWorld, Int)
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl (\ (State State# RealWorld
state3#, idx :: Int
idx@(I# Int#
idx#)) (MutableByteArray MutableByteArray# RealWorld
ba#) -> (State# RealWorld -> State RealWorld
forall s. State# s -> State s
State (MutableArray# RealWorld (MutableByteArray# RealWorld)
-> Int#
-> MutableByteArray# RealWorld
-> State# RealWorld
-> State# RealWorld
forall d a. MutableArray# d a -> Int# -> a -> State# d -> State# d
writeArray# MutableArray# RealWorld (MutableByteArray# RealWorld)
mutarr# Int#
idx# MutableByteArray# RealWorld
ba# State# RealWorld
state3#), Int
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1))
                  (State# RealWorld -> State RealWorld
forall s. State# s -> State s
State State# RealWorld
state2#, Int
0)
                  [MutableByteArray RealWorld]
iovecs in
    let !(# State# RealWorld
state5#, Array# (MutableByteArray# RealWorld)
arr# #)
          = MutableArray# RealWorld (MutableByteArray# RealWorld)
-> State# RealWorld
-> (# State# RealWorld, Array# (MutableByteArray# RealWorld) #)
forall d a.
MutableArray# d a -> State# d -> (# State# d, Array# a #)
unsafeFreezeArray# MutableArray# RealWorld (MutableByteArray# RealWorld)
mutarr# State# RealWorld
state4# in
    (# State# RealWorld
State# (PrimState IO)
state5#, Array# (MutableByteArray# RealWorld) -> ArrayMutableByteArray
ArrayMutableByteArray Array# (MutableByteArray# RealWorld)
arr# #)
  (Int
bytesRecv, MsgFlags
newFlags, CSize
newControllen, CSocklen
newNamelen) <-
    MutableByteArray (PrimState IO)
-> (Ptr Word8 -> IO (Int, MsgFlags, CSize, CSocklen))
-> IO (Int, MsgFlags, CSize, CSocklen)
forall (m :: * -> *) a.
PrimBase m =>
MutableByteArray (PrimState m) -> (Ptr Word8 -> m a) -> m a
withMutableByteArrayContents MutableByteArray RealWorld
MutableByteArray (PrimState IO)
control ((Ptr Word8 -> IO (Int, MsgFlags, CSize, CSocklen))
 -> IO (Int, MsgFlags, CSize, CSocklen))
-> (Ptr Word8 -> IO (Int, MsgFlags, CSize, CSocklen))
-> IO (Int, MsgFlags, CSize, CSocklen)
forall a b. (a -> b) -> a -> b
$ \ Ptr Word8
control' ->
    CSize
-> (Ptr CSize -> IO (Int, MsgFlags, CSize, CSocklen))
-> IO (Int, MsgFlags, CSize, CSocklen)
forall a b. Storable a => a -> (Ptr a -> IO b) -> IO b
with (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
controllen) ((Ptr CSize -> IO (Int, MsgFlags, CSize, CSocklen))
 -> IO (Int, MsgFlags, CSize, CSocklen))
-> (Ptr CSize -> IO (Int, MsgFlags, CSize, CSocklen))
-> IO (Int, MsgFlags, CSize, CSocklen)
forall a b. (a -> b) -> a -> b
$ \ Ptr CSize
controllen' ->
    CSocklen
-> (Ptr CSocklen -> IO (Int, MsgFlags, CSize, CSocklen))
-> IO (Int, MsgFlags, CSize, CSocklen)
forall a b. Storable a => a -> (Ptr a -> IO b) -> IO b
with (Int -> CSocklen
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
namelen) ((Ptr CSocklen -> IO (Int, MsgFlags, CSize, CSocklen))
 -> IO (Int, MsgFlags, CSize, CSocklen))
-> (Ptr CSocklen -> IO (Int, MsgFlags, CSize, CSocklen))
-> IO (Int, MsgFlags, CSize, CSocklen)
forall a b. (a -> b) -> a -> b
$ \ Ptr CSocklen
namelen' ->
    MsgFlags
-> (Ptr MsgFlags -> IO (Int, MsgFlags, CSize, CSocklen))
-> IO (Int, MsgFlags, CSize, CSocklen)
forall a b. Storable a => a -> (Ptr a -> IO b) -> IO b
with MsgFlags
flags ((Ptr MsgFlags -> IO (Int, MsgFlags, CSize, CSocklen))
 -> IO (Int, MsgFlags, CSize, CSocklen))
-> (Ptr MsgFlags -> IO (Int, MsgFlags, CSize, CSocklen))
-> IO (Int, MsgFlags, CSize, CSocklen)
forall a b. (a -> b) -> a -> b
$ \ Ptr MsgFlags
flags' -> do
      Int
bytesRecv <- CSsize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CSsize -> Int) -> IO CSsize -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> 
        Fd
-> MutableByteArray# RealWorld
-> Ptr CSocklen
-> Array# (MutableByteArray# RealWorld)
-> ByteArray#
-> ByteArray#
-> CSize
-> Ptr Word8
-> Ptr CSize
-> Ptr MsgFlags
-> IO CSsize
forall a.
Fd
-> MutableByteArray# RealWorld
-> Ptr CSocklen
-> Array# (MutableByteArray# RealWorld)
-> ByteArray#
-> ByteArray#
-> CSize
-> Ptr a
-> Ptr CSize
-> Ptr MsgFlags
-> IO CSsize
I.recvmsg# Fd
sockfd
                   MutableByteArray# RealWorld
sockaddr# Ptr CSocklen
namelen'
                   Array# (MutableByteArray# RealWorld)
iov# ByteArray#
offs# ByteArray#
size# (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
iovlen)
                   Ptr Word8
control' Ptr CSize
controllen'
                   Ptr MsgFlags
flags'
      MsgFlags
newFlags   <- Ptr MsgFlags -> IO MsgFlags
forall a. Storable a => Ptr a -> IO a
peek Ptr MsgFlags
flags'
      CSize
newControllen
                 <- Ptr CSize -> IO CSize
forall a. Storable a => Ptr a -> IO a
peek Ptr CSize
controllen'
      CSocklen
newNamelen <- Ptr CSocklen -> IO CSocklen
forall a. Storable a => Ptr a -> IO a
peek Ptr CSocklen
namelen'
      (Int, MsgFlags, CSize, CSocklen)
-> IO (Int, MsgFlags, CSize, CSocklen)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Int
bytesRecv, MsgFlags
newFlags, CSize
newControllen, CSocklen
newNamelen)
  MutableByteArray (PrimState IO) -> Int -> IO ()
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> Int -> m ()
shrinkMutableByteArray MutableByteArray RealWorld
MutableByteArray (PrimState IO)
name (CSocklen -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSocklen
newNamelen)
  MutableByteArray (PrimState IO) -> Int -> IO ()
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> Int -> m ()
shrinkMutableByteArray MutableByteArray RealWorld
MutableByteArray (PrimState IO)
control (CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
newControllen)

  ByteArray
frozenName    <- MutableByteArray (PrimState IO) -> IO ByteArray
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> m ByteArray
unsafeFreezeByteArray MutableByteArray RealWorld
MutableByteArray (PrimState IO)
name
  ByteArray
frozenControl <- MutableByteArray (PrimState IO) -> IO ByteArray
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> m ByteArray
unsafeFreezeByteArray MutableByteArray RealWorld
MutableByteArray (PrimState IO)
control
  (Int, MsgFlags, [AncillaryData], Addr)
-> IO (Int, MsgFlags, [AncillaryData], Addr)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Int
bytesRecv, MsgFlags
newFlags, ByteArray -> [AncillaryData]
decodeAncillaryData ByteArray
frozenControl, ByteArray -> Addr
mkAddr ByteArray
frozenName)
  where !iovlen :: Int
iovlen@(I# Int#
iovlen#) = [MutableByteArray RealWorld] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [MutableByteArray RealWorld]
iovecs
        !(I# Int#
_0#) = Int
0
        !(PrimArray ByteArray#
offs#) = [Item (PrimArray CPtrdiff)] -> PrimArray CPtrdiff
forall l. IsList l => [Item l] -> l
fromList [CPtrdiff]
[Item (PrimArray CPtrdiff)]
offs
        !(PrimArray ByteArray#
size#) = [Item (PrimArray CSize)] -> PrimArray CSize
forall l. IsList l => [Item l] -> l
fromList [CSize]
[Item (PrimArray CSize)]
size

-- | A version of `recvmsg` that does not return the address
recvmsg_ :: Socket -> [(MutableByteArray RealWorld, Int, Int)] -> Int -> MsgFlags -> IO (Int, MsgFlags, [AncillaryData])
recvmsg_ :: Socket
-> [(MutableByteArray RealWorld, Int, Int)]
-> Int
-> MsgFlags
-> IO (Int, MsgFlags, [AncillaryData])
recvmsg_ (Socket -> Fd
unSocket -> Fd
sockfd) ([(MutableByteArray RealWorld, Int, Int)]
-> ([MutableByteArray RealWorld], [Int], [Int])
forall a b c. [(a, b, c)] -> ([a], [b], [c])
unzip3 -> ([MutableByteArray RealWorld]
iovecs, (Int -> CPtrdiff) -> [Int] -> [CPtrdiff]
forall a b. (a -> b) -> [a] -> [b]
map Int -> CPtrdiff
forall a b. (Integral a, Num b) => a -> b
fromIntegral -> [CPtrdiff]
offs :: [CPtrdiff], (Int -> CSize) -> [Int] -> [CSize]
forall a b. (a -> b) -> [a] -> [b]
map Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral -> [CSize]
size :: [CSize])) Int
controllen MsgFlags
flags = do
  MutableByteArray RealWorld
control <- Int -> IO (MutableByteArray (PrimState IO))
forall (m :: * -> *).
PrimMonad m =>
Int -> m (MutableByteArray (PrimState m))
newCmsgBuffer Int
controllen
  (MutableByteArray MutableByteArray# RealWorld
sockaddr#) 
          <- Int -> IO (MutableByteArray (PrimState IO))
forall (m :: * -> *).
PrimMonad m =>
Int -> m (MutableByteArray (PrimState m))
newByteArray Int
0
  let namelen :: CSocklen
namelen = CSocklen
0 
  (ArrayMutableByteArray Array# (MutableByteArray# RealWorld)
iov#) <- (State# (PrimState IO)
 -> (# State# (PrimState IO), ArrayMutableByteArray #))
-> IO ArrayMutableByteArray
forall a.
(State# (PrimState IO) -> (# State# (PrimState IO), a #)) -> IO a
forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
primitive ((State# (PrimState IO)
  -> (# State# (PrimState IO), ArrayMutableByteArray #))
 -> IO ArrayMutableByteArray)
-> (State# (PrimState IO)
    -> (# State# (PrimState IO), ArrayMutableByteArray #))
-> IO ArrayMutableByteArray
forall a b. (a -> b) -> a -> b
$ \ State# (PrimState IO)
state0# -> 
    let !(# State# (PrimState IO)
state1#, MutableByteArray# (PrimState IO)
dummy# #) 
          = Int#
-> State# (PrimState IO)
-> (# State# (PrimState IO), MutableByteArray# (PrimState IO) #)
forall d. Int# -> State# d -> (# State# d, MutableByteArray# d #)
newByteArray# Int#
_0# State# (PrimState IO)
state0# in
    let !(# State# RealWorld
state2#, MutableArray# RealWorld (MutableByteArray# RealWorld)
mutarr# #)
          = Int#
-> MutableByteArray# RealWorld
-> State# RealWorld
-> (# State# RealWorld,
      MutableArray# RealWorld (MutableByteArray# RealWorld) #)
forall a d.
Int# -> a -> State# d -> (# State# d, MutableArray# d a #)
newArray# Int#
iovlen# MutableByteArray# RealWorld
dummy# State# RealWorld
state1# in
    let !(State State# RealWorld
state4#, Int
_)
          = ((State RealWorld, Int)
 -> MutableByteArray RealWorld -> (State RealWorld, Int))
-> (State RealWorld, Int)
-> [MutableByteArray RealWorld]
-> (State RealWorld, Int)
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl (\ (State State# RealWorld
state3#, idx :: Int
idx@(I# Int#
idx#)) (MutableByteArray MutableByteArray# RealWorld
ba#) -> (State# RealWorld -> State RealWorld
forall s. State# s -> State s
State (MutableArray# RealWorld (MutableByteArray# RealWorld)
-> Int#
-> MutableByteArray# RealWorld
-> State# RealWorld
-> State# RealWorld
forall d a. MutableArray# d a -> Int# -> a -> State# d -> State# d
writeArray# MutableArray# RealWorld (MutableByteArray# RealWorld)
mutarr# Int#
idx# MutableByteArray# RealWorld
ba# State# RealWorld
state3#), Int
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1))
                  (State# RealWorld -> State RealWorld
forall s. State# s -> State s
State State# RealWorld
state2#, Int
0)
                  [MutableByteArray RealWorld]
iovecs in
    let !(# State# RealWorld
state5#, Array# (MutableByteArray# RealWorld)
arr# #)
          = MutableArray# RealWorld (MutableByteArray# RealWorld)
-> State# RealWorld
-> (# State# RealWorld, Array# (MutableByteArray# RealWorld) #)
forall d a.
MutableArray# d a -> State# d -> (# State# d, Array# a #)
unsafeFreezeArray# MutableArray# RealWorld (MutableByteArray# RealWorld)
mutarr# State# RealWorld
state4# in
    (# State# RealWorld
State# (PrimState IO)
state5#, Array# (MutableByteArray# RealWorld) -> ArrayMutableByteArray
ArrayMutableByteArray Array# (MutableByteArray# RealWorld)
arr# #)
  (Int
bytesRecv, MsgFlags
newFlags, CSize
newControllen) <-
    MutableByteArray (PrimState IO)
-> (Ptr Word8 -> IO (Int, MsgFlags, CSize))
-> IO (Int, MsgFlags, CSize)
forall (m :: * -> *) a.
PrimBase m =>
MutableByteArray (PrimState m) -> (Ptr Word8 -> m a) -> m a
withMutableByteArrayContents MutableByteArray RealWorld
MutableByteArray (PrimState IO)
control ((Ptr Word8 -> IO (Int, MsgFlags, CSize))
 -> IO (Int, MsgFlags, CSize))
-> (Ptr Word8 -> IO (Int, MsgFlags, CSize))
-> IO (Int, MsgFlags, CSize)
forall a b. (a -> b) -> a -> b
$ \ Ptr Word8
control' ->
    CSize
-> (Ptr CSize -> IO (Int, MsgFlags, CSize))
-> IO (Int, MsgFlags, CSize)
forall a b. Storable a => a -> (Ptr a -> IO b) -> IO b
with (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
controllen) ((Ptr CSize -> IO (Int, MsgFlags, CSize))
 -> IO (Int, MsgFlags, CSize))
-> (Ptr CSize -> IO (Int, MsgFlags, CSize))
-> IO (Int, MsgFlags, CSize)
forall a b. (a -> b) -> a -> b
$ \ Ptr CSize
controllen' ->
    CSocklen
-> (Ptr CSocklen -> IO (Int, MsgFlags, CSize))
-> IO (Int, MsgFlags, CSize)
forall a b. Storable a => a -> (Ptr a -> IO b) -> IO b
with CSocklen
namelen ((Ptr CSocklen -> IO (Int, MsgFlags, CSize))
 -> IO (Int, MsgFlags, CSize))
-> (Ptr CSocklen -> IO (Int, MsgFlags, CSize))
-> IO (Int, MsgFlags, CSize)
forall a b. (a -> b) -> a -> b
$ \ Ptr CSocklen
namelen' ->
    MsgFlags
-> (Ptr MsgFlags -> IO (Int, MsgFlags, CSize))
-> IO (Int, MsgFlags, CSize)
forall a b. Storable a => a -> (Ptr a -> IO b) -> IO b
with MsgFlags
flags ((Ptr MsgFlags -> IO (Int, MsgFlags, CSize))
 -> IO (Int, MsgFlags, CSize))
-> (Ptr MsgFlags -> IO (Int, MsgFlags, CSize))
-> IO (Int, MsgFlags, CSize)
forall a b. (a -> b) -> a -> b
$ \ Ptr MsgFlags
flags' -> do
      Int
bytesRecv <- CSsize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CSsize -> Int) -> IO CSsize -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> 
        Fd
-> MutableByteArray# RealWorld
-> Ptr CSocklen
-> Array# (MutableByteArray# RealWorld)
-> ByteArray#
-> ByteArray#
-> CSize
-> Ptr Word8
-> Ptr CSize
-> Ptr MsgFlags
-> IO CSsize
forall a.
Fd
-> MutableByteArray# RealWorld
-> Ptr CSocklen
-> Array# (MutableByteArray# RealWorld)
-> ByteArray#
-> ByteArray#
-> CSize
-> Ptr a
-> Ptr CSize
-> Ptr MsgFlags
-> IO CSsize
I.recvmsg# Fd
sockfd
                   MutableByteArray# RealWorld
sockaddr# Ptr CSocklen
namelen'
                   Array# (MutableByteArray# RealWorld)
iov# ByteArray#
offs# ByteArray#
size# (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
iovlen)
                   Ptr Word8
control' Ptr CSize
controllen'
                   Ptr MsgFlags
flags'
      MsgFlags
newFlags   <- Ptr MsgFlags -> IO MsgFlags
forall a. Storable a => Ptr a -> IO a
peek Ptr MsgFlags
flags'
      CSize
newControllen
                 <- Ptr CSize -> IO CSize
forall a. Storable a => Ptr a -> IO a
peek Ptr CSize
controllen'
      (Int, MsgFlags, CSize) -> IO (Int, MsgFlags, CSize)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Int
bytesRecv, MsgFlags
newFlags, CSize
newControllen)
  MutableByteArray (PrimState IO) -> Int -> IO ()
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> Int -> m ()
shrinkMutableByteArray MutableByteArray RealWorld
MutableByteArray (PrimState IO)
control (CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
newControllen)
  ByteArray
frozenControl <- MutableByteArray (PrimState IO) -> IO ByteArray
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> m ByteArray
unsafeFreezeByteArray MutableByteArray RealWorld
MutableByteArray (PrimState IO)
control
  (Int, MsgFlags, [AncillaryData])
-> IO (Int, MsgFlags, [AncillaryData])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Int
bytesRecv, MsgFlags
newFlags, ByteArray -> [AncillaryData]
decodeAncillaryData ByteArray
frozenControl)
  where !iovlen :: Int
iovlen@(I# Int#
iovlen#) = [MutableByteArray RealWorld] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [MutableByteArray RealWorld]
iovecs
        !(I# Int#
_0#) = Int
0
        !(PrimArray ByteArray#
offs#) = [Item (PrimArray CPtrdiff)] -> PrimArray CPtrdiff
forall l. IsList l => [Item l] -> l
fromList [CPtrdiff]
[Item (PrimArray CPtrdiff)]
offs
        !(PrimArray ByteArray#
size#) = [Item (PrimArray CSize)] -> PrimArray CSize
forall l. IsList l => [Item l] -> l
fromList [CSize]
[Item (PrimArray CSize)]
size

-- | Shutdown all or part of of a duplex connection
shutdown :: Socket -> ShutHow -> IO ()
shutdown :: Socket -> ShutHow -> IO ()
shutdown = Fd -> ShutHow -> IO ()
I.shutdown (Fd -> ShutHow -> IO ())
-> (Socket -> Fd) -> Socket -> ShutHow -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Socket -> Fd
unSocket