sendfile-0.3: src/Network/Socket/SendFile/Win32.hsc
{-# LANGUAGE ForeignFunctionInterface #-}
-- | Win32 system-dependent code for 'TransmitFile'.
module Network.Socket.SendFile.Win32 (sendFile') where
import Data.Int
import Data.Word
import Foreign.C.Error (throwErrno)
import Foreign.Ptr (IntPtr, intPtrToPtr)
import GHC.Handle (withHandle_)
import GHC.IOBase (FD, haFD)
import System.IO (Handle, hFlush)
import System.Win32.Types
#include <windows.h>
sendFile' :: Handle -> Handle -> Integer -> IO ()
sendFile' outp inp count = do
hFlush outp -- flush the buffer before invoking transmitFile
withHandle_ "Network.Socket.SendFile.Win32.sendFile'" outp $ \outp' -> do
withHandle_ "Network.Socket.SendFile.Win32.sendFile'" inp $ \inp' -> do
let out_fd = haFD outp'
in_hdl <- get_osfhandle (haFD inp')
transmitFile (fromIntegral out_fd) in_hdl (fromIntegral count)
get_osfhandle :: FD -- ^ User file descriptor.
-> IO HANDLE -- ^ The operating-system file handle.
get_osfhandle fd = do
res <- c_get_osfhandle fd
if res == (#const INVALID_HANDLE_VALUE)
then throwErrno "Network.Socket.SendFile.Win32.get_osfhandle"
else return (intPtrToPtr res)
transmitFile :: FD -- ^ A handle to a connected socket.
-> HANDLE -- ^ A handle to the open file that the TransmitFile function transmits.
-> DWORD -- ^ The number of bytes in the file to transmit.
-> IO ()
transmitFile out_fd in_hdl count =
failIf_ (== 0) "Network.Socket.SendFile.Win32.transmitFile" (c_TransmitFile out_fd in_hdl count)
foreign import ccall
c_get_osfhandle :: FD -> IO IntPtr
foreign import ccall
c_TransmitFile :: FD -> HANDLE -> DWORD -> IO (#type BOOL)