diff options
author | Sergei Trofimovich <slyfox@gentoo.org> | 2014-07-28 07:59:36 -0500 |
---|---|---|
committer | Austin Seipp <austin@well-typed.com> | 2014-07-28 09:29:19 -0500 |
commit | f510c7cac5b2e9afe0ebde2766a671c59137f3cc (patch) | |
tree | fe7d8cd3c231af6a344e43dcd01d8c77aae2e0af /libraries/base/System/IO.hs | |
parent | b126ad3f59a62f91b2e2d92ec9d51d245861b655 (diff) | |
download | haskell-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.hs | 24 |
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 |