summaryrefslogtreecommitdiff
path: root/libraries/base/System/IO.hs
diff options
context:
space:
mode:
authorSergei Trofimovich <slyfox@gentoo.org>2014-07-28 07:59:36 -0500
committerAustin Seipp <austin@well-typed.com>2014-07-28 09:29:19 -0500
commitf510c7cac5b2e9afe0ebde2766a671c59137f3cc (patch)
treefe7d8cd3c231af6a344e43dcd01d8c77aae2e0af /libraries/base/System/IO.hs
parentb126ad3f59a62f91b2e2d92ec9d51d245861b655 (diff)
downloadhaskell-f510c7cac5b2e9afe0ebde2766a671c59137f3cc.tar.gz
base: make System.IO.openTempFile generate less predictable names
It basically changes prefix ++ getpid() ++ seq_no ++ suffix for prefix ++ rand() ++ rand() ++ suffix Which make any call to 'openTempFile' finish without loops. Bug-report: https://ghc.haskell.org/trac/ghc/ticket/9058 Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org> Signed-off-by: Austin Seipp <austin@well-typed.com>
Diffstat (limited to 'libraries/base/System/IO.hs')
-rw-r--r--libraries/base/System/IO.hs24
1 files changed, 16 insertions, 8 deletions
diff --git a/libraries/base/System/IO.hs b/libraries/base/System/IO.hs
index 004ff54777..60514e18bd 100644
--- a/libraries/base/System/IO.hs
+++ b/libraries/base/System/IO.hs
@@ -464,9 +464,7 @@ openBinaryTempFileWithDefaultPermissions tmp_dir template
openTempFile' :: String -> FilePath -> String -> Bool -> CMode
-> IO (FilePath, Handle)
-openTempFile' loc tmp_dir template binary mode = do
- pid <- c_getpid
- findTempName pid
+openTempFile' loc tmp_dir template binary mode = findTempName
where
-- We split off the last extension, so we can use .foo.ext files
-- for temporary files (hidden on Unix OSes). Unfortunately we're
@@ -485,10 +483,13 @@ openTempFile' loc tmp_dir template binary mode = do
-- beginning with '.' as the second component.
_ -> error "bug in System.IO.openTempFile"
- findTempName x = do
+ findTempName = do
+ rs <- rand_string
+ let filename = prefix ++ rs ++ suffix
+ filepath = tmp_dir `combine` filename
r <- openNewFile filepath binary mode
case r of
- FileExists -> findTempName (x + 1)
+ FileExists -> findTempName
OpenNewError errno -> ioError (errnoToIOError loc errno Nothing (Just tmp_dir))
NewFileCreated fd -> do
(fD,fd_type) <- FD.mkFD fd ReadWriteMode Nothing{-no stat-}
@@ -501,9 +502,6 @@ openTempFile' loc tmp_dir template binary mode = do
return (filepath, h)
where
- filename = prefix ++ show x ++ suffix
- filepath = tmp_dir `combine` filename
-
-- XXX bits copied from System.FilePath, since that's not available here
combine a b
| null b = a
@@ -511,6 +509,16 @@ openTempFile' loc tmp_dir template binary mode = do
| last a == pathSeparator = a ++ b
| otherwise = a ++ [pathSeparator] ++ b
+-- int rand(void) from <stdlib.h>, limited by RAND_MAX (small value, 32768)
+foreign import ccall "rand" c_rand :: IO CInt
+
+-- build large digit-alike number
+rand_string :: IO String
+rand_string = do
+ r1 <- c_rand
+ r2 <- c_rand
+ return $ show r1 ++ show r2
+
data OpenNewFileResult
= NewFileCreated CInt
| FileExists