0001 import pty, os, sys, signal 0002 from test.test_support import verbose, TestFailed, TestSkipped 0003 0004 TEST_STRING_1 = "I wish to buy a fish license.\n" 0005 TEST_STRING_2 = "For my pet fish, Eric.\n" 0006 0007 if verbose: 0008 def debug(msg): 0009 print msg 0010 else: 0011 def debug(msg): 0012 pass 0013 0014 # Marginal testing of pty suite. Cannot do extensive 'do or fail' testing 0015 # because pty code is not too portable. 0016 0017 def test_basic_pty(): 0018 try: 0019 debug("Calling master_open()") 0020 master_fd, slave_name = pty.master_open() 0021 debug("Got master_fd '%d', slave_name '%s'"%(master_fd, slave_name)) 0022 debug("Calling slave_open(%r)"%(slave_name,)) 0023 slave_fd = pty.slave_open(slave_name) 0024 debug("Got slave_fd '%d'"%slave_fd) 0025 except OSError: 0026 # " An optional feature could not be imported " ... ? 0027 raise TestSkipped, "Pseudo-terminals (seemingly) not functional." 0028 0029 if not os.isatty(slave_fd): 0030 raise TestFailed, "slave_fd is not a tty" 0031 0032 # IRIX apparently turns \n into \r\n. Allow that, but avoid allowing other 0033 # differences (like extra whitespace, trailing garbage, etc.) 0034 0035 debug("Writing to slave_fd") 0036 os.write(slave_fd, TEST_STRING_1) 0037 s1 = os.read(master_fd, 1024) 0038 sys.stdout.write(s1.replace("\r\n", "\n")) 0039 0040 debug("Writing chunked output") 0041 os.write(slave_fd, TEST_STRING_2[:5]) 0042 os.write(slave_fd, TEST_STRING_2[5:]) 0043 s2 = os.read(master_fd, 1024) 0044 sys.stdout.write(s2.replace("\r\n", "\n")) 0045 0046 os.close(slave_fd) 0047 os.close(master_fd) 0048 0049 def handle_sig(sig, frame): 0050 raise TestFailed, "isatty hung" 0051 0052 # isatty() and close() can hang on some platforms 0053 # set an alarm before running the test to make sure we don't hang forever 0054 old_alarm = signal.signal(signal.SIGALRM, handle_sig) 0055 signal.alarm(10) 0056 0057 try: 0058 test_basic_pty() 0059 finally: 0060 # remove alarm, restore old alarm handler 0061 signal.alarm(0) 0062 signal.signal(signal.SIGALRM, old_alarm) 0063 0064 # basic pty passed. 0065 0066 debug("calling pty.fork()") 0067 pid, master_fd = pty.fork() 0068 if pid == pty.CHILD: 0069 # stdout should be connected to a tty. 0070 if not os.isatty(1): 0071 debug("Child's fd 1 is not a tty?!") 0072 os._exit(3) 0073 0074 # After pty.fork(), the child should already be a session leader. 0075 # (on those systems that have that concept.) 0076 debug("In child, calling os.setsid()") 0077 try: 0078 os.setsid() 0079 except OSError: 0080 # Good, we already were session leader 0081 debug("Good: OSError was raised.") 0082 pass 0083 except AttributeError: 0084 # Have pty, but not setsid() ? 0085 debug("No setsid() available ?") 0086 pass 0087 except: 0088 # We don't want this error to propagate, escaping the call to 0089 # os._exit() and causing very peculiar behavior in the calling 0090 # regrtest.py ! 0091 # Note: could add traceback printing here. 0092 debug("An unexpected error was raised.") 0093 os._exit(1) 0094 else: 0095 debug("os.setsid() succeeded! (bad!)") 0096 os._exit(2) 0097 os._exit(4) 0098 else: 0099 debug("Waiting for child (%d) to finish."%pid) 0100 (pid, status) = os.waitpid(pid, 0) 0101 res = status >> 8 0102 debug("Child (%d) exited with status %d (%d)."%(pid, res, status)) 0103 if res == 1: 0104 raise TestFailed, "Child raised an unexpected exception in os.setsid()" 0105 elif res == 2: 0106 raise TestFailed, "pty.fork() failed to make child a session leader." 0107 elif res == 3: 0108 raise TestFailed, "Child spawned by pty.fork() did not have a tty as stdout" 0109 elif res != 4: 0110 raise TestFailed, "pty.fork() failed for unknown reasons." 0111 0112 os.close(master_fd) 0113 0114 # pty.fork() passed. 0115
Generated by PyXR 0.9.4