Fix a bug in getDirectoryEntries where the directory stream wasn't
always being closed. This one shows up on Solaris as a "too many open
files" failure when trying to run the test suite.
getDirectoryContents :: FilePath -> IO [FilePath]
getDirectoryContents path = do
getDirectoryContents :: FilePath -> IO [FilePath]
getDirectoryContents path = do
- alloca $ \ ptr_dEnt -> do
- p <- withCString path $ \s ->
- throwErrnoIfNullRetry "getDirectoryContents" (c_opendir s)
- loop ptr_dEnt p
+ alloca $ \ ptr_dEnt ->
+ bracket
+ (withCString path $ \s ->
+ throwErrnoIfNullRetry desc (c_opendir s))
+ (\p -> throwErrnoIfMinus1_ desc (c_closedir p))
+ (\p -> loop ptr_dEnt p)
+ desc = "getDirectoryContents"
+
loop :: Ptr (Ptr CDirent) -> Ptr CDir -> IO [String]
loop ptr_dEnt dir = do
resetErrno
r <- readdir dir ptr_dEnt
loop :: Ptr (Ptr CDirent) -> Ptr CDir -> IO [String]
loop ptr_dEnt dir = do
resetErrno
r <- readdir dir ptr_dEnt
then do
dEnt <- peek ptr_dEnt
then do
dEnt <- peek ptr_dEnt
then return []
else do
entry <- (d_name dEnt >>= peekCString)
then return []
else do
entry <- (d_name dEnt >>= peekCString)
return (entry:entries)
else do errno <- getErrno
if (errno == eINTR) then loop ptr_dEnt dir else do
return (entry:entries)
else do errno <- getErrno
if (errno == eINTR) then loop ptr_dEnt dir else do
- throwErrnoIfMinus1_ "getDirectoryContents" $ c_closedir dir
let (Errno eo) = errno
if (eo == end_of_dir)
then return []
let (Errno eo) = errno
if (eo == end_of_dir)
then return []
- else throwErrno "getDirectoryContents"