xref: /third_party/python/Lib/test/test_ioctl.py (revision 7db96d56)
17db96d56Sopenharmony_ciimport array
27db96d56Sopenharmony_ciimport unittest
37db96d56Sopenharmony_cifrom test.support import get_attribute
47db96d56Sopenharmony_cifrom test.support.import_helper import import_module
57db96d56Sopenharmony_ciimport os, struct
67db96d56Sopenharmony_cifcntl = import_module('fcntl')
77db96d56Sopenharmony_citermios = import_module('termios')
87db96d56Sopenharmony_ciget_attribute(termios, 'TIOCGPGRP') #Can't run tests without this feature
97db96d56Sopenharmony_ci
107db96d56Sopenharmony_citry:
117db96d56Sopenharmony_ci    tty = open("/dev/tty", "rb")
127db96d56Sopenharmony_ciexcept OSError:
137db96d56Sopenharmony_ci    raise unittest.SkipTest("Unable to open /dev/tty")
147db96d56Sopenharmony_cielse:
157db96d56Sopenharmony_ci    with tty:
167db96d56Sopenharmony_ci        # Skip if another process is in foreground
177db96d56Sopenharmony_ci        r = fcntl.ioctl(tty, termios.TIOCGPGRP, "    ")
187db96d56Sopenharmony_ci    rpgrp = struct.unpack("i", r)[0]
197db96d56Sopenharmony_ci    if rpgrp not in (os.getpgrp(), os.getsid(0)):
207db96d56Sopenharmony_ci        raise unittest.SkipTest("Neither the process group nor the session "
217db96d56Sopenharmony_ci                                "are attached to /dev/tty")
227db96d56Sopenharmony_ci    del tty, r, rpgrp
237db96d56Sopenharmony_ci
247db96d56Sopenharmony_citry:
257db96d56Sopenharmony_ci    import pty
267db96d56Sopenharmony_ciexcept ImportError:
277db96d56Sopenharmony_ci    pty = None
287db96d56Sopenharmony_ci
297db96d56Sopenharmony_ciclass IoctlTests(unittest.TestCase):
307db96d56Sopenharmony_ci    def test_ioctl(self):
317db96d56Sopenharmony_ci        # If this process has been put into the background, TIOCGPGRP returns
327db96d56Sopenharmony_ci        # the session ID instead of the process group id.
337db96d56Sopenharmony_ci        ids = (os.getpgrp(), os.getsid(0))
347db96d56Sopenharmony_ci        with open("/dev/tty", "rb") as tty:
357db96d56Sopenharmony_ci            r = fcntl.ioctl(tty, termios.TIOCGPGRP, "    ")
367db96d56Sopenharmony_ci            rpgrp = struct.unpack("i", r)[0]
377db96d56Sopenharmony_ci            self.assertIn(rpgrp, ids)
387db96d56Sopenharmony_ci
397db96d56Sopenharmony_ci    def _check_ioctl_mutate_len(self, nbytes=None):
407db96d56Sopenharmony_ci        buf = array.array('i')
417db96d56Sopenharmony_ci        intsize = buf.itemsize
427db96d56Sopenharmony_ci        ids = (os.getpgrp(), os.getsid(0))
437db96d56Sopenharmony_ci        # A fill value unlikely to be in `ids`
447db96d56Sopenharmony_ci        fill = -12345
457db96d56Sopenharmony_ci        if nbytes is not None:
467db96d56Sopenharmony_ci            # Extend the buffer so that it is exactly `nbytes` bytes long
477db96d56Sopenharmony_ci            buf.extend([fill] * (nbytes // intsize))
487db96d56Sopenharmony_ci            self.assertEqual(len(buf) * intsize, nbytes)   # sanity check
497db96d56Sopenharmony_ci        else:
507db96d56Sopenharmony_ci            buf.append(fill)
517db96d56Sopenharmony_ci        with open("/dev/tty", "rb") as tty:
527db96d56Sopenharmony_ci            r = fcntl.ioctl(tty, termios.TIOCGPGRP, buf, True)
537db96d56Sopenharmony_ci        rpgrp = buf[0]
547db96d56Sopenharmony_ci        self.assertEqual(r, 0)
557db96d56Sopenharmony_ci        self.assertIn(rpgrp, ids)
567db96d56Sopenharmony_ci
577db96d56Sopenharmony_ci    def test_ioctl_mutate(self):
587db96d56Sopenharmony_ci        self._check_ioctl_mutate_len()
597db96d56Sopenharmony_ci
607db96d56Sopenharmony_ci    def test_ioctl_mutate_1024(self):
617db96d56Sopenharmony_ci        # Issue #9758: a mutable buffer of exactly 1024 bytes wouldn't be
627db96d56Sopenharmony_ci        # copied back after the system call.
637db96d56Sopenharmony_ci        self._check_ioctl_mutate_len(1024)
647db96d56Sopenharmony_ci
657db96d56Sopenharmony_ci    def test_ioctl_mutate_2048(self):
667db96d56Sopenharmony_ci        # Test with a larger buffer, just for the record.
677db96d56Sopenharmony_ci        self._check_ioctl_mutate_len(2048)
687db96d56Sopenharmony_ci
697db96d56Sopenharmony_ci    def test_ioctl_signed_unsigned_code_param(self):
707db96d56Sopenharmony_ci        if not pty:
717db96d56Sopenharmony_ci            raise unittest.SkipTest('pty module required')
727db96d56Sopenharmony_ci        mfd, sfd = pty.openpty()
737db96d56Sopenharmony_ci        try:
747db96d56Sopenharmony_ci            if termios.TIOCSWINSZ < 0:
757db96d56Sopenharmony_ci                set_winsz_opcode_maybe_neg = termios.TIOCSWINSZ
767db96d56Sopenharmony_ci                set_winsz_opcode_pos = termios.TIOCSWINSZ & 0xffffffff
777db96d56Sopenharmony_ci            else:
787db96d56Sopenharmony_ci                set_winsz_opcode_pos = termios.TIOCSWINSZ
797db96d56Sopenharmony_ci                set_winsz_opcode_maybe_neg, = struct.unpack("i",
807db96d56Sopenharmony_ci                        struct.pack("I", termios.TIOCSWINSZ))
817db96d56Sopenharmony_ci
827db96d56Sopenharmony_ci            our_winsz = struct.pack("HHHH",80,25,0,0)
837db96d56Sopenharmony_ci            # test both with a positive and potentially negative ioctl code
847db96d56Sopenharmony_ci            new_winsz = fcntl.ioctl(mfd, set_winsz_opcode_pos, our_winsz)
857db96d56Sopenharmony_ci            new_winsz = fcntl.ioctl(mfd, set_winsz_opcode_maybe_neg, our_winsz)
867db96d56Sopenharmony_ci        finally:
877db96d56Sopenharmony_ci            os.close(mfd)
887db96d56Sopenharmony_ci            os.close(sfd)
897db96d56Sopenharmony_ci
907db96d56Sopenharmony_ci
917db96d56Sopenharmony_ciif __name__ == "__main__":
927db96d56Sopenharmony_ci    unittest.main()
93