#2808: createDirectoryIfMissing should be atomic
------------------------------------+---------------------------------------
Reporter: EricKow | Owner: igloo
Type: merge | Status: reopened
Priority: normal | Milestone: 6.10.2
Component: libraries/directory | Version: 6.10.1
Severity: normal | Resolution:
Keywords: | Difficulty: Unknown
Testcase: | Os: Unknown/Multiple
Architecture: Unknown/Multiple |
------------------------------------+---------------------------------------
Comment (by duncan):
Updated to address Simon's comments and to handle the two `create_parents`
cases in a more similar way, especially when it comes to trailing
directory separators.
Ignoring comments it looks like:
{{{
createDirectoryIfMissing create_parents path0
| create_parents = createDirs (parents path0)
| otherwise = createDirs (take 1 (parents path0))
where
parents = reverse . scanl1 (</>) . splitDirectories . normalise
createDirs [] = return ()
createDirs (dir:[]) = createDir dir throw
createDirs (dir:dirs) =
createDir dir $ \_ -> do
createDirs dirs
createDir dir throw
createDir :: FilePath -> (IOException -> IO ()) -> IO ()
createDir dir notExistHandler = do
r <- try $ createDirectory dir
case (r :: Either IOException ()) of
Right () -> return ()
Left e
| isDoesNotExistError e -> notExistHandler e
| isAlreadyExistsError e -> do
exists <- doesDirectoryExist dir
if exists then return ()
else throw e
| otherwise -> throw e
}}}
There are two changes, one is to use `scanl1 (</>) . splitDirectories`
instead of `scanl1 (++) . splitPath`. The other is to add a clause:
{{{
createDirs (dir:[]) = createDir dir throw
}}}
So that we do not attempt to create the last dir twice. When it fails
there's not more parent dirs to try so it's a hard failure.
That also means we can use `createDirs` in the `not create_parents` case.
We don't just pass `head (parents path0)` because it will be empty when
`path0 == ""`. Using `take 1` covers both cases.
--
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/2808#comment:8>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs