diff options
author | Antoine Pitrou <solipsis@pitrou.net> | 2010-09-07 16:30:09 (GMT) |
---|---|---|
committer | Antoine Pitrou <solipsis@pitrou.net> | 2010-09-07 16:30:09 (GMT) |
commit | 5e38aae91bcc1ae0560debb9866df17e7da20ab1 (patch) | |
tree | e2f7c76e4df9baa236dfc2eeb7025d14f73133d4 | |
parent | 7f7561ebfc10089d7ee651487835d6229d5a97e2 (diff) | |
download | cpython-5e38aae91bcc1ae0560debb9866df17e7da20ab1.zip cpython-5e38aae91bcc1ae0560debb9866df17e7da20ab1.tar.gz cpython-5e38aae91bcc1ae0560debb9866df17e7da20ab1.tar.bz2 |
Issue #9758: When fcntl.ioctl() was called with mutable_flag set to True,
and the passed buffer was exactly 1024 bytes long, the buffer wouldn't
be updated back after the system call. Original patch by Brian Brazil.
-rw-r--r-- | Lib/test/test_ioctl.py | 31 | ||||
-rw-r--r-- | Misc/NEWS | 4 | ||||
-rw-r--r-- | Modules/fcntlmodule.c | 2 |
3 files changed, 31 insertions, 6 deletions
diff --git a/Lib/test/test_ioctl.py b/Lib/test/test_ioctl.py index 07dac09..6c7ab0c 100644 --- a/Lib/test/test_ioctl.py +++ b/Lib/test/test_ioctl.py @@ -1,3 +1,4 @@ +import array import unittest from test.support import run_unittest, import_module, get_attribute import os, struct @@ -34,16 +35,36 @@ class IoctlTests(unittest.TestCase): rpgrp = struct.unpack("i", r)[0] self.assertIn(rpgrp, ids) - def test_ioctl_mutate(self): - import array - buf = array.array('i', [0]) + def _check_ioctl_mutate_len(self, nbytes=None): + buf = array.array('i') + intsize = buf.itemsize ids = (os.getpgrp(), os.getsid(0)) - tty = open("/dev/tty", "r") - r = fcntl.ioctl(tty, termios.TIOCGPGRP, buf, 1) + # A fill value unlikely to be in `ids` + fill = -12345 + if nbytes is not None: + # Extend the buffer so that it is exactly `nbytes` bytes long + buf.extend([fill] * (nbytes // intsize)) + self.assertEqual(len(buf) * intsize, nbytes) # sanity check + else: + buf.append(fill) + with open("/dev/tty", "r") as tty: + r = fcntl.ioctl(tty, termios.TIOCGPGRP, buf, 1) rpgrp = buf[0] self.assertEquals(r, 0) self.assertIn(rpgrp, ids) + def test_ioctl_mutate(self): + self._check_ioctl_mutate_len() + + def test_ioctl_mutate_1024(self): + # Issue #9758: a mutable buffer of exactly 1024 bytes wouldn't be + # copied back after the system call. + self._check_ioctl_mutate_len(1024) + + def test_ioctl_mutate_2048(self): + # 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') @@ -13,6 +13,10 @@ Core and Builtins Library ------- +- Issue #9758: When fcntl.ioctl() was called with mutable_flag set to True, + and the passed buffer was exactly 1024 bytes long, the buffer wouldn't + be updated back after the system call. Original patch by Brian Brazil. + - Updates to the random module: * Document which parts of the module are guaranteed to stay the same diff --git a/Modules/fcntlmodule.c b/Modules/fcntlmodule.c index a7cdccb..bfc5985 100644 --- a/Modules/fcntlmodule.c +++ b/Modules/fcntlmodule.c @@ -157,7 +157,7 @@ fcntl_ioctl(PyObject *self, PyObject *args) else { ret = ioctl(fd, code, arg); } - if (mutate_arg && (len < IOCTL_BUFSZ)) { + if (mutate_arg && (len <= IOCTL_BUFSZ)) { memcpy(str, buf, len); } PyBuffer_Release(&pstr); /* No further access to str below this point */ |