Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Maintain same ownership when formatting #248

Merged
merged 1 commit into from
Sep 3, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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