~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/_readdir_pyx.pyx

  • Committer: Vincent Ladeuil
  • Date: 2010-02-10 15:46:03 UTC
  • mfrom: (4985.3.21 update)
  • mto: This revision was merged to the branch mainline in revision 5021.
  • Revision ID: v.ladeuil+lp@free.fr-20100210154603-k4no1gvfuqpzrw7p
Update performs two merges in a more logical order but stop on conflicts

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006, 2008 Canonical Ltd
 
1
# Copyright (C) 2006, 2008, 2009 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
"""Wrapper for readdir which returns files ordered by inode."""
18
18
 
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:
155
156
        (mode, ino, dev, nlink, uid, gid, size, None(atime), mtime, ctime)
156
157
        """
157
158
        return repr((self.st_mode, 0, 0, 0, 0, 0, self.st_size, None,
158
 
                     self._mtime, self._ctime))
 
159
                     self.st_mtime, self.st_ctime))
159
160
 
160
161
 
161
162
from bzrlib import osutils
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, strerror(errno))
 
308
            raise_os_error(errno, "open: ", ".")
302
309
        if -1 == chdir(path):
303
 
            raise OSError(errno, strerror(errno))
 
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, strerror(errno))
 
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, strerror(errno))
 
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, strerror(errno))
 
352
                            raise_os_error(errno, "lstat: ",
 
353
                                path + "/" + entry.d_name)
344
354
                        else:
345
 
                            kind = _missing
346
 
                            statvalue = None
 
355
                            # the file seems to have disappeared after being
 
356
                            # seen by readdir - perhaps a transient temporary
 
357
                            # file.  there's no point returning it.
 
358
                            continue
347
359
                    # We append a 5-tuple that can be modified in-place by the C
348
360
                    # api:
349
361
                    # inode to sort on (to replace with top_path)
355
367
                        statvalue, None))
356
368
        finally:
357
369
            if -1 == closedir(the_dir):
358
 
                raise OSError(errno, strerror(errno))
 
370
                raise_os_error(errno, "closedir: ", path)
359
371
    finally:
360
372
        if -1 != orig_dir_fd:
361
373
            failed = False
363
375
                # try to close the original directory anyhow
364
376
                failed = True
365
377
            if -1 == close(orig_dir_fd) or failed:
366
 
                raise OSError(errno, strerror(errno))
 
378
                raise_os_error(errno, "return to orig_dir: ", "")
367
379
 
368
380
    return result
369
381