summaryrefslogtreecommitdiff
path: root/Utility/TempFile.hs
diff options
context:
space:
mode:
Diffstat (limited to 'Utility/TempFile.hs')
-rw-r--r--Utility/TempFile.hs39
1 files changed, 39 insertions, 0 deletions
diff --git a/Utility/TempFile.hs b/Utility/TempFile.hs
new file mode 100644
index 000000000..1e823c10e
--- /dev/null
+++ b/Utility/TempFile.hs
@@ -0,0 +1,39 @@
+{- temp file functions
+ -
+ - Copyright 2010-2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Utility.TempFile where
+
+import IO (bracket)
+import System.IO
+import System.Posix.Process hiding (executeFile)
+import System.Directory
+
+import Utility.Misc
+import Utility.Path
+
+{- Runs an action like writeFile, writing to a temp file first and
+ - then moving it into place. The temp file is stored in the same
+ - directory as the final file to avoid cross-device renames. -}
+viaTmp :: (FilePath -> String -> IO ()) -> FilePath -> String -> IO ()
+viaTmp a file content = do
+ pid <- getProcessID
+ let tmpfile = file ++ ".tmp" ++ show pid
+ createDirectoryIfMissing True (parentDir file)
+ a tmpfile content
+ renameFile tmpfile file
+
+{- Runs an action with a temp file, then removes the file. -}
+withTempFile :: String -> (FilePath -> Handle -> IO a) -> IO a
+withTempFile template a = bracket create remove use
+ where
+ create = do
+ tmpdir <- catch getTemporaryDirectory (const $ return ".")
+ openTempFile tmpdir template
+ remove (name, handle) = do
+ hClose handle
+ catchBool (removeFile name >> return True)
+ use (name, handle) = a name handle