-
Notifications
You must be signed in to change notification settings - Fork 96
Remove readDirStreamWithPtr; replace readdir_r() with readdir() #349
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -53,7 +53,6 @@ module System.Posix.Directory.Common ( | |
getRealDirType, | ||
unsafeOpenDirStreamFd, | ||
readDirStreamWith, | ||
readDirStreamWithPtr, | ||
|
||
rewindDirStream, | ||
closeDirStream, | ||
|
@@ -289,46 +288,23 @@ foreign import capi unsafe "dirent.h fdopendir" | |
-- if an entry was read and @Nothing@ if the end of the directory stream was | ||
-- reached. | ||
-- | ||
-- __NOTE:__ The lifetime of the pointer wrapped in the `DirEnt` is limited to | ||
-- invocation of the callback and it will be freed automatically after. Do not | ||
-- pass it to the outside world! | ||
-- __NOTE:__ Accessing the `DirEnt` is not guaranteed to be valid after any | ||
-- subsequent operations on the same `DirStream`. To be safe, do not pass | ||
-- references to the `DirEnt` to the outside world. | ||
-- | ||
-- @since 2.8.6.0 | ||
readDirStreamWith :: (DirEnt -> IO a) -> DirStream -> IO (Maybe a) | ||
readDirStreamWith f dstream = alloca | ||
(\ptr_dEnt -> readDirStreamWithPtr ptr_dEnt f dstream) | ||
|
||
-- | A version of 'readDirStreamWith' that takes a pre-allocated pointer in | ||
-- addition to the other arguments. This pointer is used to store the pointer | ||
-- to the next directory entry, if there is any. This function is intended for | ||
-- use cases where you need to read a lot of directory entries and want to | ||
-- reuse the pointer for each of them. Using for example 'readDirStream' or | ||
-- 'readDirStreamWith' in this scenario would allocate a new pointer for each | ||
-- call of these functions. | ||
-- | ||
-- __NOTE__: You are responsible for releasing the pointer after you are done. | ||
-- __NOTE:__ Multiple threads reading from the same `DirStream` is not safe. | ||
-- | ||
-- @since 2.8.6.0 | ||
readDirStreamWithPtr :: Ptr DirEnt -> (DirEnt -> IO a) -> DirStream -> IO (Maybe a) | ||
readDirStreamWithPtr ptr_dEnt f dstream@(DirStream dirp) = do | ||
readDirStreamWith :: (DirEnt -> IO a) -> DirStream -> IO (Maybe a) | ||
readDirStreamWith f (DirStream dirp) = do | ||
resetErrno | ||
r <- c_readdir dirp (castPtr ptr_dEnt) | ||
if (r == 0) | ||
then do dEnt@(DirEnt dEntPtr) <- peek ptr_dEnt | ||
if (dEntPtr == nullPtr) | ||
cDirentPtr <- c_readdir dirp | ||
if (cDirentPtr /= nullPtr) | ||
then Just <$> f (DirEnt cDirentPtr) | ||
else do (Errno eo) <- getErrno | ||
if (eo == 0) | ||
then return Nothing | ||
else do | ||
res <- f dEnt | ||
c_freeDirEnt dEntPtr | ||
return (Just res) | ||
else do errno <- getErrno | ||
if (errno == eINTR) | ||
then readDirStreamWithPtr ptr_dEnt f dstream | ||
else do | ||
let (Errno eo) = errno | ||
if (eo == 0) | ||
then return Nothing | ||
else throwErrno "readDirStream" | ||
else throwErrno "readDirStream" | ||
|
||
-- | @since 2.8.6.0 | ||
dirEntName :: DirEnt -> IO CString | ||
|
@@ -345,12 +321,8 @@ foreign import ccall unsafe "__hscore_d_type" | |
d_type :: Ptr CDirent -> IO CChar | ||
|
||
-- traversing directories | ||
foreign import ccall unsafe "__hscore_readdir" | ||
c_readdir :: Ptr CDir -> Ptr (Ptr CDirent) -> IO CInt | ||
|
||
foreign import ccall unsafe "__hscore_free_dirent" | ||
c_freeDirEnt :: Ptr CDirent -> IO () | ||
|
||
foreign import ccall unsafe "readdir" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are you sure this works on mac? We've had horrible bugs before when not using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
It passed CI so I assume so. 32-bit ARM failed though. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changing that to
Busy with work so not looking into it right now. |
||
c_readdir :: Ptr CDir -> IO (Ptr CDirent) | ||
|
||
-- | @rewindDirStream dp@ calls @rewinddir@ to reposition | ||
-- the directory stream @dp@ at the beginning of the directory. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is exported from
System.Posix.Directory.Internals
, but the module says "no PVP guarantees", so it's fine. Although maybe we can shim it for time being withreadDirStreamWithPtr _ = readDirStreamWith
?..There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I reintroduced it, it would be with a deprecation warning stating it's implemented like that. Happy to do that—let me know.