summaryrefslogtreecommitdiff
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
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.
-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