diff options
author | Simon Marlow <marlowsd@gmail.com> | 2010-02-16 13:48:41 +0000 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2010-02-16 13:48:41 +0000 |
commit | cd81cd88f2e6f7972221bf2f6d956a0a63ac2e84 (patch) | |
tree | 24bb80170c46a5f9161dfed7cff1126545e4995f /utils | |
parent | 32578fc55ac105aa3bd08ef6aa607bfdbe375eec (diff) | |
download | haskell-cd81cd88f2e6f7972221bf2f6d956a0a63ac2e84.tar.gz |
Write the binary cache file atomically
Should fix an occasional build error of the form
ghc-pkg: too few bytes. Failed reading at byte position 8
Diffstat (limited to 'utils')
-rw-r--r-- | utils/ghc-pkg/Main.hs | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/utils/ghc-pkg/Main.hs b/utils/ghc-pkg/Main.hs index ea18000818..0ac8041034 100644 --- a/utils/ghc-pkg/Main.hs +++ b/utils/ghc-pkg/Main.hs @@ -10,7 +10,7 @@ module Main (main) where import Version ( version, targetOS, targetARCH ) -import Distribution.InstalledPackageInfo.Binary +import Distribution.InstalledPackageInfo.Binary() import qualified Distribution.Simple.PackageIndex as PackageIndex import Distribution.ModuleName hiding (main) import Distribution.InstalledPackageInfo @@ -735,7 +735,7 @@ updateDBCache verbosity db = do let filename = location db </> cachefilename when (verbosity > Normal) $ putStrLn ("writing cache " ++ filename) - writeBinPackageDB filename (map convertPackageInfoOut (packages db)) + writeBinaryFileAtomic filename (map convertPackageInfoOut (packages db)) `catch` \e -> if isPermissionError e then die (filename ++ ": you don't have permission to modify this file") @@ -1548,12 +1548,20 @@ catchError io handler = io `Exception.catch` handler' where handler' (Exception.ErrorCall err) = handler err +writeBinaryFileAtomic :: Bin.Binary a => FilePath -> a -> IO () +writeBinaryFileAtomic targetFile obj = + withFileAtomic targetFile $ \h -> B.hPutStr h (Bin.encode obj) + +writeFileAtomic :: FilePath -> String -> IO () +writeFileAtomic targetFile content = + withFileAtomic targetFile $ \h -> hPutStr h content + -- copied from Cabal's Distribution.Simple.Utils, except that we want -- to use text files here, rather than binary files. -writeFileAtomic :: FilePath -> String -> IO () -writeFileAtomic targetFile content = do +withFileAtomic :: FilePath -> (Handle -> IO ()) -> IO () +withFileAtomic targetFile write_content = do (newFile, newHandle) <- openNewFile targetDir template - do hPutStr newHandle content + do write_content newHandle hClose newHandle #if mingw32_HOST_OS || mingw32_TARGET_OS renameFile newFile targetFile |