more OsPath conversion
Sponsored-by: Nicholas Golder-Manning
This commit is contained in:
parent
0376bc5ee0
commit
27305042f3
24 changed files with 180 additions and 153 deletions
|
@ -16,6 +16,7 @@ module Utility.FileIO
|
|||
(
|
||||
withFile,
|
||||
openFile,
|
||||
withBinaryFile,
|
||||
openBinaryFile,
|
||||
readFile,
|
||||
readFile',
|
||||
|
@ -52,6 +53,11 @@ 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)
|
||||
|
@ -110,6 +116,9 @@ 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
|
||||
|
||||
|
|
|
@ -25,26 +25,27 @@ import Foreign (complement)
|
|||
import Control.Monad.Catch
|
||||
|
||||
import Utility.Exception
|
||||
import Utility.FileSystemEncoding
|
||||
import qualified Utility.RawFilePath as R
|
||||
import qualified Utility.FileIO as F
|
||||
import Utility.OsPath
|
||||
|
||||
{- Applies a conversion function to a file's mode. -}
|
||||
modifyFileMode :: RawFilePath -> (FileMode -> FileMode) -> IO ()
|
||||
modifyFileMode :: OsPath -> (FileMode -> FileMode) -> IO ()
|
||||
modifyFileMode f convert = void $ modifyFileMode' f convert
|
||||
|
||||
modifyFileMode' :: RawFilePath -> (FileMode -> FileMode) -> IO FileMode
|
||||
modifyFileMode' :: OsPath -> (FileMode -> FileMode) -> IO FileMode
|
||||
modifyFileMode' f convert = do
|
||||
s <- R.getFileStatus f
|
||||
s <- R.getFileStatus f'
|
||||
let old = fileMode s
|
||||
let new = convert old
|
||||
when (new /= old) $
|
||||
R.setFileMode f new
|
||||
R.setFileMode f' new
|
||||
return old
|
||||
where
|
||||
f' = fromOsPath f
|
||||
|
||||
{- Runs an action after changing a file's mode, then restores the old mode. -}
|
||||
withModifiedFileMode :: RawFilePath -> (FileMode -> FileMode) -> IO a -> IO a
|
||||
withModifiedFileMode :: OsPath -> (FileMode -> FileMode) -> IO a -> IO a
|
||||
withModifiedFileMode file convert a = bracket setup cleanup go
|
||||
where
|
||||
setup = modifyFileMode' file convert
|
||||
|
@ -77,15 +78,15 @@ otherGroupModes =
|
|||
]
|
||||
|
||||
{- Removes the write bits from a file. -}
|
||||
preventWrite :: RawFilePath -> IO ()
|
||||
preventWrite :: OsPath -> IO ()
|
||||
preventWrite f = modifyFileMode f $ removeModes writeModes
|
||||
|
||||
{- Turns a file's owner write bit back on. -}
|
||||
allowWrite :: RawFilePath -> IO ()
|
||||
allowWrite :: OsPath -> IO ()
|
||||
allowWrite f = modifyFileMode f $ addModes [ownerWriteMode]
|
||||
|
||||
{- Turns a file's owner read bit back on. -}
|
||||
allowRead :: RawFilePath -> IO ()
|
||||
allowRead :: OsPath -> IO ()
|
||||
allowRead f = modifyFileMode f $ addModes [ownerReadMode]
|
||||
|
||||
{- Allows owner and group to read and write to a file. -}
|
||||
|
@ -95,7 +96,7 @@ groupSharedModes =
|
|||
, ownerReadMode, groupReadMode
|
||||
]
|
||||
|
||||
groupWriteRead :: RawFilePath -> IO ()
|
||||
groupWriteRead :: OsPath -> IO ()
|
||||
groupWriteRead f = modifyFileMode f $ addModes groupSharedModes
|
||||
|
||||
checkMode :: FileMode -> FileMode -> Bool
|
||||
|
@ -105,13 +106,13 @@ checkMode checkfor mode = checkfor `intersectFileModes` mode == checkfor
|
|||
isExecutable :: FileMode -> Bool
|
||||
isExecutable mode = combineModes executeModes `intersectFileModes` mode /= 0
|
||||
|
||||
data ModeSetter = ModeSetter FileMode (RawFilePath -> IO ())
|
||||
data ModeSetter = ModeSetter FileMode (OsPath -> IO ())
|
||||
|
||||
{- Runs an action which should create the file, passing it the desired
|
||||
- initial file mode. Then runs the ModeSetter's action on the file, which
|
||||
- can adjust the initial mode if umask prevented the file from being
|
||||
- created with the right mode. -}
|
||||
applyModeSetter :: Maybe ModeSetter -> RawFilePath -> (Maybe FileMode -> IO a) -> IO a
|
||||
applyModeSetter :: Maybe ModeSetter -> OsPath -> (Maybe FileMode -> IO a) -> IO a
|
||||
applyModeSetter (Just (ModeSetter mode modeaction)) file a = do
|
||||
r <- a (Just mode)
|
||||
void $ tryIO $ modeaction file
|
||||
|
@ -159,7 +160,7 @@ isSticky = checkMode stickyMode
|
|||
stickyMode :: FileMode
|
||||
stickyMode = 512
|
||||
|
||||
setSticky :: RawFilePath -> IO ()
|
||||
setSticky :: OsPath -> IO ()
|
||||
setSticky f = modifyFileMode f $ addModes [stickyMode]
|
||||
#endif
|
||||
|
||||
|
@ -172,15 +173,15 @@ setSticky f = modifyFileMode f $ addModes [stickyMode]
|
|||
- On a filesystem that does not support file permissions, this is the same
|
||||
- as writeFile.
|
||||
-}
|
||||
writeFileProtected :: RawFilePath -> String -> IO ()
|
||||
writeFileProtected :: OsPath -> String -> IO ()
|
||||
writeFileProtected file content = writeFileProtected' file
|
||||
(\h -> hPutStr h content)
|
||||
|
||||
writeFileProtected' :: RawFilePath -> (Handle -> IO ()) -> IO ()
|
||||
writeFileProtected' :: OsPath -> (Handle -> IO ()) -> IO ()
|
||||
writeFileProtected' file writer = bracket setup cleanup writer
|
||||
where
|
||||
setup = do
|
||||
h <- protectedOutput $ F.openFile (toOsPath file) WriteMode
|
||||
h <- protectedOutput $ F.openFile file WriteMode
|
||||
void $ tryIO $ modifyFileMode file $ removeModes otherGroupModes
|
||||
return h
|
||||
cleanup = hClose
|
||||
|
|
|
@ -418,7 +418,7 @@ testHarness tmpdir cmd a = ifM (inSearchPath (unGpgCmd cmd))
|
|||
origenviron <- getEnvironment
|
||||
let environ = addEntry var (fromOsPath subdir) origenviron
|
||||
-- gpg is picky about permissions on its home dir
|
||||
liftIO $ void $ tryIO $ modifyFileMode (fromOsPath subdir) $
|
||||
liftIO $ void $ tryIO $ modifyFileMode subdir $
|
||||
removeModes $ otherGroupModes
|
||||
-- For some reason, recent gpg needs a trustdb to be set up.
|
||||
_ <- pipeStrict' cmd [Param "--trust-model", Param "auto", Param "--update-trustdb"] (Just environ) mempty
|
||||
|
|
|
@ -75,12 +75,11 @@ tryLock lockreq mode lockfile = uninterruptibleMask_ $ do
|
|||
-- Close on exec flag is set so child processes do not inherit the lock.
|
||||
openLockFile :: LockRequest -> Maybe ModeSetter -> LockFile -> IO Fd
|
||||
openLockFile lockreq filemode lockfile = do
|
||||
l <- applyModeSetter filemode lockfile' $ \filemode' ->
|
||||
openFdWithMode lockfile' openfor filemode' defaultFileFlags
|
||||
l <- applyModeSetter filemode lockfile $ \filemode' ->
|
||||
openFdWithMode (fromOsPath lockfile) openfor filemode' defaultFileFlags
|
||||
setFdOption l CloseOnExec True
|
||||
return l
|
||||
where
|
||||
lockfile' = fromOsPath lockfile
|
||||
openfor = case lockreq of
|
||||
ReadLock -> ReadOnly
|
||||
_ -> ReadWrite
|
||||
|
|
|
@ -55,6 +55,7 @@ import Utility.HumanTime
|
|||
import Utility.SimpleProtocol as Proto
|
||||
import Utility.ThreadScheduler
|
||||
import Utility.SafeOutput
|
||||
import qualified Utility.FileIO as F
|
||||
|
||||
import qualified Data.ByteString.Lazy as L
|
||||
import qualified Data.ByteString as S
|
||||
|
@ -121,8 +122,8 @@ zeroBytesProcessed = BytesProcessed 0
|
|||
|
||||
{- Sends the content of a file to an action, updating the meter as it's
|
||||
- consumed. -}
|
||||
withMeteredFile :: FilePath -> MeterUpdate -> (L.ByteString -> IO a) -> IO a
|
||||
withMeteredFile f meterupdate a = withBinaryFile f ReadMode $ \h ->
|
||||
withMeteredFile :: OsPath -> MeterUpdate -> (L.ByteString -> IO a) -> IO a
|
||||
withMeteredFile f meterupdate a = F.withBinaryFile f ReadMode $ \h ->
|
||||
hGetContentsMetered h meterupdate >>= a
|
||||
|
||||
{- Calls the action repeatedly with chunks from the lazy ByteString.
|
||||
|
@ -140,8 +141,8 @@ meteredWrite' meterupdate a = go zeroBytesProcessed . L.toChunks
|
|||
meterupdate sofar'
|
||||
go sofar' cs
|
||||
|
||||
meteredWriteFile :: MeterUpdate -> FilePath -> L.ByteString -> IO ()
|
||||
meteredWriteFile meterupdate f b = withBinaryFile f WriteMode $ \h ->
|
||||
meteredWriteFile :: MeterUpdate -> OsPath -> L.ByteString -> IO ()
|
||||
meteredWriteFile meterupdate f b = F.withBinaryFile f WriteMode $ \h ->
|
||||
meteredWrite meterupdate (S.hPut h) b
|
||||
|
||||
{- Applies an offset to a MeterUpdate. This can be useful when
|
||||
|
|
|
@ -150,7 +150,7 @@ changeUserSshConfig modifier = do
|
|||
writeSshConfig :: OsPath -> String -> IO ()
|
||||
writeSshConfig f s = do
|
||||
F.writeFile' f (linesFile' (encodeBS s))
|
||||
setSshConfigMode (fromOsPath f)
|
||||
setSshConfigMode f
|
||||
|
||||
{- Ensure that the ssh config file lacks any group or other write bits,
|
||||
- since ssh is paranoid about not working if other users can write
|
||||
|
@ -159,7 +159,7 @@ writeSshConfig f s = do
|
|||
- If the chmod fails, ignore the failure, as it might be a filesystem like
|
||||
- Android's that does not support file modes.
|
||||
-}
|
||||
setSshConfigMode :: RawFilePath -> IO ()
|
||||
setSshConfigMode :: OsPath -> IO ()
|
||||
setSshConfigMode f = void $ tryIO $ modifyFileMode f $
|
||||
removeModes [groupWriteMode, otherWriteMode]
|
||||
|
||||
|
|
|
@ -171,7 +171,7 @@ prepHiddenServiceSocketDir :: AppName -> UserID -> UniqueIdent -> IO ()
|
|||
prepHiddenServiceSocketDir appname uid ident = do
|
||||
createDirectoryIfMissing True d
|
||||
setOwnerAndGroup (fromOsPath d) uid (-1)
|
||||
modifyFileMode (fromOsPath d) $
|
||||
modifyFileMode d $
|
||||
addModes [ownerReadMode, ownerExecuteMode, ownerWriteMode]
|
||||
where
|
||||
d = takeDirectory $ hiddenServiceSocketFile appname uid ident
|
||||
|
|
|
@ -433,7 +433,7 @@ download' nocurlerror meterupdate iv url file uo =
|
|||
|
||||
downloadfile u = do
|
||||
noverification
|
||||
let src = unEscapeString (uriPath u)
|
||||
let src = toOsPath $ unEscapeString (uriPath u)
|
||||
withMeteredFile src meterupdate $
|
||||
F.writeFile file
|
||||
return $ Right ()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue