Rev 3845: (mbp) SunOS fixes to readdir_pyx in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Fri Nov 21 04:44:53 GMT 2008


At file:///home/pqm/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 3845
revision-id: pqm at pqm.ubuntu.com-20081121044450-xgyehkv3u1da37wg
parent: pqm at pqm.ubuntu.com-20081121033557-q9noqdq5v3ulpg9a
parent: mbp at sourcefrog.net-20081121040625-zvsu9pu1pen8pqfr
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Fri 2008-11-21 04:44:50 +0000
message:
  (mbp) SunOS fixes to readdir_pyx
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/_readdir_pyx.pyx        readdir.pyx-20060609152855-rm6v321vuaqyh9tu-1
    ------------------------------------------------------------
    revno: 3841.1.5
    revision-id: mbp at sourcefrog.net-20081121040625-zvsu9pu1pen8pqfr
    parent: mbp at sourcefrog.net-20081120044501-otknkuki8kqbihpj
    committer: Martin Pool <mbp at sourcefrog.net>
    branch nick: 297381-readdir
    timestamp: Fri 2008-11-21 15:06:25 +1100
    message:
      Review cleanups on readdir
    modified:
      bzrlib/_readdir_pyx.pyx        readdir.pyx-20060609152855-rm6v321vuaqyh9tu-1
    ------------------------------------------------------------
    revno: 3841.1.4
    revision-id: mbp at sourcefrog.net-20081120044501-otknkuki8kqbihpj
    parent: mbp at sourcefrog.net-20081120041717-0ay1x181hd3q97r2
    committer: Martin Pool <mbp at sourcefrog.net>
    branch nick: 297381-readdir
    timestamp: Thu 2008-11-20 15:45:01 +1100
    message:
      Use open/fchdir rather than getcwd/chdir to save and restore directory location
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/_readdir_pyx.pyx        readdir.pyx-20060609152855-rm6v321vuaqyh9tu-1
=== modified file 'NEWS'
--- a/NEWS	2008-11-21 00:53:02 +0000
+++ b/NEWS	2008-11-21 04:44:50 +0000
@@ -31,7 +31,9 @@
       (Martin Pool, #289148)
 
     * Don't call the system ``chdir()`` with an empty path. Sun OS seems
-      to give an error in that case. (John Arbash Meinel, #297831)
+      to give an error in that case.  Also, don't count on ``getcwd()`` 
+      being able to allocate a new buffer, which is a gnu extension.  
+      (John Arbash Meinel, Martin Pool, Harry Hirsch, #297831)
 
     * PermissionDenied errors from smart servers no longer cause
       “PermissionDenied: "None"” on the client.

=== modified file 'bzrlib/_readdir_pyx.pyx'
--- a/bzrlib/_readdir_pyx.pyx	2008-11-20 04:17:17 +0000
+++ b/bzrlib/_readdir_pyx.pyx	2008-11-21 04:06:25 +0000
@@ -36,6 +36,8 @@
 
 cdef extern from 'unistd.h':
     int chdir(char *path)
+    int close(int fd)
+    int fchdir(int fd)
     char *getcwd(char *, int size)
 
 cdef extern from 'stdlib.h':
@@ -49,6 +51,7 @@
     ctypedef long time_t
     ctypedef unsigned long ino_t
     ctypedef unsigned long long off_t
+    ctypedef int mode_t
 
 
 cdef extern from 'sys/stat.h':
@@ -69,6 +72,11 @@
     int S_ISSOCK(int mode)
 
 
+cdef extern from 'fcntl.h':
+    int O_RDONLY
+    int open(char *pathname, int flags, mode_t mode)
+
+
 cdef extern from 'Python.h':
     char * PyString_AS_STRING(object)
     ctypedef int Py_ssize_t # Required for older pyrex versions
@@ -279,14 +287,23 @@
     cdef char *name
     cdef int stat_result
     cdef _Stat statvalue
-    cdef char *cwd
     global errno
+    cdef int orig_dir_fd
 
-    cwd = getcwd(NULL, 0)
-    if path != "":
-        # Avoid chdir('') because it causes problems on Sun OS
+    # Avoid chdir('') because it causes problems on Sun OS, and avoid this if
+    # staying in .
+    if path != "" and path != '.':
+        # we change into the requested directory before reading, and back at the
+        # end, because that turns out to make the stat calls measurably faster than
+        # passing full paths every time.
+        orig_dir_fd = open(".", O_RDONLY, 0)
+        if orig_dir_fd == -1:
+            raise OSError(errno, strerror(errno))
         if -1 == chdir(path):
             raise OSError(errno, strerror(errno))
+    else:
+        orig_dir_fd = -1
+
     try:
         the_dir = opendir(".")
         if NULL == the_dir:
@@ -299,7 +316,7 @@
                 # beforehand so that eof can be distinguished from errors.  See
                 # <https://bugs.launchpad.net/bzr/+bug/279381>
                 while True:
-                    errno = 0;
+                    errno = 0
                     entry = readdir(the_dir)
                     if entry == NULL and (errno == EAGAIN or errno == EINTR):
                         # try again
@@ -340,10 +357,14 @@
             if -1 == closedir(the_dir):
                 raise OSError(errno, strerror(errno))
     finally:
-        if -1 == chdir(cwd):
-            free(cwd)
-            raise OSError(errno, strerror(errno))
-        free(cwd)
+        if -1 != orig_dir_fd:
+            failed = False
+            if -1 == fchdir(orig_dir_fd):
+                # try to close the original directory anyhow
+                failed = True
+            if -1 == close(orig_dir_fd) or failed:
+                raise OSError(errno, strerror(errno))
+
     return result
 
 




More information about the bazaar-commits mailing list