File.hs 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. -- | UniformIO functions for file access
  2. module System.IO.Uniform.File (
  3. FileIO,
  4. openFile
  5. ) where
  6. import System.IO.Uniform
  7. import System.IO.Uniform.External
  8. import Foreign
  9. import Foreign.C.String
  10. import Foreign.C.Error
  11. import qualified Data.ByteString as BS
  12. import Control.Monad
  13. import System.Posix.Types (Fd(..))
  14. -- | UniformIO type for file IO.
  15. instance UniformIO FileIO where
  16. uRead s n = allocaArray n (
  17. \b -> do
  18. count <- c_recv (fd s) b $ fromIntegral n
  19. if count < 0
  20. then throwErrno "could not read"
  21. else BS.packCStringLen (b, fromIntegral count)
  22. )
  23. uPut s t = BS.useAsCStringLen t (
  24. \(str, n) -> do
  25. count <- c_send (fd s) str $ fromIntegral n
  26. when (count < 0) $ throwErrno "could not write"
  27. )
  28. uClose s = do
  29. f <- Fd <$> c_prepareToClose (fd s)
  30. closeFd f
  31. startTls _ = return
  32. isSecure _ = True
  33. isEOF s = c_isDsEof . fd $ s
  34. -- | Open a file for bidirectional IO.
  35. openFile :: String -> IO FileIO
  36. openFile fileName = do
  37. r <- withCString fileName (
  38. fmap FileIO . c_createFile
  39. )
  40. if fd r == nullPtr
  41. then throwErrno "could not open file"
  42. else return r