[project @ 1996-01-08 20:28:12 by partain]
[ghc-hetmet.git] / ghc / lib / haskell-1.3 / LibDirectory.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1995
3 %
4 \section[LibDirectory]{Haskell 1.3 Directory Operations}
5
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.
13
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.
18
19 \begin{code}
20 module LibDirectory where
21
22 import PreludeIOError
23 import PreludeGlaST
24 import PS
25
26 createDirectory :: FilePath -> IO ()
27 createDirectory path =
28     _ccall_ createDirectory path                    `thenPrimIO` \ rc ->
29     if rc == 0 then
30         return ()
31     else
32         _constructError                             `thenPrimIO` \ ioError ->
33         failWith ioError
34 \end{code}
35
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.
39
40 The operation may fail with:
41 \begin{itemize}
42 \item $AlreadyExists$
43 The operand refers to a directory that already exists.  
44 [$EEXIST$]
45 \item $HardwareFault$
46 A physical I/O error has occurred.
47 [$EIO$]
48 \item $InvalidArgument$
49 The operand is not a valid directory name.
50 [$ENAMETOOLONG$, $ELOOP$]
51 \item $NoSuchThing$
52 There is no path to the directory. 
53 [$ENOENT$, $ENOTDIR$]
54 \item $PermissionDenied$
55 The process has insufficient privileges to perform the operation.
56 [$EROFS$, $EACCES$]
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$, 
61 $EMLINK$] 
62 \item $InappropriateType$
63 The path refers to an existing non-directory object.
64 [$EEXIST$]
65 \end{itemize}
66
67
68 \begin{code}
69 removeDirectory :: FilePath -> IO ()
70 removeDirectory path =
71     _ccall_ removeDirectory path                    `thenPrimIO` \ rc ->
72     if rc == 0 then
73         return ()
74     else
75         _constructError                             `thenPrimIO` \ ioError ->
76         failWith ioError
77 \end{code}
78
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
86 directory).
87
88 The operation may fail with:
89 \begin{itemize}
90 \item $HardwareFault$
91 A physical I/O error has occurred.
92 [$EIO$]
93 \item $InvalidArgument$
94 The operand is not a valid directory name.
95 [$ENAMETOOLONG$, $ELOOP$]
96 \item $NoSuchThing$
97 The directory does not exist. 
98 [$ENOENT$, $ENOTDIR$]
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.
107 [$EINVAL$]
108 \item $InappropriateType$
109 The operand refers to an existing non-directory object.
110 [$ENOTDIR$]
111 \end{itemize}
112
113
114 \begin{code}
115 removeFile :: FilePath -> IO ()
116 removeFile path =
117     _ccall_ removeFile path                         `thenPrimIO` \ rc ->
118     if rc == 0 then
119         return ()
120     else
121         _constructError                             `thenPrimIO` \ ioError ->
122         failWith ioError
123
124 \end{code}
125
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).
131
132 The operation may fail with:
133 \begin{itemize}
134 \item $HardwareFault$
135 A physical I/O error has occurred.
136 [$EIO$]
137 \item $InvalidArgument$
138 The operand is not a valid file name.
139 [$ENAMETOOLONG$, $ELOOP$]
140 \item $NoSuchThing$
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.  
148 [$EBUSY$]
149 \item $InappropriateType$
150 The operand refers to an existing directory.
151 [$EPERM$, $EINVAL$]
152 \end{itemize}
153
154
155 \begin{code}
156 renameDirectory :: FilePath -> FilePath -> IO ()
157 renameDirectory opath npath =
158     _ccall_ renameDirectory opath npath             `thenPrimIO` \ rc ->
159     if rc == 0 then
160         return ()
161     else
162         _constructError                             `thenPrimIO` \ ioError ->
163         failWith ioError
164 \end{code}
165
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
174 must be documented.
175
176 The operation may fail with:
177 \begin{itemize}
178 \item $HardwareFault$
179 A physical I/O error has occurred.
180 [$EIO$]
181 \item $InvalidArgument$
182 Either operand is not a valid directory name.
183 [$ENAMETOOLONG$, $ELOOP$]
184 \item $NoSuchThing$
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$, 
193 $EMLINK$]
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.
199 [$EINVAL$, $EXDEV$]
200 \item $InappropriateType$
201 Either path refers to an existing non-directory object.
202 [$ENOTDIR$, $EISDIR$]
203 \end{itemize}
204
205
206 \begin{code}
207 renameFile :: FilePath -> FilePath -> IO ()
208 renameFile opath npath =
209     _ccall_ renameFile opath npath                  `thenPrimIO` \ rc ->
210     if rc == 0 then
211         return ()
212     else
213         _constructError                             `thenPrimIO` \ ioError ->
214         failWith ioError
215 \end{code}
216
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
223 documented.
224
225 The operation may fail with:
226 \begin{itemize}
227 \item $HardwareFault$
228 A physical I/O error has occurred.
229 [$EIO$]
230 \item $InvalidArgument$
231 Either operand is not a valid file name.
232 [$ENAMETOOLONG$, $ELOOP$]
233 \item $NoSuchThing$
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$, 
242 $EMLINK$]
243 \item $UnsatisfiedConstraints$
244 Implementation-dependent constraints are not satisfied.
245 [$EBUSY$]
246 \item $UnsupportedOperation$
247 The implementation does not support renaming in this situation.
248 [$EXDEV$]
249 \item $InappropriateType$
250 Either path refers to an existing directory.
251 [$ENOTDIR$, $EISDIR$, $EINVAL$, 
252 $EEXIST$, $ENOTEMPTY$]
253 \end{itemize}
254
255
256 \begin{code}
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` \ () ->
262     return entries
263   where
264     getEntries :: _Addr -> Int -> PrimIO [FilePath]
265     getEntries ptr n =
266         _casm_ ``%r = ((char **)%0)[%1];'' ptr n    `thenPrimIO` \ str ->
267         if str == ``NULL'' then 
268             returnPrimIO []
269         else
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)
275
276 \end{code}
277
278 $getDirectoryContents dir$ returns a list of
279 <i>all</i> entries in {\em dir}.
280
281 The operation may fail with:
282 \begin{itemize}
283 \item $HardwareFault$
284 A physical I/O error has occurred.
285 [$EIO$]
286 \item $InvalidArgument$
287 The operand is not a valid directory name.
288 [$ENAMETOOLONG$, $ELOOP$]
289 \item $NoSuchThing$
290 The directory does not exist.
291 [$ENOENT$, $ENOTDIR$]
292 \item $PermissionDenied$
293 The process has insufficient privileges to perform the operation.
294 [$EACCES$]
295 \item $ResourceExhausted$
296 Insufficient resources are available to perform the operation.
297 [$EMFILE$, $ENFILE$]
298 \item $InappropriateType$
299 The path refers to an existing non-directory object.
300 [$ENOTDIR$]
301 \end{itemize}
302
303
304 \begin{code}
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)
313     else
314         _constructError                             `thenPrimIO` \ ioError ->
315         failWith ioError
316 \end{code}
317
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.
321
322 The operation may fail with:
323 \begin{itemize}
324 \item $HardwareFault$
325 A physical I/O error has occurred.
326 [$EIO$]
327 \item $NoSuchThing$
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.
332 [$EACCES$]
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.
337 \end{itemize}
338
339
340 \begin{code}
341 setCurrentDirectory :: FilePath -> IO ()
342 setCurrentDirectory path =
343     _ccall_ setCurrentDirectory path                `thenPrimIO` \ rc ->
344     if rc == 0 then
345         return ()
346     else
347         _constructError                             `thenPrimIO` \ ioError ->
348         failWith ioError
349 \end{code}
350
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}.
354
355 The operation may fail with:
356 \begin{itemize}
357 \item $HardwareFault$
358 A physical I/O error has occurred.
359 [$EIO$]
360 \item $InvalidArgument$
361 The operand is not a valid directory name.
362 [$ENAMETOOLONG$, $ELOOP$]
363 \item $NoSuchThing$
364 The directory does not exist.
365 [$ENOENT$, $ENOTDIR$]
366 \item $PermissionDenied$
367 The process has insufficient privileges to perform the operation.
368 [$EACCES$]
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.
374 [$ENOTDIR$]
375 \end{itemize}
376