3 % (c) The GRASP/AQUA Project, Glasgow University, 1995-1996
5 \section[LibDirectory]{Haskell 1.3 Directory Operations}
7 A directory contains a series of entries, each of which is a named
8 reference to a file system object (file, directory etc.). Some
9 entries may be hidden, inaccessible, or have some administrative
10 function (e.g. "." or ".." under POSIX), but in this standard all such
11 entries are considered to form part of the directory contents.
12 Entries in sub-directories are not, however, considered to form part
13 of the directory contents.
15 Each file system object is referenced by a {\em path}. There is
16 normally at least one absolute path to each file system object. In
17 some operating systems, it may also be possible to have paths which
18 are relative to the current directory.
21 createDirectory, removeDirectory, removeFile,
22 renameDirectory, renameFile, getDirectoryContents,
23 getCurrentDirectory, setCurrentDirectory ) where
27 import GHCps ( packCBytesST, unpackPS )
29 createDirectory :: FilePath -> IO ()
30 removeDirectory :: FilePath -> IO ()
31 removeFile :: FilePath -> IO ()
32 renameDirectory :: FilePath -> FilePath -> IO ()
33 renameFile :: FilePath -> FilePath -> IO ()
34 getDirectoryContents :: FilePath -> IO [FilePath]
35 getCurrentDirectory :: IO FilePath
36 setCurrentDirectory :: FilePath -> IO ()
40 $createDirectory dir$ creates a new directory
41 {\em dir} which is initially empty, or as near to empty as the
42 operating system allows.
44 The operation may fail with:
47 The operand refers to a directory that already exists.
50 A physical I/O error has occurred.
52 \item $InvalidArgument$
53 The operand is not a valid directory name.
54 [$ENAMETOOLONG$, $ELOOP$]
56 There is no path to the directory.
58 \item $PermissionDenied$
59 The process has insufficient privileges to perform the operation.
61 \item $ResourceExhausted$
62 Insufficient resources (virtual memory, process file descriptors,
63 physical disk space, etc.) are available to perform the operation.
64 [$EDQUOT$, $ENOSPC$, $ENOMEM$,
66 \item $InappropriateType$
67 The path refers to an existing non-directory object.
72 createDirectory path =
73 _ccall_ createDirectory path `stThen` \ rc ->
77 constructErrorAndFail "createDirectory"
79 ------------------------
81 $removeDirectory dir$ removes an existing directory {\em dir}. The
82 implementation may specify additional constraints which must be
83 satisfied before a directory can be removed (e.g. the directory has to
84 be empty, or may not be in use by other processes). It is not legal
85 for an implementation to partially remove a directory unless the
86 entire directory is removed. A conformant implementation need not
87 support directory removal in all situations (e.g. removal of the root
90 The operation may fail with:
93 A physical I/O error has occurred.
95 \item $InvalidArgument$
96 The operand is not a valid directory name.
97 [$ENAMETOOLONG$, $ELOOP$]
99 The directory does not exist.
100 [$ENOENT$, $ENOTDIR$]
101 \item $PermissionDenied$
102 The process has insufficient privileges to perform the operation.
103 [$EROFS$, $EACCES$, $EPERM$]
104 \item $UnsatisfiedConstraints$
105 Implementation-dependent constraints are not satisfied.
106 [$EBUSY$, $ENOTEMPTY$, $EEXIST$]
107 \item $UnsupportedOperation$
108 The implementation does not support removal in this situation.
110 \item $InappropriateType$
111 The operand refers to an existing non-directory object.
115 removeDirectory path =
116 _ccall_ removeDirectory path `stThen` \ rc ->
120 constructErrorAndFail "removeDirectory"
122 ----------------------------
124 $removeFile file$ removes the directory entry for an existing file
125 {\em file}, where {\em file} is not itself a directory. The
126 implementation may specify additional constraints which must be
127 satisfied before a file can be removed (e.g. the file may not be in
128 use by other processes).
130 The operation may fail with:
132 \item $HardwareFault$
133 A physical I/O error has occurred.
135 \item $InvalidArgument$
136 The operand is not a valid file name.
137 [$ENAMETOOLONG$, $ELOOP$]
139 The file does not exist.
140 [$ENOENT$, $ENOTDIR$]
141 \item $PermissionDenied$
142 The process has insufficient privileges to perform the operation.
143 [$EROFS$, $EACCES$, $EPERM$]
144 \item $UnsatisfiedConstraints$
145 Implementation-dependent constraints are not satisfied.
147 \item $InappropriateType$
148 The operand refers to an existing directory.
153 _ccall_ removeFile path `stThen` \ rc ->
157 constructErrorAndFail "removeFile"
159 ---------------------------
161 $renameDirectory old$ {\em new} changes the name of an existing
162 directory from {\em old} to {\em new}. If the {\em new} directory
163 already exists, it is atomically replaced by the {\em old} directory.
164 If the {\em new} directory is neither the {\em old} directory nor an
165 alias of the {\em old} directory, it is removed as if by
166 $removeDirectory$. A conformant implementation need not support
167 renaming directories in all situations (e.g. renaming to an existing
168 directory, or across different physical devices), but the constraints
171 The operation may fail with:
173 \item $HardwareFault$
174 A physical I/O error has occurred.
176 \item $InvalidArgument$
177 Either operand is not a valid directory name.
178 [$ENAMETOOLONG$, $ELOOP$]
180 The original directory does not exist, or there is no path to the target.
181 [$ENOENT$, $ENOTDIR$]
182 \item $PermissionDenied$
183 The process has insufficient privileges to perform the operation.
184 [$EROFS$, $EACCES$, $EPERM$]
185 \item $ResourceExhausted$
186 Insufficient resources are available to perform the operation.
187 [$EDQUOT$, $ENOSPC$, $ENOMEM$,
189 \item $UnsatisfiedConstraints$
190 Implementation-dependent constraints are not satisfied.
191 [$EBUSY$, $ENOTEMPTY$, $EEXIST$]
192 \item $UnsupportedOperation$
193 The implementation does not support renaming in this situation.
195 \item $InappropriateType$
196 Either path refers to an existing non-directory object.
197 [$ENOTDIR$, $EISDIR$]
200 renameDirectory opath npath =
201 _ccall_ renameDirectory opath npath `stThen` \ rc ->
205 constructErrorAndFail "renameDirectory"
207 -----------------------------
209 $renameFile old$ {\em new} changes the name of an existing file system
210 object from {\em old} to {\em new}. If the {\em new} object already
211 exists, it is atomically replaced by the {\em old} object. Neither
212 path may refer to an existing directory. A conformant implementation
213 need not support renaming files in all situations (e.g. renaming
214 across different physical devices), but the constraints must be
217 The operation may fail with:
219 \item $HardwareFault$
220 A physical I/O error has occurred.
222 \item $InvalidArgument$
223 Either operand is not a valid file name.
224 [$ENAMETOOLONG$, $ELOOP$]
226 The original file does not exist, or there is no path to the target.
227 [$ENOENT$, $ENOTDIR$]
228 \item $PermissionDenied$
229 The process has insufficient privileges to perform the operation.
230 [$EROFS$, $EACCES$, $EPERM$]
231 \item $ResourceExhausted$
232 Insufficient resources are available to perform the operation.
233 [$EDQUOT$, $ENOSPC$, $ENOMEM$,
235 \item $UnsatisfiedConstraints$
236 Implementation-dependent constraints are not satisfied.
238 \item $UnsupportedOperation$
239 The implementation does not support renaming in this situation.
241 \item $InappropriateType$
242 Either path refers to an existing directory.
243 [$ENOTDIR$, $EISDIR$, $EINVAL$,
244 $EEXIST$, $ENOTEMPTY$]
247 renameFile opath npath =
248 _ccall_ renameFile opath npath `stThen` \ rc ->
252 constructErrorAndFail "renameFile"
254 ---------------------------
256 $getDirectoryContents dir$ returns a list of
257 <i>all</i> entries in {\em dir}.
259 The operation may fail with:
261 \item $HardwareFault$
262 A physical I/O error has occurred.
264 \item $InvalidArgument$
265 The operand is not a valid directory name.
266 [$ENAMETOOLONG$, $ELOOP$]
268 The directory does not exist.
269 [$ENOENT$, $ENOTDIR$]
270 \item $PermissionDenied$
271 The process has insufficient privileges to perform the operation.
273 \item $ResourceExhausted$
274 Insufficient resources are available to perform the operation.
276 \item $InappropriateType$
277 The path refers to an existing non-directory object.
281 getDirectoryContents path =
282 _ccall_ getDirectoryContents path `stThen` \ ptr ->
283 if ptr == ``NULL'' then
284 constructErrorAndFail "getDirectoryContents"
286 stToIO (getEntries ptr 0) >>= \ entries ->
287 _ccall_ free ptr `stThen` \ () ->
290 getEntries :: Addr -> Int -> PrimIO [FilePath]
292 _casm_ ``%r = ((char **)%0)[%1];'' ptr n >>= \ str ->
293 if str == ``NULL'' then
296 _ccall_ strlen str >>= \ len ->
297 packCBytesST len str >>= \ entry ->
298 _ccall_ free str >>= \ () ->
299 getEntries ptr (n+1) >>= \ entries ->
300 return (unpackPS entry : entries)
302 ---------------------
304 If the operating system has a notion of current directories,
305 $getCurrentDirectory$ returns an absolute path to the
306 current directory of the calling process.
308 The operation may fail with:
310 \item $HardwareFault$
311 A physical I/O error has occurred.
314 There is no path referring to the current directory.
315 [$EPERM$, $ENOENT$, $ESTALE$...]
316 \item $PermissionDenied$
317 The process has insufficient privileges to perform the operation.
319 \item $ResourceExhausted$
320 Insufficient resources are available to perform the operation.
321 \item $UnsupportedOperation$
322 The operating system has no notion of current directory.
325 getCurrentDirectory =
326 _ccall_ getCurrentDirectory `stThen` \ str ->
327 if str /= ``NULL'' then
328 _ccall_ strlen str `stThen` \ len ->
329 stToIO (packCBytesST len str) >>= \ pwd ->
330 _ccall_ free str `stThen` \ () ->
331 return (unpackPS pwd)
333 constructErrorAndFail "getCurrentDirectory"
335 --------------------------
337 If the operating system has a notion of current directories,
338 $setCurrentDirectory dir$ changes the current
339 directory of the calling process to {\em dir}.
341 The operation may fail with:
343 \item $HardwareFault$
344 A physical I/O error has occurred.
346 \item $InvalidArgument$
347 The operand is not a valid directory name.
348 [$ENAMETOOLONG$, $ELOOP$]
350 The directory does not exist.
351 [$ENOENT$, $ENOTDIR$]
352 \item $PermissionDenied$
353 The process has insufficient privileges to perform the operation.
355 \item $UnsupportedOperation$
356 The operating system has no notion of current directory, or the
357 current directory cannot be dynamically changed.
358 \item $InappropriateType$
359 The path refers to an existing non-directory object.
363 setCurrentDirectory path =
364 _ccall_ setCurrentDirectory path `stThen` \ rc ->
368 constructErrorAndFail "setCurrentDirectory"