From e0aff931023a6c3f7a06caaa5dfa1aad2da3889d Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 23 Apr 2014 14:04:09 -0400 Subject: merge from git-annex --- Utility/FileMode.hs | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) (limited to 'Utility/FileMode.hs') diff --git a/Utility/FileMode.hs b/Utility/FileMode.hs index b17cadc..9c15da8 100644 --- a/Utility/FileMode.hs +++ b/Utility/FileMode.hs @@ -9,15 +9,18 @@ module Utility.FileMode where -import Common - +import System.IO +import Control.Monad import Control.Exception (bracket) import System.PosixCompat.Types +import Utility.PosixFiles #ifndef mingw32_HOST_OS import System.Posix.Files #endif import Foreign (complement) +import Utility.Exception + {- Applies a conversion function to a file's mode. -} modifyFileMode :: FilePath -> (FileMode -> FileMode) -> IO () modifyFileMode f convert = void $ modifyFileMode' f convert @@ -56,6 +59,12 @@ readModes = [ownerReadMode, groupReadMode, otherReadMode] executeModes :: [FileMode] executeModes = [ownerExecuteMode, groupExecuteMode, otherExecuteMode] +otherGroupModes :: [FileMode] +otherGroupModes = + [ groupReadMode, otherReadMode + , groupWriteMode, otherWriteMode + ] + {- Removes the write bits from a file. -} preventWrite :: FilePath -> IO () preventWrite f = modifyFileMode f $ removeModes writeModes @@ -99,13 +108,20 @@ noUmask :: FileMode -> IO a -> IO a #ifndef mingw32_HOST_OS noUmask mode a | mode == stdFileMode = a - | otherwise = bracket setup cleanup go + | otherwise = withUmask nullFileMode a +#else +noUmask _ a = a +#endif + +withUmask :: FileMode -> IO a -> IO a +#ifndef mingw32_HOST_OS +withUmask umask a = bracket setup cleanup go where - setup = setFileCreationMask nullFileMode + setup = setFileCreationMask umask cleanup = setFileCreationMask go _ = a #else -noUmask _ a = a +withUmask _ a = a #endif combineModes :: [FileMode] -> FileMode @@ -127,14 +143,16 @@ setSticky f = modifyFileMode f $ addModes [stickyMode] #endif {- Writes a file, ensuring that its modes do not allow it to be read - - by anyone other than the current user, before any content is written. + - or written by anyone other than the current user, + - before any content is written. + - + - When possible, this is done using the umask. - - On a filesystem that does not support file permissions, this is the same - as writeFile. -} writeFileProtected :: FilePath -> String -> IO () -writeFileProtected file content = withFile file WriteMode $ \h -> do - void $ tryIO $ - modifyFileMode file $ - removeModes [groupReadMode, otherReadMode] - hPutStr h content +writeFileProtected file content = withUmask 0o0077 $ + withFile file WriteMode $ \h -> do + void $ tryIO $ modifyFileMode file $ removeModes otherGroupModes + hPutStr h content -- cgit v1.2.3