2 % (c) The GRASP/AQUA Project, Glasgow University, 1995
4 \section[LibDirectory]{Haskell 1.3 Directory Operations}
6 A directory contains a series of entries, each of which is a named
7 reference to a file system object (file, directory etc.). Some
8 entries may be hidden, inaccessible, or have some administrative
9 function (e.g. "." or ".." under POSIX), but in this standard all such
10 entries are considered to form part of the directory contents.
11 Entries in sub-directories are not, however, considered to form part
12 of the directory contents.
14 Each file system object is referenced by a {\em path}. There is
15 normally at least one absolute path to each file system object. In
16 some operating systems, it may also be possible to have paths which
17 are relative to the current directory.
20 module LibDirectory where
26 createDirectory :: FilePath -> IO ()
27 createDirectory path =
28 _ccall_ createDirectory path `thenPrimIO` \ rc ->
32 _constructError `thenPrimIO` \ ioError ->
36 $createDirectory dir$ creates a new directory
37 {\em dir} which is initially empty, or as near to empty as the
38 operating system allows.
40 The operation may fail with:
43 The operand refers to a directory that already exists.
46 A physical I/O error has occurred.
48 \item $InvalidArgument$
49 The operand is not a valid directory name.
50 [$ENAMETOOLONG$, $ELOOP$]
52 There is no path to the directory.
54 \item $PermissionDenied$
55 The process has insufficient privileges to perform the operation.
57 \item $ResourceExhausted$
58 Insufficient resources (virtual memory, process file descriptors,
59 physical disk space, etc.) are available to perform the operation.
60 [$EDQUOT$, $ENOSPC$, $ENOMEM$,
62 \item $InappropriateType$
63 The path refers to an existing non-directory object.
69 removeDirectory :: FilePath -> IO ()
70 removeDirectory path =
71 _ccall_ removeDirectory path `thenPrimIO` \ rc ->
75 _constructError `thenPrimIO` \ ioError ->
79 $removeDirectory dir$ removes an existing directory {\em dir}. The
80 implementation may specify additional constraints which must be
81 satisfied before a directory can be removed (e.g. the directory has to
82 be empty, or may not be in use by other processes). It is not legal
83 for an implementation to partially remove a directory unless the
84 entire directory is removed. A conformant implementation need not
85 support directory removal in all situations (e.g. removal of the root
88 The operation may fail with:
91 A physical I/O error has occurred.
93 \item $InvalidArgument$
94 The operand is not a valid directory name.
95 [$ENAMETOOLONG$, $ELOOP$]
97 The directory does not exist.
99 \item $PermissionDenied$
100 The process has insufficient privileges to perform the operation.
101 [$EROFS$, $EACCES$, $EPERM$]
102 \item $UnsatisfiedConstraints$
103 Implementation-dependent constraints are not satisfied.
104 [$EBUSY$, $ENOTEMPTY$, $EEXIST$]
105 \item $UnsupportedOperation$
106 The implementation does not support removal in this situation.
108 \item $InappropriateType$
109 The operand refers to an existing non-directory object.
115 removeFile :: FilePath -> IO ()
117 _ccall_ removeFile path `thenPrimIO` \ rc ->
121 _constructError `thenPrimIO` \ ioError ->
126 $removeFile file$ removes the directory entry for an existing file
127 {\em file}, where {\em file} is not itself a directory. The
128 implementation may specify additional constraints which must be
129 satisfied before a file can be removed (e.g. the file may not be in
130 use by other processes).
132 The operation may fail with:
134 \item $HardwareFault$
135 A physical I/O error has occurred.
137 \item $InvalidArgument$
138 The operand is not a valid file name.
139 [$ENAMETOOLONG$, $ELOOP$]
141 The file does not exist.
142 [$ENOENT$, $ENOTDIR$]
143 \item $PermissionDenied$
144 The process has insufficient privileges to perform the operation.
145 [$EROFS$, $EACCES$, $EPERM$]
146 \item $UnsatisfiedConstraints$
147 Implementation-dependent constraints are not satisfied.
149 \item $InappropriateType$
150 The operand refers to an existing directory.
156 renameDirectory :: FilePath -> FilePath -> IO ()
157 renameDirectory opath npath =
158 _ccall_ renameDirectory opath npath `thenPrimIO` \ rc ->
162 _constructError `thenPrimIO` \ ioError ->
166 $renameDirectory old$ {\em new} changes the name of an existing
167 directory from {\em old} to {\em new}. If the {\em new} directory
168 already exists, it is atomically replaced by the {\em old} directory.
169 If the {\em new} directory is neither the {\em old} directory nor an
170 alias of the {\em old} directory, it is removed as if by
171 $removeDirectory$. A conformant implementation need not support
172 renaming directories in all situations (e.g. renaming to an existing
173 directory, or across different physical devices), but the constraints
176 The operation may fail with:
178 \item $HardwareFault$
179 A physical I/O error has occurred.
181 \item $InvalidArgument$
182 Either operand is not a valid directory name.
183 [$ENAMETOOLONG$, $ELOOP$]
185 The original directory does not exist, or there is no path to the target.
186 [$ENOENT$, $ENOTDIR$]
187 \item $PermissionDenied$
188 The process has insufficient privileges to perform the operation.
189 [$EROFS$, $EACCES$, $EPERM$]
190 \item $ResourceExhausted$
191 Insufficient resources are available to perform the operation.
192 [$EDQUOT$, $ENOSPC$, $ENOMEM$,
194 \item $UnsatisfiedConstraints$
195 Implementation-dependent constraints are not satisfied.
196 [$EBUSY$, $ENOTEMPTY$, $EEXIST$]
197 \item $UnsupportedOperation$
198 The implementation does not support renaming in this situation.
200 \item $InappropriateType$
201 Either path refers to an existing non-directory object.
202 [$ENOTDIR$, $EISDIR$]
207 renameFile :: FilePath -> FilePath -> IO ()
208 renameFile opath npath =
209 _ccall_ renameFile opath npath `thenPrimIO` \ rc ->
213 _constructError `thenPrimIO` \ ioError ->
217 $renameFile old$ {\em new} changes the name of an existing file system
218 object from {\em old} to {\em new}. If the {\em new} object already
219 exists, it is atomically replaced by the {\em old} object. Neither
220 path may refer to an existing directory. A conformant implementation
221 need not support renaming files in all situations (e.g. renaming
222 across different physical devices), but the constraints must be
225 The operation may fail with:
227 \item $HardwareFault$
228 A physical I/O error has occurred.
230 \item $InvalidArgument$
231 Either operand is not a valid file name.
232 [$ENAMETOOLONG$, $ELOOP$]
234 The original file does not exist, or there is no path to the target.
235 [$ENOENT$, $ENOTDIR$]
236 \item $PermissionDenied$
237 The process has insufficient privileges to perform the operation.
238 [$EROFS$, $EACCES$, $EPERM$]
239 \item $ResourceExhausted$
240 Insufficient resources are available to perform the operation.
241 [$EDQUOT$, $ENOSPC$, $ENOMEM$,
243 \item $UnsatisfiedConstraints$
244 Implementation-dependent constraints are not satisfied.
246 \item $UnsupportedOperation$
247 The implementation does not support renaming in this situation.
249 \item $InappropriateType$
250 Either path refers to an existing directory.
251 [$ENOTDIR$, $EISDIR$, $EINVAL$,
252 $EEXIST$, $ENOTEMPTY$]
257 getDirectoryContents :: FilePath -> IO [FilePath]
258 getDirectoryContents path =
259 _ccall_ getDirectoryContents path `thenPrimIO` \ ptr ->
260 getEntries ptr 0 `thenPrimIO` \ entries ->
261 _ccall_ free ptr `thenPrimIO` \ () ->
264 getEntries :: _Addr -> Int -> PrimIO [FilePath]
266 _casm_ ``%r = ((char **)%0)[%1];'' ptr n `thenPrimIO` \ str ->
267 if str == ``NULL'' then
270 _ccall_ strlen str `thenPrimIO` \ len ->
271 _packCBytesST len str `thenStrictlyST` \ entry ->
272 _ccall_ free str `thenPrimIO` \ () ->
273 getEntries ptr (n+1) `thenPrimIO` \ entries ->
274 returnPrimIO (_unpackPS entry : entries)
278 $getDirectoryContents dir$ returns a list of
279 <i>all</i> entries in {\em dir}.
281 The operation may fail with:
283 \item $HardwareFault$
284 A physical I/O error has occurred.
286 \item $InvalidArgument$
287 The operand is not a valid directory name.
288 [$ENAMETOOLONG$, $ELOOP$]
290 The directory does not exist.
291 [$ENOENT$, $ENOTDIR$]
292 \item $PermissionDenied$
293 The process has insufficient privileges to perform the operation.
295 \item $ResourceExhausted$
296 Insufficient resources are available to perform the operation.
298 \item $InappropriateType$
299 The path refers to an existing non-directory object.
305 getCurrentDirectory :: IO FilePath
306 getCurrentDirectory =
307 _ccall_ getCurrentDirectory `thenPrimIO` \ str ->
308 if str /= ``NULL'' then
309 _ccall_ strlen str `thenPrimIO` \ len ->
310 _packCBytesST len str `thenStrictlyST` \ pwd ->
311 _ccall_ free str `thenPrimIO` \ () ->
312 return (_unpackPS pwd)
314 _constructError `thenPrimIO` \ ioError ->
318 If the operating system has a notion of current directories,
319 $getCurrentDirectory$ returns an absolute path to the
320 current directory of the calling process.
322 The operation may fail with:
324 \item $HardwareFault$
325 A physical I/O error has occurred.
328 There is no path referring to the current directory.
329 [$EPERM$, $ENOENT$, $ESTALE$...]
330 \item $PermissionDenied$
331 The process has insufficient privileges to perform the operation.
333 \item $ResourceExhausted$
334 Insufficient resources are available to perform the operation.
335 \item $UnsupportedOperation$
336 The operating system has no notion of current directory.
341 setCurrentDirectory :: FilePath -> IO ()
342 setCurrentDirectory path =
343 _ccall_ setCurrentDirectory path `thenPrimIO` \ rc ->
347 _constructError `thenPrimIO` \ ioError ->
351 If the operating system has a notion of current directories,
352 $setCurrentDirectory dir$ changes the current
353 directory of the calling process to {\em dir}.
355 The operation may fail with:
357 \item $HardwareFault$
358 A physical I/O error has occurred.
360 \item $InvalidArgument$
361 The operand is not a valid directory name.
362 [$ENAMETOOLONG$, $ELOOP$]
364 The directory does not exist.
365 [$ENOENT$, $ENOTDIR$]
366 \item $PermissionDenied$
367 The process has insufficient privileges to perform the operation.
369 \item $UnsupportedOperation$
370 The operating system has no notion of current directory, or the
371 current directory cannot be dynamically changed.
372 \item $InappropriateType$
373 The path refers to an existing non-directory object.