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