module SendFile.Internal (
fileSize,
sendFile,
sendFile',
sendFileMode
) where
import System.IO (
Handle(..),
IOMode(..),
SeekMode(..),
hFileSize,
hFlush,
hSeek,
withBinaryFile
)
import Foreign.C
import GHC.IOBase (haFD)
import GHC.Handle (withHandle_)
sendFileMode :: String
sendFileMode = "LINUX_SENDFILE"
sendFile' :: Handle -> FilePath -> Int -> Int -> IO ()
sendFile' outh infp offset count = do
hFlush outh
withHandle_ "sendFile" outh $ \outh' -> do
withCString infp $ \in_fp -> do
let out_fd = haFD outh'
err <- c_sendfile_linux out_fd in_fp (fromIntegral offset) (fromIntegral count)
if err == 0
then return ()
else fail ("errno " ++ show err)
foreign import ccall
c_sendfile_linux :: CInt -> CString -> CLong -> CLong -> IO Int
fileSize :: FilePath -> IO Int
fileSize fp = fmap fromIntegral (withBinaryFile fp ReadMode hFileSize)
sendFile :: Handle -> FilePath -> IO ()
sendFile outh infp = do
count <- fileSize infp
sendFile' outh infp 0 count