@@ -1734,6 +1734,39 @@ posix_fildes_fd(int fd, int (*func)(int))
1734
1734
1735
1735
1736
1736
#ifdef MS_WINDOWS
1737
+ static wchar_t *
1738
+ win32_wgetcwd (wchar_t * buf , DWORD buf_size )
1739
+ {
1740
+ wchar_t * local_buf = buf ;
1741
+ while (1 ) {
1742
+ wchar_t * temp ;
1743
+ DWORD result = GetCurrentDirectoryW (buf_size , local_buf );
1744
+ if (!result )
1745
+ goto fail ;
1746
+
1747
+ /* L'\0' is not counted in result on success. */
1748
+ if (result < buf_size )
1749
+ break ;
1750
+
1751
+ buf_size = result ;
1752
+ temp = PyMem_RawRealloc (local_buf != buf ? local_buf : NULL ,
1753
+ buf_size * sizeof (wchar_t ));
1754
+ if (!temp ) {
1755
+ SetLastError (ERROR_OUTOFMEMORY );
1756
+ goto fail ;
1757
+ }
1758
+ local_buf = temp ;
1759
+ }
1760
+
1761
+ return local_buf ;
1762
+
1763
+ fail :
1764
+ if (local_buf != buf ) {
1765
+ PyMem_RawFree (local_buf );
1766
+ }
1767
+ return NULL ;
1768
+ }
1769
+
1737
1770
/* This is a reimplementation of the C library's chdir function,
1738
1771
but one that produces Win32 errors instead of DOS error codes.
1739
1772
chdir is essentially a wrapper around SetCurrentDirectory; however,
@@ -1742,36 +1775,28 @@ posix_fildes_fd(int fd, int (*func)(int))
1742
1775
static BOOL __stdcall
1743
1776
win32_wchdir (LPCWSTR path )
1744
1777
{
1745
- wchar_t path_buf [MAX_PATH ], * new_path = path_buf ;
1778
+ wchar_t path_buf [MAX_PATH ], * new_path ;
1746
1779
int result ;
1747
1780
wchar_t env [4 ] = L"=x:" ;
1748
1781
1749
1782
if (!SetCurrentDirectoryW (path ))
1750
1783
return FALSE;
1751
- result = GetCurrentDirectoryW (Py_ARRAY_LENGTH (path_buf ), new_path );
1752
- if (!result )
1784
+
1785
+ new_path = win32_wgetcwd (path_buf , (DWORD )Py_ARRAY_LENGTH (path_buf ));
1786
+ if (!new_path )
1753
1787
return FALSE;
1754
- if (result > Py_ARRAY_LENGTH (path_buf )) {
1755
- new_path = PyMem_RawMalloc (result * sizeof (wchar_t ));
1756
- if (!new_path ) {
1757
- SetLastError (ERROR_OUTOFMEMORY );
1758
- return FALSE;
1759
- }
1760
- result = GetCurrentDirectoryW (result , new_path );
1761
- if (!result ) {
1762
- PyMem_RawFree (new_path );
1763
- return FALSE;
1764
- }
1765
- }
1788
+
1766
1789
int is_unc_like_path = (wcsncmp (new_path , L"\\\\" , 2 ) == 0 ||
1767
1790
wcsncmp (new_path , L"//" , 2 ) == 0 );
1768
1791
if (!is_unc_like_path ) {
1769
1792
env [1 ] = new_path [0 ];
1770
1793
result = SetEnvironmentVariableW (env , new_path );
1794
+ } else {
1795
+ result = TRUE;
1771
1796
}
1772
1797
if (new_path != path_buf )
1773
1798
PyMem_RawFree (new_path );
1774
- return result ? TRUE : FALSE ;
1799
+ return result ;
1775
1800
}
1776
1801
#endif
1777
1802
@@ -3736,50 +3761,24 @@ static PyObject *
3736
3761
posix_getcwd (int use_bytes )
3737
3762
{
3738
3763
#ifdef MS_WINDOWS
3739
- wchar_t wbuf [MAXPATHLEN ];
3740
- wchar_t * wbuf2 = wbuf ;
3741
- DWORD len ;
3764
+ wchar_t wbuf [MAX_PATH ];
3765
+ wchar_t * wbuf2 ;
3742
3766
3743
3767
Py_BEGIN_ALLOW_THREADS
3744
- len = GetCurrentDirectoryW (Py_ARRAY_LENGTH (wbuf ), wbuf );
3745
- /* If the buffer is large enough, len does not include the
3746
- terminating \0. If the buffer is too small, len includes
3747
- the space needed for the terminator. */
3748
- if (len >= Py_ARRAY_LENGTH (wbuf )) {
3749
- if (len <= PY_SSIZE_T_MAX / sizeof (wchar_t )) {
3750
- wbuf2 = PyMem_RawMalloc (len * sizeof (wchar_t ));
3751
- }
3752
- else {
3753
- wbuf2 = NULL ;
3754
- }
3755
- if (wbuf2 ) {
3756
- len = GetCurrentDirectoryW (len , wbuf2 );
3757
- }
3758
- }
3768
+ wbuf2 = win32_wgetcwd (wbuf , (DWORD )Py_ARRAY_LENGTH (wbuf ));
3759
3769
Py_END_ALLOW_THREADS
3760
3770
3761
3771
if (!wbuf2 ) {
3762
- PyErr_NoMemory ();
3763
- return NULL ;
3764
- }
3765
- if (!len ) {
3766
- if (wbuf2 != wbuf )
3767
- PyMem_RawFree (wbuf2 );
3768
3772
return PyErr_SetFromWindowsErr (0 );
3769
3773
}
3770
3774
3771
- PyObject * resobj = PyUnicode_FromWideChar (wbuf2 , len );
3775
+ PyObject * resobj = PyUnicode_FromWideChar (wbuf2 , -1 );
3776
+ if (use_bytes && resobj ) {
3777
+ Py_SETREF (resobj , PyUnicode_EncodeFSDefault (resobj ));
3778
+ }
3772
3779
if (wbuf2 != wbuf ) {
3773
3780
PyMem_RawFree (wbuf2 );
3774
3781
}
3775
-
3776
- if (use_bytes ) {
3777
- if (resobj == NULL ) {
3778
- return NULL ;
3779
- }
3780
- Py_SETREF (resobj , PyUnicode_EncodeFSDefault (resobj ));
3781
- }
3782
-
3783
3782
return resobj ;
3784
3783
#else
3785
3784
const size_t chunk = 1024 ;
0 commit comments