@@ -4,13 +4,12 @@ module ProjectM36.Persist (writeFileSync,
44 writeBSFileSync,
55 renameSync,
66 DiskSync(..)) where
7−-- on Windows, use FlushFileBuffers and System.Directory's rename (which uses MoveFileEx)
8−import System.Directory (renameDirectory)
7+-- on Windows, use FlushFileBuffers and MoveFileEx
98
109#if defined(mingw32_HOST_OS)
1110import System.Win32.File (flushFileBuffers)
12−--import ProjectM36.Win32Handle
1311#else
12+import qualified System.Posix as Posix
1413import System.Posix.Unistd (fileSynchroniseDataOnly)
1514import System.Posix.IO (handleToFd)
1615import Foreign.C
@@ -36,9 +35,18 @@ writeFileSync sync path strOut = withFile path WriteMode handler
3635
3736renameSync :: DiskSync -> FilePath -> FilePath -> IO ()
3837renameSync sync srcPath dstPath = do
39− renameDirectory srcPath dstPath
38+ atomicRename srcPath dstPath
4039 syncDirectory sync dstPath
4140
41+-- System.Directory's renameFile/renameDirectory almost do exactly what we want except that it needlessly differentiates between directories and files
42+atomicRename :: FilePath -> FilePath -> IO ()
43+atomicRename srcPath dstPath = do
44+#if defined(ming32_HOST_OS)
45+ Win32.moveFileEx srcPath dstPath Win32.mOVEFILE_REPLACE_EXISTING
46+#else
47+ Posix.rename srcPath dstPath
48+#endif
49+
4250syncHandle :: DiskSync -> Handle -> IO ()
4351syncHandle FsyncDiskSync handle = do
4452#if defined(mingw32_HOST_OS)