From 6914d7de311fa3c49dc2a9a26c4eae927164b2f0 Mon Sep 17 00:00:00 2001 From: Simon Marlow Date: Tue, 22 Aug 2006 12:19:09 +0000 Subject: [PATCH] copyFile: try removing the target file before opening it for writing --- System/Directory.hs | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/System/Directory.hs b/System/Directory.hs index bdd7f3c..5e87c21 100644 --- a/System/Directory.hs +++ b/System/Directory.hs @@ -510,14 +510,23 @@ If the /new/ file already exists, it is atomically replaced by the /old/ file. Neither path may refer to an existing directory. -} copyFile :: FilePath -> FilePath -> IO () -copyFile fromFPath toFPath = +copyFile fromFPath toFPath = do + -- We try removing the target file before opening it for + -- writing. In the event that the target file is locked or in + -- use, this allows us to replace it safely. However, it + -- leaves a race condition: someone else might create the file + -- after we delete it, but there isn't much we can do about + -- that. #if (!(defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ > 600)) - do readFile fromFPath >>= writeFile toFPath - try (copyPermissions fromFPath toFPath) - return () + contents <- readFile fromFPath + try (removeFile toFPath) + writeFile toFPath contents + try (copyPermissions fromFPath toFPath) + return () #else - (bracket (openBinaryFile fromFPath ReadMode) hClose $ \hFrom -> - bracket (openBinaryFile toFPath WriteMode) hClose $ \hTo -> + (bracket (openBinaryFile fromFPath ReadMode) hClose $ \hFrom -> do + try (removeFile toFPath) + bracket (openBinaryFile toFPath WriteMode) hClose $ \hTo -> do allocaBytes bufferSize $ \buffer -> do copyContents hFrom hTo buffer try (copyPermissions fromFPath toFPath) -- 1.7.10.4