{-# LINE 1 "src/System/SendFile/Linux.hsc" #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE ForeignFunctionInterface #-}
module System.SendFile.Linux
( sendFile
, sendFileImpl
, sendFileMode
) where
import Control.Concurrent (threadWaitWrite)
import Data.Int (Int64)
import Data.Word (Word64)
import Foreign.C.Error (throwErrnoIfMinus1RetryMayBlock)
{-# LINE 19 "src/System/SendFile/Linux.hsc" #-}
import Foreign.C.Types (CInt (..), CSize (..))
{-# LINE 23 "src/System/SendFile/Linux.hsc" #-}
import Foreign.Marshal (alloca)
import Foreign.Ptr (Ptr, nullPtr)
import Foreign.Storable (poke)
{-# LINE 27 "src/System/SendFile/Linux.hsc" #-}
import System.Posix.Types (COff (..), CSsize (..), Fd (..))
{-# LINE 31 "src/System/SendFile/Linux.hsc" #-}
sendFile :: Fd -> Fd -> Word64 -> Word64 -> IO Int64
sendFile = sendFileImpl c_sendfile threadWaitWrite
{-# INLINE sendFile #-}
sendFileImpl :: (Fd -> Fd -> Ptr COff -> CSize -> IO CSsize)
-> (Fd -> IO ())
-> Fd -> Fd -> Word64 -> Word64 -> IO Int64
sendFileImpl !raw_sendfile !wait out_fd in_fd off count
| count <= 0 = return 0
| off == 0 = do
nsent <- sendfile raw_sendfile wait out_fd in_fd nullPtr bytes
return $! fromIntegral nsent
| otherwise = alloca $ \poff -> do
poke poff (fromIntegral off)
nsent <- sendfile raw_sendfile wait out_fd in_fd poff bytes
return $! fromIntegral nsent
where
bytes = fromIntegral count
{-# INLINE sendFileImpl #-}
sendfile :: (Fd -> Fd -> Ptr COff -> CSize -> IO CSsize)
-> (Fd -> IO ())
-> Fd -> Fd -> Ptr COff -> CSize -> IO CSsize
sendfile raw_sendfile wait out_fd in_fd poff bytes =
throwErrnoIfMinus1RetryMayBlock
"sendfile"
(raw_sendfile out_fd in_fd poff bytes)
(wait out_fd)
{-# INLINE sendfile #-}
foreign import ccall unsafe "sys/sendfile.h sendfile64" c_sendfile
:: Fd -> Fd -> Ptr COff -> CSize -> IO CSsize
sendFileMode :: String
sendFileMode = "LINUX_SENDFILE"