1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
|
{- This is a subset of the functions provided by file-io, supplimented with
- readFileString, writeFileString, and appendFileString.
-
- When building with file-io, all exported functions set the close-on-exec
- flag. Also, some other issues are handled that file-io does not handle
- correctly.
-
- When not building with file-io, this provides equvilant
- RawFilePath versions. Note that those versions do not currently
- set the close-on-exec flag.
-
- Since Prelude exports many of these as well, this needs to be imported
- qualified.
-
- Copyright 2025 Joey Hess <id@joeyh.name>
-
- License: BSD-2-clause
-}
{-# OPTIONS_GHC -fno-warn-tabs #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE NoImplicitPrelude #-}
module Utility.FileIO
(
withFile,
openFile,
withBinaryFile,
openBinaryFile,
readFile,
readFile',
writeFile,
writeFile',
appendFile,
appendFile',
openTempFile,
readFileString,
writeFileString,
appendFileString,
) where
#ifdef WITH_OSPATH
#ifndef mingw32_HOST_OS
import Utility.FileIO.CloseOnExec
import Utility.FileIO.String
#else
-- On Windows, System.File.OsPath does not handle UNC-style conversion itself,
-- so that has to be done when calling it. See
-- https://github.com/haskell/file-io/issues/39
import Utility.Path.Windows
import Utility.OsPath
import System.IO (IO, Handle, IOMode)
import Prelude (String, return)
import qualified Utility.FileIO.CloseOnExec as O
import qualified Utility.FileIO.String as O
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as L
import Control.Applicative
withFile :: OsPath -> IOMode -> (Handle -> IO r) -> IO r
withFile f m a = do
f' <- toOsPath <$> convertToWindowsNativeNamespace (fromOsPath f)
O.withFile f' m a
openFile :: OsPath -> IOMode -> IO Handle
openFile f m = do
f' <- toOsPath <$> convertToWindowsNativeNamespace (fromOsPath f)
O.openFile f' m
withBinaryFile :: OsPath -> IOMode -> (Handle -> IO r) -> IO r
withBinaryFile f m a = do
f' <- toOsPath <$> convertToWindowsNativeNamespace (fromOsPath f)
O.withBinaryFile f' m a
openBinaryFile :: OsPath -> IOMode -> IO Handle
openBinaryFile f m = do
f' <- toOsPath <$> convertToWindowsNativeNamespace (fromOsPath f)
O.openBinaryFile f' m
readFile :: OsPath -> IO L.ByteString
readFile f = do
f' <- toOsPath <$> convertToWindowsNativeNamespace (fromOsPath f)
O.readFile f'
readFile' :: OsPath -> IO B.ByteString
readFile' f = do
f' <- toOsPath <$> convertToWindowsNativeNamespace (fromOsPath f)
O.readFile' f'
writeFile :: OsPath -> L.ByteString -> IO ()
writeFile f b = do
f' <- toOsPath <$> convertToWindowsNativeNamespace (fromOsPath f)
O.writeFile f' b
writeFile' :: OsPath -> B.ByteString -> IO ()
writeFile' f b = do
f' <- toOsPath <$> convertToWindowsNativeNamespace (fromOsPath f)
O.writeFile' f' b
appendFile :: OsPath -> L.ByteString -> IO ()
appendFile f b = do
f' <- toOsPath <$> convertToWindowsNativeNamespace (fromOsPath f)
O.appendFile f' b
appendFile' :: OsPath -> B.ByteString -> IO ()
appendFile' f b = do
f' <- toOsPath <$> convertToWindowsNativeNamespace (fromOsPath f)
O.appendFile' f' b
openTempFile :: OsPath -> OsPath -> IO (OsPath, Handle)
openTempFile p s = do
p' <- toOsPath <$> convertToWindowsNativeNamespace (fromOsPath p)
(t, h) <- O.openTempFile p' s
-- Avoid returning mangled path from convertToWindowsNativeNamespace
let t' = p </> takeFileName t
return (t', h)
readFileString :: OsPath -> IO String
readFileString p = do
p' <- toOsPath <$> convertToWindowsNativeNamespace (fromOsPath p)
O.readFileString p'
writeFileString :: OsPath -> String -> IO ()
writeFileString f txt = do
f' <- toOsPath <$> convertToWindowsNativeNamespace (fromOsPath f)
O.writeFileString f' txt
appendFileString :: OsPath -> String -> IO ()
appendFileString f txt = do
f' <- toOsPath <$> convertToWindowsNativeNamespace (fromOsPath f)
O.appendFileString f' txt
#endif
#else
-- RawFilePath versions
import Utility.OsPath
import Utility.FileSystemEncoding
import System.IO (IO, Handle, IOMode)
import Prelude (String, (.), return)
import qualified Prelude as P
import qualified System.IO
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as L
withFile :: OsPath -> IOMode -> (Handle -> IO r) -> IO r
withFile = System.IO.withFile . fromRawFilePath
openFile :: OsPath -> IOMode -> IO Handle
openFile = System.IO.openFile . fromRawFilePath
withBinaryFile :: OsPath -> IOMode -> (Handle -> IO r) -> IO r
withBinaryFile = System.IO.withBinaryFile . fromRawFilePath
openBinaryFile :: OsPath -> IOMode -> IO Handle
openBinaryFile = System.IO.openBinaryFile . fromRawFilePath
readFile :: OsPath -> IO L.ByteString
readFile = L.readFile . fromRawFilePath
readFile' :: OsPath -> IO B.ByteString
readFile' = B.readFile . fromRawFilePath
writeFile :: OsPath -> L.ByteString -> IO ()
writeFile = L.writeFile . fromRawFilePath
writeFile' :: OsPath -> B.ByteString -> IO ()
writeFile' = B.writeFile . fromRawFilePath
appendFile :: OsPath -> L.ByteString -> IO ()
appendFile = L.appendFile . fromRawFilePath
appendFile' :: OsPath -> B.ByteString -> IO ()
appendFile' = B.appendFile . fromRawFilePath
openTempFile :: OsPath -> OsPath -> IO (OsPath, Handle)
openTempFile p s = do
(t, h) <- System.IO.openTempFile
(fromRawFilePath p)
(fromRawFilePath s)
return (toRawFilePath t, h)
readFileString :: OsPath -> IO String
readFileString = P.readFile . fromRawFilePath
writeFileString :: OsPath -> String -> IO ()
writeFileString = P.writeFile . fromRawFilePath
appendFileString :: OsPath -> String -> IO ()
appendFileString = P.appendFile . fromRawFilePath
#endif
|