module System.IO.Temp
( createTempDirectory
, openBinaryTempFile
, openTempFile
) where
-- NB: this module was extracted directly from "Distribution/Simple/Utils.hs"
-- in a Cabal tree whose most recent commit was on Sun Oct 10 22:00:26
--
-- The files in the Distribution/Compat tree are exact copies of the
-- corresponding file in the Cabal checkout.
import Control.Monad ( when )
import Control.Monad.IO.Class ( MonadIO(..) )
import Control.Monad.Trans.Resource ( MonadResource, ReleaseKey, allocate )
import System.Directory
( doesDirectoryExist, doesFileExist, getTemporaryDirectory
, removeDirectory, removeDirectoryRecursive, removeFile )
import System.IO ( Handle )
import qualified Distribution.Compat.TempFile as Compat
-- | Create a temporary directory. The directory will be deleted if empty
-- when the resource is released. If a parent directory is supplied, the
-- temporary directory will be created there; otherwise, it will be created
-- in the system temporary directory returned by 'getTemporaryDirectory'.
createTempDirectory :: MonadResource m
=> Maybe FilePath -- ^ optional parent directory
-> String
-- ^ filename template; for security, a random number
-- will be inserted between the filename and any
-- extension.
-> m (ReleaseKey, FilePath)
createTempDirectory mDir tmpl = do
dir <- resolveTempDir mDir
allocate (Compat.createTempDirectory dir tmpl) removeDirectoryRecursive
-- | Open a temporary file in binary mode. The file will be readable and
-- writeable, but only by the current user. The file will be deleted when
-- the resource is released, if it still exists. If a parent directory is
-- supplied, the file will be created there; otherwise, it will be created
-- in the system temporary directory returned by 'getTemporaryDirectory'.
openBinaryTempFile :: MonadResource m
=> Maybe FilePath -- ^ optional parent directory
-> String
-- ^ filename template; for security, a random number
-- will be inserted between the filename and any
-- extension.
-> m (ReleaseKey, FilePath, Handle)
openBinaryTempFile mDir tmpl = do
dir <- resolveTempDir mDir
(key, (path, h)) <- allocate (Compat.openBinaryTempFile dir tmpl)
(removeFileIfExists . fst)
return (key, path, h)
-- | Open a temporary file. The file will be readable and writeable, but
-- only by the current user. The file will be deleted when the resource is
-- released, if it still exists. If a parent directory is supplied, the
-- file will be created there; otherwise, it will be created in the system
-- temporary directory returned by 'getTemporaryDirectory'.
openTempFile :: MonadResource m
=> Maybe FilePath -- ^ optional parent directory
-> String
-- ^ filename template; for security, a random number will be
-- inserted between the filename and any extension.
-> m (ReleaseKey, FilePath, Handle)
openTempFile mDir tmpl = do
dir <- resolveTempDir mDir
(key, (path, h)) <- allocate (Compat.openTempFile dir tmpl)
(removeFileIfExists . fst)
return (key, path, h)
removeFileIfExists :: FilePath -> IO ()
removeFileIfExists path = do
exists <- doesFileExist path
when exists $ removeFile path
resolveTempDir :: MonadIO m => Maybe FilePath -> m FilePath
resolveTempDir = maybe (liftIO getTemporaryDirectory) return