ghc/9aace0eaf6279f17368a1753b65...

94 lines
3.7 KiB
Diff

From 9aace0eaf6279f17368a1753b65afbdc466e8291 Mon Sep 17 00:00:00 2001
From: Sylvain Henry <sylvain@haskus.fr>
Date: Sat, 10 Apr 2021 14:48:16 +0200
Subject: [PATCH] Produce constant file atomically (#19684)
---
utils/deriveConstants/Main.hs | 21 ++++++++++++++++-----
utils/deriveConstants/deriveConstants.cabal | 3 ++-
2 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/utils/deriveConstants/Main.hs b/utils/deriveConstants/Main.hs
index 8bf8ae7b44d..9db673a9852 100644
--- a/utils/deriveConstants/Main.hs
+++ b/utils/deriveConstants/Main.hs
@@ -34,9 +34,10 @@ import Data.Maybe (catMaybes, mapMaybe, fromMaybe)
import Numeric (readHex)
import System.Environment (getArgs)
import System.Exit (ExitCode(ExitSuccess), exitFailure)
-import System.FilePath ((</>))
+import System.FilePath ((</>),(<.>))
import System.IO (stderr, hPutStrLn)
import System.Process (showCommandForUser, readProcess, rawSystem)
+import System.Directory (renameFile)
main :: IO ()
main = do opts <- parseArgs
@@ -79,6 +80,16 @@ data Options = Options {
o_targetOS :: Maybe String
}
+-- | Write a file atomically
+--
+-- This avoids other processes seeing the file while it is being written into.
+atomicWriteFile :: FilePath -> String -> IO ()
+atomicWriteFile fn s = do
+ let tmp = fn <.> "tmp"
+ writeFile tmp s
+ renameFile tmp fn
+
+
parseArgs :: IO Options
parseArgs = do args <- getArgs
opts <- f emptyOptions args
@@ -670,7 +681,7 @@ getWanted verbose os tmpdir gccProgram gccFlags nmProgram mobjdumpProgram
= do let cStuff = unlines (headers ++ concatMap (doWanted . snd) (wanteds os))
cFile = tmpdir </> "tmp.c"
oFile = tmpdir </> "tmp.o"
- writeFile cFile cStuff
+ atomicWriteFile cFile cStuff
execute verbose gccProgram (gccFlags ++ ["-c", cFile, "-o", oFile])
xs <- case os of
"openbsd" -> readProcess objdumpProgam ["--syms", oFile] ""
@@ -855,7 +866,7 @@ getWanted verbose os tmpdir gccProgram gccFlags nmProgram mobjdumpProgram
= return (w, FieldTypeGcptrMacro name)
writeHaskellType :: FilePath -> [What Fst] -> IO ()
-writeHaskellType fn ws = writeFile fn xs
+writeHaskellType fn ws = atomicWriteFile fn xs
where xs = unlines [header, body, footer, parser]
header = "module GHC.Platform.Constants where\n\n\
\import Prelude\n\
@@ -920,7 +931,7 @@ writeHaskellType fn ws = writeFile fn xs
writeHaskellValue :: FilePath -> [What Snd] -> IO ()
-writeHaskellValue fn rs = writeFile fn xs
+writeHaskellValue fn rs = atomicWriteFile fn xs
where xs = unlines [header, body, footer]
header = "PlatformConstants {"
footer = " }"
@@ -937,7 +948,7 @@ writeHaskellValue fn rs = writeFile fn xs
doWhat (FieldTypeGcptrMacro {}) = []
writeHeader :: FilePath -> [(Where, What Snd)] -> IO ()
-writeHeader fn rs = writeFile fn xs
+writeHeader fn rs = atomicWriteFile fn xs
where xs = headers ++ hs ++ unlines body
headers = "/* This file is created automatically. Do not edit by hand.*/\n\n"
haskellRs = fmap snd $ filter (\r -> fst r `elem` [Haskell,Both]) rs
diff --git a/utils/deriveConstants/deriveConstants.cabal b/utils/deriveConstants/deriveConstants.cabal
index 50b5b695c30..36ba7ebe1f7 100644
--- a/utils/deriveConstants/deriveConstants.cabal
+++ b/utils/deriveConstants/deriveConstants.cabal
@@ -20,4 +20,5 @@ Executable deriveConstants
Build-Depends: base >= 4 && < 5,
containers,
process,
- filepath
+ filepath,
+ directory
--
GitLab