summaryrefslogtreecommitdiff
path: root/Utility/FileMode.hs
diff options
context:
space:
mode:
Diffstat (limited to 'Utility/FileMode.hs')
-rw-r--r--Utility/FileMode.hs40
1 files changed, 29 insertions, 11 deletions
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