diff options
author | Segev Finer <segev208@gmail.com> | 2021-04-24 01:00:27 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-23 23:00:27 +0100 |
commit | 5e437fb872279960992c9a07f1a4c051b4948c53 (patch) | |
tree | da3e3ad584eba24da9cfe63c4acd1a01e55d4676 /Python/fileutils.c | |
parent | 6b59e662fa39a356d6eb03d349b140477857f4b1 (diff) | |
download | cpython-git-5e437fb872279960992c9a07f1a4c051b4948c53.tar.gz |
bpo-30555: Fix WindowsConsoleIO fails in the presence of fd redirection (GH-1927)
This works by not caching the handle and instead getting the handle from
the file descriptor each time, so that if the actual handle changes by
fd redirection closing/opening the console handle beneath our feet, we
will keep working correctly.
Diffstat (limited to 'Python/fileutils.c')
-rw-r--r-- | Python/fileutils.c | 61 |
1 files changed, 45 insertions, 16 deletions
diff --git a/Python/fileutils.c b/Python/fileutils.c index 4997f92225..2a079bbadc 100644 --- a/Python/fileutils.c +++ b/Python/fileutils.c @@ -1016,9 +1016,7 @@ _Py_fstat_noraise(int fd, struct _Py_stat_struct *status) HANDLE h; int type; - _Py_BEGIN_SUPPRESS_IPH - h = (HANDLE)_get_osfhandle(fd); - _Py_END_SUPPRESS_IPH + h = _Py_get_osfhandle_noraise(fd); if (h == INVALID_HANDLE_VALUE) { /* errno is already set by _get_osfhandle, but we also set @@ -1157,9 +1155,7 @@ get_inheritable(int fd, int raise) HANDLE handle; DWORD flags; - _Py_BEGIN_SUPPRESS_IPH - handle = (HANDLE)_get_osfhandle(fd); - _Py_END_SUPPRESS_IPH + handle = _Py_get_osfhandle_noraise(fd); if (handle == INVALID_HANDLE_VALUE) { if (raise) PyErr_SetFromErrno(PyExc_OSError); @@ -1230,9 +1226,7 @@ set_inheritable(int fd, int inheritable, int raise, int *atomic_flag_works) } #ifdef MS_WINDOWS - _Py_BEGIN_SUPPRESS_IPH - handle = (HANDLE)_get_osfhandle(fd); - _Py_END_SUPPRESS_IPH + handle = _Py_get_osfhandle_noraise(fd); if (handle == INVALID_HANDLE_VALUE) { if (raise) PyErr_SetFromErrno(PyExc_OSError); @@ -2006,13 +2000,9 @@ _Py_dup(int fd) assert(PyGILState_Check()); #ifdef MS_WINDOWS - _Py_BEGIN_SUPPRESS_IPH - handle = (HANDLE)_get_osfhandle(fd); - _Py_END_SUPPRESS_IPH - if (handle == INVALID_HANDLE_VALUE) { - PyErr_SetFromErrno(PyExc_OSError); + handle = _Py_get_osfhandle(fd); + if (handle == INVALID_HANDLE_VALUE) return -1; - } Py_BEGIN_ALLOW_THREADS _Py_BEGIN_SUPPRESS_IPH @@ -2122,8 +2112,47 @@ error: PyErr_SetFromErrno(PyExc_OSError); return -1; } -#endif +#else /* MS_WINDOWS */ +void* +_Py_get_osfhandle_noraise(int fd) +{ + void *handle; + _Py_BEGIN_SUPPRESS_IPH + handle = (void*)_get_osfhandle(fd); + _Py_END_SUPPRESS_IPH + return handle; +} +void* +_Py_get_osfhandle(int fd) +{ + void *handle = _Py_get_osfhandle_noraise(fd); + if (handle == INVALID_HANDLE_VALUE) + PyErr_SetFromErrno(PyExc_OSError); + + return handle; +} + +int +_Py_open_osfhandle_noraise(void *handle, int flags) +{ + int fd; + _Py_BEGIN_SUPPRESS_IPH + fd = _open_osfhandle((intptr_t)handle, flags); + _Py_END_SUPPRESS_IPH + return fd; +} + +int +_Py_open_osfhandle(void *handle, int flags) +{ + int fd = _Py_open_osfhandle_noraise(handle, flags); + if (fd == -1) + PyErr_SetFromErrno(PyExc_OSError); + + return fd; +} +#endif /* MS_WINDOWS */ int _Py_GetLocaleconvNumeric(struct lconv *lc, |