1 ##############################################################
3 # opendir.pyx - A class exposing the functionality of
4 # =========== the opendir() family of C libary functions.
7 # greg.ewing@canterbury.ac.nz
9 # This software and derivative works created from it
10 # may be used and redistributed without restriction.
12 ##############################################################
14 cdef extern from "sys/errno.h":
17 cdef extern from "stdio.h":
20 cdef extern from "dirent.h":
25 DIR *c_opendir "opendir" (char *)
26 int readdir_r(DIR *, dirent *, dirent **)
28 void seekdir(DIR *, long)
33 #------------------------------------------------------------------
36 """opendir(pathname) --> an open directory object
38 Opens a directory and provides incremental access to
39 the filenames it contains. May be used as a file-like
40 object or as an iterator.
42 When used as a file-like object, each call to read()
43 returns one filename, or an empty string when the end
44 of the directory is reached. The close() method should
45 be called when finished with the directory.
47 The close() method should also be called when used as
48 an iterator and iteration is stopped prematurely. If
49 iteration proceeds to completion, the directory is
50 closed automatically."""
54 def __cinit__(self, char *path):
55 self.dir = c_opendir(path)
57 raise IOError(errno, "%s: '%s'" % (strerror(errno), path))
59 def __dealloc__(self):
64 """read() --> filename or empty string
66 Returns the next filename from the directory, or an empty
67 string if the end of the directory has been reached."""
69 cdef dirent entry, *result
71 if readdir_r(self.dir, &entry, &result) < 0:
79 """tell() --> position
81 Returns a value representing the current position in the
82 directory, suitable for passing to tell(). Only valid for
83 this directory object as long as it remains open."""
86 return telldir(self.dir)
88 def seek(self, long pos):
91 Returns the directory to the specified position, which
92 should be a value previously returned by tell()."""
95 seekdir(self.dir, pos)
100 Resets the position to the beginning of the directory."""
108 Closes the directory and frees the underlying file descriptor."""
111 if closedir(self.dir) < 0:
115 # MaxOSX doesn't seem to have dirfd, despite what the
119 # """fileno() --> file descriptor
121 # Returns the file descriptor associated with the open directory."""
124 # return dirfd(self.dir)
130 """next() --> filename
132 Returns the next filename from the directory. If the end of the
133 directory has been reached, closes the directory and raises
143 #------------------------------------------------------------------
145 cdef int check_open(opendir d) except -1:
147 raise ValueError("Directory is closed")