Skip to content

Commit

Permalink
Merge pull request #248 from NixOS/atomic-chown
Browse files Browse the repository at this point in the history
  • Loading branch information
infinisil committed Sep 3, 2024
2 parents 8a73acf + 3e7918b commit 3e8eef7
Showing 1 changed file with 9 additions and 2 deletions.
11 changes: 9 additions & 2 deletions main/System/IO/Atomic.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import Control.Monad (when)
import System.Directory (doesFileExist, removeFile, renameFile)
import System.FilePath (takeDirectory, takeFileName)
import System.IO (Handle, hClose, openTempFileWithDefaultPermissions)
import System.Posix.Files (fileMode, getFileStatus, setFileMode)
import System.Posix.Files (fileGroup, fileMode, fileOwner, getFileStatus, setFileMode, setOwnerAndGroup)

-- | Like @withFile@ but replaces the contents atomically.
--
Expand Down Expand Up @@ -50,7 +50,14 @@ withOutputFile path act = transact begin commit rollback $ \(tpath, th) -> do
copyAttributes (tpath, _th) = do
exists <- doesFileExist path
when exists $ do
getFileStatus path >>= setFileMode tpath . fileMode
status <- getFileStatus path
setFileMode tpath (fileMode status)
-- Set the temporary files owner to the same as the original file.
-- This only succeeds if either:
-- - The owner matches already, no change necessary
-- - The current user has the CAP_CHOWN permission
-- See also https://stackoverflow.com/a/49079630 for more context
setOwnerAndGroup tpath (fileOwner status) (fileGroup status)

commit :: (FilePath, Handle) -> IO ()
commit (tpath, th) = hClose th *> renameFile tpath path
Expand Down

0 comments on commit 3e8eef7

Please sign in to comment.