Issue #2722. Now the char buffer to support the path string has
not fixed length, it mallocs memory if needed. As a result, we
don't have a maximum for the getcwd() method.
diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py
index 179864a..188f463 100644
--- a/Lib/test/test_posix.py
+++ b/Lib/test/test_posix.py
@@ -10,6 +10,7 @@
import time
import os
import pwd
+import shutil
import unittest
import warnings
warnings.filterwarnings('ignore', '.* potential security risk .*',
@@ -231,6 +232,38 @@
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)
diff --git a/Misc/NEWS b/Misc/NEWS
index c98a2af..4964ed7 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -108,6 +108,8 @@
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).
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index a4bbac5..8f32fd4 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -1956,19 +1956,38 @@
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