File.hs 1.1 KB

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