Issue #2722. Now the char buffer to support the path string has
authorFacundo Batista <facundobatista@gmail.com>
Sun, 22 Jun 2008 13:36:20 +0000 (13:36 +0000)
committerFacundo Batista <facundobatista@gmail.com>
Sun, 22 Jun 2008 13:36:20 +0000 (13:36 +0000)
not fixed length, it mallocs memory if needed. As a result, we
don't have a maximum for the getcwd() method.

Lib/test/test_posix.py
Misc/NEWS
Modules/posixmodule.c

index 179864ac08972f24cc0dc004a7e9d9815c1278cc..188f4631ac88eb1be8db5cd9ba138138b73a3505 100644 (file)
@@ -10,6 +10,7 @@ except ImportError:
 import time
 import os
 import pwd
+import shutil
 import unittest
 import warnings
 warnings.filterwarnings('ignore', '.* potential security risk .*',
@@ -231,6 +232,38 @@ class PosixTester(unittest.TestCase):
             if hasattr(st, 'st_flags'):
                 posix.lchflags(test_support.TESTFN, st.st_flags)
 
+    def test_getcwd_long_pathnames(self):
+        if hasattr(posix, 'getcwd'):
+            dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
+            curdir = os.getcwd()
+            base_path = os.path.abspath(test_support.TESTFN) + '.getcwd'
+
+            try:
+                os.mkdir(base_path)
+                os.chdir(base_path)
+
+                def _create_and_do_getcwd(dirname, current_path_length = 0):
+                    try:
+                        os.mkdir(dirname)
+                    except:
+                        raise test_support.TestSkipped, "mkdir cannot create directory sufficiently deep for getcwd test"
+
+                    os.chdir(dirname)
+                    try:
+                        os.getcwd()
+                        if current_path_length < 1027:
+                            _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
+                    finally:
+                        os.chdir('..')
+                        os.rmdir(dirname)
+
+                _create_and_do_getcwd(dirname)
+
+            finally:
+                shutil.rmtree(base_path)
+                os.chdir(curdir)
+
+
 def test_main():
     test_support.run_unittest(PosixTester)
 
index c98a2af3d1aaaf63c9e5e43116688f13feb1b335..4964ed785026d0999bc020741a1320d2d9c364b3 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -108,6 +108,8 @@ Extension Modules
 Library
 -------
 
+- Issue #2722: Now the os.getcwd() supports very long path names.
+
 - Issue #2888: Fixed the behaviour of pprint when working with nested
   structures, to match the behaviour of 2.5 and 3.0 (now follows the common
   sense).
index a4bbac556a7d38aad56e744b0550971242a4cb10..8f32fd43497a6560f40204cd377e6e995212e87e 100644 (file)
@@ -1956,19 +1956,38 @@ Return a string representing the current working directory.");
 static PyObject *
 posix_getcwd(PyObject *self, PyObject *noargs)
 {
-       char buf[1026];
-       char *res;
+       int bufsize_incr = 1024;
+       int bufsize = 0;
+       char *tmpbuf = NULL;
+       char *res = NULL;
+       PyObject *dynamic_return;
 
        Py_BEGIN_ALLOW_THREADS
+       do {
+               bufsize = bufsize + bufsize_incr;
+               tmpbuf = malloc(bufsize);
+               if (tmpbuf == NULL) {
+                       break;
+               }
 #if defined(PYOS_OS2) && defined(PYCC_GCC)
-       res = _getcwd2(buf, sizeof buf);
+               res = _getcwd2(tmpbuf, bufsize);
 #else
-       res = getcwd(buf, sizeof buf);
+               res = getcwd(tmpbuf, bufsize);
 #endif
+
+               if (res == NULL) {
+                       free(tmpbuf);
+               }
+       } while ((res == NULL) && (errno == ERANGE));
        Py_END_ALLOW_THREADS
+
        if (res == NULL)
                return posix_error();
-       return PyString_FromString(buf);
+
+       dynamic_return = PyString_FromString(tmpbuf);
+       free(tmpbuf);
+
+       return dynamic_return;
 }
 
 #ifdef Py_USING_UNICODE