~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/_readdir_pyx.pyx

  • Committer: Andrew Bennetts
  • Date: 2010-01-04 02:25:11 UTC
  • mfrom: (4634.108.8 2.0)
  • mto: This revision was merged to the branch mainline in revision 4928.
  • Revision ID: andrew.bennetts@canonical.com-20100104022511-2tq2r9w2te84wzgs
Merge lp:bzr/2.0 into lp:bzr, including fixes for #343218, #495000, #495023, #494406 and #498378.

Show diffs side-by-side

added added

removed removed

Lines of Context:
78
78
 
79
79
 
80
80
cdef extern from 'Python.h':
 
81
    int PyErr_CheckSignals() except -1
81
82
    char * PyString_AS_STRING(object)
82
83
    ctypedef int Py_ssize_t # Required for older pyrex versions
83
84
    ctypedef struct PyObject:
271
272
        return result
272
273
 
273
274
 
 
275
cdef raise_os_error(int errnum, char *msg_prefix, path):
 
276
    if errnum == EINTR:
 
277
        PyErr_CheckSignals()
 
278
    raise OSError(errnum, msg_prefix + strerror(errnum), path)
 
279
 
 
280
 
274
281
cdef _read_dir(path):
275
282
    """Like os.listdir, this reads the contents of a directory.
276
283
 
298
305
        # passing full paths every time.
299
306
        orig_dir_fd = open(".", O_RDONLY, 0)
300
307
        if orig_dir_fd == -1:
301
 
            raise OSError(errno, "open: " + strerror(errno), ".")
 
308
            raise_os_error(errno, "open: ", ".")
302
309
        if -1 == chdir(path):
303
 
            raise OSError(errno, "chdir: " + strerror(errno), path)
 
310
            raise_os_error(errno, "chdir: ", path)
304
311
    else:
305
312
        orig_dir_fd = -1
306
313
 
307
314
    try:
308
315
        the_dir = opendir(".")
309
316
        if NULL == the_dir:
310
 
            raise OSError(errno, "opendir: " + strerror(errno), path)
 
317
            raise_os_error(errno, "opendir: ", path)
311
318
        try:
312
319
            result = []
313
320
            entry = &sentinel
319
326
                    errno = 0
320
327
                    entry = readdir(the_dir)
321
328
                    if entry == NULL and (errno == EAGAIN or errno == EINTR):
 
329
                        if errno == EINTR:
 
330
                            PyErr_CheckSignals()
322
331
                        # try again
323
332
                        continue
324
333
                    else:
330
339
                        # we consider ENOTDIR to be 'no error'.
331
340
                        continue
332
341
                    else:
333
 
                        raise OSError(errno, "readdir: " + strerror(errno), path)
 
342
                        raise_os_error(errno, "readdir: ", path)
334
343
                name = entry.d_name
335
344
                if not (name[0] == c"." and (
336
345
                    (name[1] == 0) or 
340
349
                    stat_result = lstat(entry.d_name, &statvalue._st)
341
350
                    if stat_result != 0:
342
351
                        if errno != ENOENT:
343
 
                            raise OSError(errno, "lstat: " + strerror(errno),
 
352
                            raise_os_error(errno, "lstat: ",
344
353
                                path + "/" + entry.d_name)
345
354
                        else:
346
355
                            # the file seems to have disappeared after being
358
367
                        statvalue, None))
359
368
        finally:
360
369
            if -1 == closedir(the_dir):
361
 
                raise OSError(errno, "closedir: " + strerror(errno), path)
 
370
                raise_os_error(errno, "closedir: ", path)
362
371
    finally:
363
372
        if -1 != orig_dir_fd:
364
373
            failed = False
366
375
                # try to close the original directory anyhow
367
376
                failed = True
368
377
            if -1 == close(orig_dir_fd) or failed:
369
 
                raise OSError(errno, "return to orig_dir: " + strerror(errno))
 
378
                raise_os_error(errno, "return to orig_dir: ", "")
370
379
 
371
380
    return result
372
381