~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/_readdir_pyx.pyx

  • Committer: Robert Collins
  • Date: 2008-10-08 01:28:40 UTC
  • mfrom: (3769 +trunk)
  • mto: This revision was merged to the branch mainline in revision 3770.
  • Revision ID: robertc@robertcollins.net-20081008012840-kn5u1944l4ls60t8
NEWS conflicts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
    pass
26
26
 
27
27
 
28
 
# the opaque C library DIR type.
29
28
cdef extern from 'errno.h':
30
29
    int ENOENT
31
30
    int ENOTDIR
32
31
    int EAGAIN
 
32
    int EINTR
 
33
    char *strerror(int errno)
 
34
    # not necessarily a real variable, but this should be close enough
33
35
    int errno
34
 
    char *strerror(int errno)
35
36
 
36
37
cdef extern from 'unistd.h':
37
38
    int chdir(char *path)
89
90
    ctypedef struct dirent:
90
91
        char d_name[256]
91
92
        ino_t d_ino
 
93
    # the opaque C library DIR type.
92
94
    ctypedef struct DIR
93
95
    # should be DIR *, pyrex barfs.
94
96
    DIR * opendir(char * name)
278
280
    cdef int stat_result
279
281
    cdef _Stat statvalue
280
282
    cdef char *cwd
 
283
    global errno
281
284
 
282
285
    cwd = getcwd(NULL, 0)
283
286
    if -1 == chdir(path):
289
292
    try:
290
293
        entry = &sentinel
291
294
        while entry != NULL:
292
 
            entry = readdir(the_dir)
 
295
            # Unlike most libc functions, readdir needs errno set to 0
 
296
            # beforehand so that eof can be distinguished from errors.  See
 
297
            # <https://bugs.launchpad.net/bzr/+bug/279381>
 
298
            while True:
 
299
                errno = 0;
 
300
                entry = readdir(the_dir)
 
301
                if entry == NULL and (errno == EAGAIN or errno == EINTR):
 
302
                    # try again
 
303
                    continue
 
304
                else:
 
305
                    break
293
306
            if entry == NULL:
294
 
                if errno == EAGAIN:
295
 
                    # try again
296
 
                    continue
297
 
                elif errno != ENOTDIR and errno != ENOENT and errno != 0:
 
307
                if errno == ENOTDIR or errno == 0:
298
308
                    # We see ENOTDIR at the end of a normal directory.
299
309
                    # As ENOTDIR for read_dir(file) is triggered on opendir,
300
310
                    # we consider ENOTDIR to be 'no error'.
301
 
                    # ENOENT is listed as 'invalid position in the dir stream' for
302
 
                    # readdir. We swallow this for now and just keep reading.
 
311
                    continue
 
312
                else:
303
313
                    raise OSError(errno, strerror(errno))
304
 
                else:
305
 
                    # done
306
 
                    continue
307
314
            name = entry.d_name
308
315
            if not (name[0] == c"." and (
309
316
                (name[1] == 0) or