temporary 1.2.1.1 → 1.3
raw patch · 3 files changed
+41/−15 lines, 3 filesdep +random
Dependencies added: random
Files
- CHANGELOG.md +8/−0
- System/IO/Temp.hs +31/−13
- temporary.cabal +2/−2
CHANGELOG.md view
@@ -1,3 +1,11 @@+## 1.3++* Generated directory names are now based on random hex strings rather than PIDs.++ This got a major version bump as a courtesy to users who may depend on the+ specific form of generated names, but that form is not part of the API+ contract and should not be depended upon.+ ## 1.2.1.1 * Improve the docs
System/IO/Temp.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE CPP #-}+{-# LANGUAGE CPP, ScopedTypeVariables #-} -- | Functions to create temporary files and directories. -- -- Most functions come in two flavours: those that create files/directories@@ -21,11 +21,15 @@ -- placed between between the name and the extension to yield a unique file -- name, e.g. @name1804289383846930886.ext@. ----- For directories, no extension is recognized, so a number will be simply--- appended to the end of the template. Moreover, the number will be--- smaller, as it is derived from the current process's PID--- (but the result is still a unique directory name). So, for instance,--- the directory template @dir@ may result in a directory named @dir30112@.+-- For directories, no extension is recognized.+-- A random hexadecimal string (whose length depends on the system's word+-- size) is appended to the end of the template.+-- For instance,+-- the directory template @dir@ may result in a directory named+-- @dir-e4bd89e5d00acdee@.+--+-- You shouldn't rely on the specific form of file or directory names+-- generated by the library; it has changed in the past and may change in the future. module System.IO.Temp ( withSystemTempFile, withSystemTempDirectory, withTempFile, withTempDirectory,@@ -43,17 +47,23 @@ import qualified Control.Monad.Catch as MC import Control.Monad.IO.Class+import Data.Bits -- no import list: we use different functions+ -- depending on the base version+#if !MIN_VERSION_base(4,8,0)+import Data.Word (Word)+#endif import System.Directory import System.IO (Handle, hClose, openTempFile, openBinaryTempFile, openBinaryTempFileWithDefaultPermissions, hPutStr) import System.IO.Error (isAlreadyExistsError)-import System.Posix.Internals (c_getpid) import System.FilePath ((</>))+import System.Random #ifdef mingw32_HOST_OS import System.Directory ( createDirectory ) #else import qualified System.Posix #endif+import Text.Printf -- | Create, open, and use a temporary file in the system standard temporary directory. --@@ -164,17 +174,25 @@ :: FilePath -- ^ Parent directory to create the directory in -> String -- ^ Directory name template -> IO FilePath-createTempDirectory dir template = do- pid <- c_getpid- findTempName pid+createTempDirectory dir template = findTempName where- findTempName x = do- let dirpath = dir </> template ++ show x+ findTempName = do+ x :: Word <- randomIO+ let dirpath = dir </> template ++ printf "-%.*x" (wordSize `div` 4) x r <- MC.try $ mkPrivateDir dirpath case r of Right _ -> return dirpath- Left e | isAlreadyExistsError e -> findTempName (x+1)+ Left e | isAlreadyExistsError e -> findTempName | otherwise -> ioError e++-- | Word size in bits+wordSize :: Int+wordSize =+#if MIN_VERSION_base(4,7,0)+ finiteBitSize (undefined :: Word)+#else+ bitSize (undefined :: Word)+#endif mkPrivateDir :: String -> IO () #ifdef mingw32_HOST_OS
temporary.cabal view
@@ -1,5 +1,5 @@ name: temporary-version: 1.2.1.1+version: 1.3 cabal-version: >= 1.10 synopsis: Portable temporary file and directory support description: Functions for creating temporary files and directories.@@ -20,7 +20,7 @@ Haskell2010 exposed-modules: System.IO.Temp build-depends: base >= 3 && < 10, filepath >= 1.1, directory >= 1.0,- transformers >= 0.2.0.0, exceptions >= 0.6+ transformers >= 0.2.0.0, exceptions >= 0.6, random >= 1.1 -- note: the transformers dependency is needed for MonadIO -- on older GHCs; on newer ones, it is included in base. ghc-options: -Wall