more OsPath conversion

Sponsored-by: Nicholas Golder-Manning
This commit is contained in:
Joey Hess 2025-01-29 11:53:20 -04:00
parent 0376bc5ee0
commit 27305042f3
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
24 changed files with 180 additions and 153 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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]

View file

@ -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

View file

@ -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 ()