From 5596b0cfc275a649f17a97c881d094a949adad6d Mon Sep 17 00:00:00 2001 From: Facundo Batista Date: Sun, 22 Jun 2008 13:36:20 +0000 Subject: [PATCH] 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. --- Lib/test/test_posix.py | 33 +++++++++++++++++++++++++++++++++ Misc/NEWS | 2 ++ Modules/posixmodule.c | 29 ++++++++++++++++++++++++----- 3 files changed, 59 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index 179864ac089..188f4631ac8 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -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) diff --git a/Misc/NEWS b/Misc/NEWS index c98a2af3d1a..4964ed78502 100644 --- 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). diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index a4bbac556a7..8f32fd43497 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -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