From edb72047f35d6da48c59bcfe0c655939a88ea0a6 Mon Sep 17 00:00:00 2001 From: Raghunandan Bhat <33787364+raghunandanbhat@users.noreply.github.com> Date: Thu, 28 Jul 2022 18:48:33 -0400 Subject: gh-43414: os.get_terminal_size() now uses the actual file descriptor on Windows instead of mapping to standard handles (#93203) --- Lib/test/test_os.py | 13 +++++++++++++ .../2022-05-28-19-36-13.gh-issue-43414.NGMJ3g.rst | 2 ++ Modules/posixmodule.c | 17 ++--------------- 3 files changed, 17 insertions(+), 15 deletions(-) create mode 100644 Misc/NEWS.d/next/Windows/2022-05-28-19-36-13.gh-issue-43414.NGMJ3g.rst diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 9970b23..2dafb78 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -3665,6 +3665,19 @@ class TermsizeTests(unittest.TestCase): raise self.assertEqual(expected, actual) + @unittest.skipUnless(sys.platform == 'win32', 'Windows specific test') + def test_windows_fd(self): + """Check if get_terminal_size() returns a meaningful value in Windows""" + try: + conout = open('conout$', 'w') + except OSError: + self.skipTest('failed to open conout$') + with conout: + size = os.get_terminal_size(conout.fileno()) + + self.assertGreaterEqual(size.columns, 0) + self.assertGreaterEqual(size.lines, 0) + @unittest.skipUnless(hasattr(os, 'memfd_create'), 'requires os.memfd_create') @support.requires_linux_version(3, 17) diff --git a/Misc/NEWS.d/next/Windows/2022-05-28-19-36-13.gh-issue-43414.NGMJ3g.rst b/Misc/NEWS.d/next/Windows/2022-05-28-19-36-13.gh-issue-43414.NGMJ3g.rst new file mode 100644 index 0000000..553e876 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2022-05-28-19-36-13.gh-issue-43414.NGMJ3g.rst @@ -0,0 +1,2 @@ +:func:`os.get_terminal_size` now attempts to read the size from any provided +handle, rather than only supporting file descriptors 0, 1 and 2. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 5855c42..d45fa23 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -13247,24 +13247,11 @@ os_get_terminal_size_impl(PyObject *module, int fd) #ifdef TERMSIZE_USE_CONIO { - DWORD nhandle; HANDLE handle; CONSOLE_SCREEN_BUFFER_INFO csbi; - switch (fd) { - case 0: nhandle = STD_INPUT_HANDLE; - break; - case 1: nhandle = STD_OUTPUT_HANDLE; - break; - case 2: nhandle = STD_ERROR_HANDLE; - break; - default: - return PyErr_Format(PyExc_ValueError, "bad file descriptor"); - } - handle = GetStdHandle(nhandle); - if (handle == NULL) - return PyErr_Format(PyExc_OSError, "handle cannot be retrieved"); + handle = _Py_get_osfhandle(fd); if (handle == INVALID_HANDLE_VALUE) - return PyErr_SetFromWindowsErr(0); + return NULL; if (!GetConsoleScreenBufferInfo(handle, &csbi)) return PyErr_SetFromWindowsErr(0); -- cgit v0.12