@@ -29,12 +29,36 @@ module System.Posix.Directory (
29
29
30
30
-- * Reading directories
31
31
DirStream ,
32
- DirEnt (.. ),
32
+ DirType ( DtUnknown
33
+ #ifdef CONST_DT_FIFO
34
+ , DtFifo
35
+ #endif
36
+ #ifdef CONST_DT_CHR
37
+ , DtChr
38
+ #endif
39
+ #ifdef CONST_DT_DIR
40
+ , DtDir
41
+ #endif
42
+ #ifdef CONST_DT_BLK
43
+ , DtBlk
44
+ #endif
45
+ #ifdef CONST_DT_REG
46
+ , DtReg
47
+ #endif
48
+ #ifdef CONST_DT_LNK
49
+ , DtLnk
50
+ #endif
51
+ #ifdef CONST_DT_SOCK
52
+ , DtSock
53
+ #endif
54
+ #ifdef CONST_DT_WHT
55
+ , DtWht
56
+ #endif
57
+ ),
33
58
openDirStream ,
34
59
readDirStream ,
35
60
readDirStreamMaybe ,
36
- readDirStreamWith ,
37
- readDirStreamWithPtr ,
61
+ readDirStreamWithType ,
38
62
rewindDirStream ,
39
63
closeDirStream ,
40
64
DirStreamOffset ,
@@ -87,11 +111,11 @@ foreign import capi unsafe "HsUnix.h opendir"
87
111
-- | @readDirStream dp@ calls @readdir@ to obtain the
88
112
-- next directory entry (@struct dirent@) for the open directory
89
113
-- stream @dp@, and returns the @d_name@ member of that
90
- -- structure.
114
+ -- structure.
91
115
--
92
- -- Note that this function returns an empty filepath if the end of the
93
- -- directory stream is reached. For a safer alternative use
94
- -- 'readDirStreamMaybe'.
116
+ -- Note that this function returns an empty filepath if the end of the
117
+ -- directory stream is reached. For a safer alternative use
118
+ -- 'readDirStreamMaybe'.
95
119
readDirStream :: DirStream -> IO FilePath
96
120
readDirStream = fmap (fromMaybe " " ) . readDirStreamMaybe
97
121
@@ -104,60 +128,25 @@ readDirStreamMaybe :: DirStream -> IO (Maybe FilePath)
104
128
readDirStreamMaybe = readDirStreamWith
105
129
(\ (DirEnt dEnt) -> d_name dEnt >>= peekFilePath)
106
130
107
- -- | @readDirStreamWith f dp@ calls @readdir@ to obtain the next directory entry
108
- -- (@struct dirent@) for the open directory stream @dp@. If an entry is read,
109
- -- it passes the pointer to that structure to the provided function @f@ for
110
- -- processing. It returns the result of that function call wrapped in a @Just@
111
- -- if an entry was read and @Nothing@ if the end of the directory stream was
112
- -- reached.
113
- --
114
- -- __NOTE:__ The lifetime of the pointer wrapped in the `DirEnt` is limited to
115
- -- invocation of the callback and it will be freed automatically after. Do not
116
- -- pass it to the outside world!
117
- readDirStreamWith :: (DirEnt -> IO a ) -> DirStream -> IO (Maybe a )
118
- readDirStreamWith f dstream = alloca
119
- (\ ptr_dEnt -> readDirStreamWithPtr ptr_dEnt f dstream)
120
-
121
- -- | A version of 'readDirStreamWith' that takes a pre-allocated pointer in
122
- -- addition to the other arguments. This pointer is used to store the pointer
123
- -- to the next directory entry, if there is any. This function is intended for
124
- -- usecases where you need to read a lot of directory entries and want to
125
- -- reuse the pointer for each of them. Using for example 'readDirStream' or
126
- -- 'readDirStreamWith' in this scenario would allocate a new pointer for each
127
- -- call of these functions.
128
- --
129
- -- __NOTE__: You are responsible for releasing the pointer after you are done.
130
- readDirStreamWithPtr :: Ptr DirEnt -> (DirEnt -> IO a ) -> DirStream -> IO (Maybe a )
131
- readDirStreamWithPtr ptr_dEnt f dstream@ (DirStream dirp) = do
132
- resetErrno
133
- r <- c_readdir dirp (castPtr ptr_dEnt)
134
- if (r == 0 )
135
- then do dEnt@ (DirEnt dEntPtr) <- peek ptr_dEnt
136
- if (dEntPtr == nullPtr)
137
- then return Nothing
138
- else do
139
- res <- f dEnt
140
- c_freeDirEnt dEntPtr
141
- return (Just res)
142
- else do errno <- getErrno
143
- if (errno == eINTR)
144
- then readDirStreamWithPtr ptr_dEnt f dstream
145
- else do
146
- let (Errno eo) = errno
147
- if (eo == 0 )
148
- then return Nothing
149
- else throwErrno " readDirStream"
150
-
151
- -- traversing directories
152
- foreign import ccall unsafe " __hscore_readdir"
153
- c_readdir :: Ptr CDir -> Ptr (Ptr CDirent ) -> IO CInt
154
-
155
- foreign import ccall unsafe " __hscore_free_dirent"
156
- c_freeDirEnt :: Ptr CDirent -> IO ()
131
+ -- | @readDirStreamWithType dp@ calls @readdir@ to obtain the
132
+ -- next directory entry (@struct dirent@) for the open directory
133
+ -- stream @dp@. It returns the @d_name@ member of that
134
+ -- structure together with the entry's type (@d_type@) wrapped in a
135
+ -- @Just (d_name, d_type)@ if an entry was read and @Nothing@ if
136
+ -- the end of the directory stream was reached.
137
+ readDirStreamWithType :: DirStream -> IO (Maybe (FilePath , DirType ))
138
+ readDirStreamWithType = readDirStreamWith
139
+ (\ (DirEnt dEnt) -> (,)
140
+ <$> (d_name dEnt >>= peekFilePath)
141
+ <*> (DirType <$> d_type dEnt)
142
+ )
157
143
158
144
foreign import ccall unsafe " __hscore_d_name"
159
145
d_name :: Ptr CDirent -> IO CString
160
146
147
+ foreign import ccall unsafe " __hscore_d_type"
148
+ d_type :: Ptr CDirent -> IO CChar
149
+
161
150
162
151
-- | @getWorkingDirectory@ calls @getcwd@ to obtain the name
163
152
-- of the current working directory.
0 commit comments