]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-119770: Make termios ioctl() constants positive (#119840)
authorVictor Stinner <vstinner@python.org>
Fri, 31 May 2024 15:18:40 +0000 (17:18 +0200)
committerGitHub <noreply@github.com>
Fri, 31 May 2024 15:18:40 +0000 (17:18 +0200)
Lib/test/test_ioctl.py
Lib/test/test_termios.py
Misc/NEWS.d/next/Library/2024-05-31-12-57-31.gh-issue-119770.NCtels.rst [new file with mode: 0644]
Modules/termios.c

index 7b7067eb7b61d4cec7bb97b7c9b31ba82ee7247e..04934dfa16a5f0e6c6a9d13718c5f48cec88183c 100644 (file)
@@ -66,23 +66,15 @@ class IoctlTests(unittest.TestCase):
         # Test with a larger buffer, just for the record.
         self._check_ioctl_mutate_len(2048)
 
-    def test_ioctl_signed_unsigned_code_param(self):
-        if not pty:
-            raise unittest.SkipTest('pty module required')
+    @unittest.skipIf(pty is None, 'pty module required')
+    def test_ioctl_set_window_size(self):
         mfd, sfd = pty.openpty()
         try:
-            if termios.TIOCSWINSZ < 0:
-                set_winsz_opcode_maybe_neg = termios.TIOCSWINSZ
-                set_winsz_opcode_pos = termios.TIOCSWINSZ & 0xffffffff
-            else:
-                set_winsz_opcode_pos = termios.TIOCSWINSZ
-                set_winsz_opcode_maybe_neg, = struct.unpack("i",
-                        struct.pack("I", termios.TIOCSWINSZ))
-
-            our_winsz = struct.pack("HHHH",80,25,0,0)
-            # test both with a positive and potentially negative ioctl code
-            new_winsz = fcntl.ioctl(mfd, set_winsz_opcode_pos, our_winsz)
-            new_winsz = fcntl.ioctl(mfd, set_winsz_opcode_maybe_neg, our_winsz)
+            # (rows, columns, xpixel, ypixel)
+            our_winsz = struct.pack("HHHH", 20, 40, 0, 0)
+            result = fcntl.ioctl(mfd, termios.TIOCSWINSZ, our_winsz)
+            new_winsz = struct.unpack("HHHH", result)
+            self.assertEqual(new_winsz[:2], (20, 40))
         finally:
             os.close(mfd)
             os.close(sfd)
index 58698ffac2d9815f18b4dad7bb08b92f9b266b75..22e397c7a409c4847c5303a80d175a354b01d4be 100644 (file)
@@ -211,6 +211,15 @@ class TestModule(unittest.TestCase):
         self.assertLess(termios.VTIME, termios.NCCS)
         self.assertLess(termios.VMIN, termios.NCCS)
 
+    def test_ioctl_constants(self):
+        # gh-119770: ioctl() constants must be positive
+        for name in dir(termios):
+            if not name.startswith('TIO'):
+                continue
+            value = getattr(termios, name)
+            with self.subTest(name=name):
+                self.assertGreaterEqual(value, 0)
+
     def test_exception(self):
         self.assertTrue(issubclass(termios.error, Exception))
         self.assertFalse(issubclass(termios.error, OSError))
diff --git a/Misc/NEWS.d/next/Library/2024-05-31-12-57-31.gh-issue-119770.NCtels.rst b/Misc/NEWS.d/next/Library/2024-05-31-12-57-31.gh-issue-119770.NCtels.rst
new file mode 100644 (file)
index 0000000..94265e4
--- /dev/null
@@ -0,0 +1 @@
+Make :mod:`termios` ``ioctl()`` constants positive. Patch by Victor Stinner.
index 0633d8f82cc7e423b2df6faa24180741f3db126a..efb5fcc17fa5ef9be0495fb3e9dc9b5c8a736a63 100644 (file)
@@ -1352,9 +1352,21 @@ termios_exec(PyObject *mod)
     }
 
     while (constant->name != NULL) {
-        if (PyModule_AddIntConstant(
-            mod, constant->name, constant->value) < 0) {
-            return -1;
+        if (strncmp(constant->name, "TIO", 3) == 0) {
+            // gh-119770: Convert value to unsigned int for ioctl() constants,
+            // constants can be negative on macOS whereas ioctl() expects an
+            // unsigned long 'request'.
+            unsigned int value = constant->value & UINT_MAX;
+            if (PyModule_Add(mod, constant->name,
+                             PyLong_FromUnsignedLong(value)) < 0) {
+                return -1;
+            }
+        }
+        else {
+            if (PyModule_AddIntConstant(
+                mod, constant->name, constant->value) < 0) {
+                return -1;
+            }
         }
         ++constant;
     }