summaryrefslogtreecommitdiff
path: root/Utility/FileMode.hs
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2012-04-21 11:57:17 -0400
committerGravatar Joey Hess <joey@kitenet.net>2012-04-21 11:59:50 -0400
commitcbf9a9420e5d0fd9af2ad7d2864618386a75cfc3 (patch)
treea67524b1fe1a9e12516371e04065f9b443408147 /Utility/FileMode.hs
parent5cc76098ca7b702772ccf37a47f03da088148003 (diff)
avoid chown call if the current file mode is same as new
Not only an optimisation. fsck always tried to preventWrite to make sure file modes are good, and in a shared repo, that will fail on directories not owned by the current user. Although there may be other problems with such a setup.
Diffstat (limited to 'Utility/FileMode.hs')
-rw-r--r--Utility/FileMode.hs21
1 files changed, 14 insertions, 7 deletions
diff --git a/Utility/FileMode.hs b/Utility/FileMode.hs
index 571b03503..4992690c6 100644
--- a/Utility/FileMode.hs
+++ b/Utility/FileMode.hs
@@ -7,16 +7,24 @@
module Utility.FileMode where
-import System.Posix.Files
+import Common
+
import System.Posix.Types
import Foreign (complement)
+modifyFileMode :: FilePath -> (FileMode -> FileMode) -> IO ()
+modifyFileMode f convert = do
+ s <- getFileStatus f
+ let cur = fileMode s
+ let new = convert cur
+ when (new /= cur) $
+ setFileMode f new
+
{- Removes a FileMode from a file.
- For example, call with otherWriteMode to chmod o-w -}
unsetFileMode :: FilePath -> FileMode -> IO ()
-unsetFileMode f m = do
- s <- getFileStatus f
- setFileMode f $ fileMode s `intersectFileModes` complement m
+unsetFileMode f m = modifyFileMode f $
+ \cur -> cur `intersectFileModes` complement m
{- Removes the write bits from a file. -}
preventWrite :: FilePath -> IO ()
@@ -27,9 +35,8 @@ preventWrite f = unsetFileMode f writebits
{- Turns a file's write bit back on. -}
allowWrite :: FilePath -> IO ()
-allowWrite f = do
- s <- getFileStatus f
- setFileMode f $ fileMode s `unionFileModes` ownerWriteMode
+allowWrite f = modifyFileMode f $
+ \cur -> cur `unionFileModes` ownerWriteMode
{- Checks if a file mode indicates it's a symlink. -}
isSymLink :: FileMode -> Bool