Skip to content

Commit 7d81452

Browse files
committed
Prevent the pty test from hanging by setting an alarm.
Currently, test_pty hangs on AIX & HPUX if run after test_openpty.
1 parent ef4b7ed commit 7d81452

File tree

1 file changed

+46
-30
lines changed

1 file changed

+46
-30
lines changed

Lib/test/test_pty.py

Lines changed: 46 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import pty, os, sys
1+
import pty, os, sys, signal
22
from test.test_support import verbose, TestFailed, TestSkipped
33

44
TEST_STRING_1 = "I wish to buy a fish license.\n"
@@ -14,36 +14,52 @@ def debug(msg):
1414
# Marginal testing of pty suite. Cannot do extensive 'do or fail' testing
1515
# because pty code is not too portable.
1616

17+
def test_basic_pty():
18+
try:
19+
debug("Calling master_open()")
20+
master_fd, slave_name = pty.master_open()
21+
debug("Got master_fd '%d', slave_name '%s'"%(master_fd, slave_name))
22+
debug("Calling slave_open(%s)"%`slave_name`)
23+
slave_fd = pty.slave_open(slave_name)
24+
debug("Got slave_fd '%d'"%slave_fd)
25+
except OSError:
26+
# " An optional feature could not be imported " ... ?
27+
raise TestSkipped, "Pseudo-terminals (seemingly) not functional."
28+
29+
if not os.isatty(slave_fd):
30+
raise TestFailed, "slave_fd is not a tty"
31+
32+
# IRIX apparently turns \n into \r\n. Allow that, but avoid allowing other
33+
# differences (like extra whitespace, trailing garbage, etc.)
34+
35+
debug("Writing to slave_fd")
36+
os.write(slave_fd, TEST_STRING_1)
37+
s1 = os.read(master_fd, 1024)
38+
sys.stdout.write(s1.replace("\r\n", "\n"))
39+
40+
debug("Writing chunked output")
41+
os.write(slave_fd, TEST_STRING_2[:5])
42+
os.write(slave_fd, TEST_STRING_2[5:])
43+
s2 = os.read(master_fd, 1024)
44+
sys.stdout.write(s2.replace("\r\n", "\n"))
45+
46+
os.close(slave_fd)
47+
os.close(master_fd)
48+
49+
def handle_sig(sig, frame):
50+
raise TestFailed, "isatty hung"
51+
52+
# isatty() and close() can hang on some platforms
53+
# set an alarm before running the test to make sure we don't hang forever
54+
old_alarm = signal.signal(signal.SIGALRM, handle_sig)
55+
signal.alarm(10)
56+
1757
try:
18-
debug("Calling master_open()")
19-
master_fd, slave_name = pty.master_open()
20-
debug("Got master_fd '%d', slave_name '%s'"%(master_fd, slave_name))
21-
debug("Calling slave_open(%s)"%`slave_name`)
22-
slave_fd = pty.slave_open(slave_name)
23-
debug("Got slave_fd '%d'"%slave_fd)
24-
except OSError:
25-
# " An optional feature could not be imported " ... ?
26-
raise TestSkipped, "Pseudo-terminals (seemingly) not functional."
27-
28-
if not os.isatty(slave_fd):
29-
raise TestFailed, "slave_fd is not a tty"
30-
31-
# IRIX apparently turns \n into \r\n. Allow that, but avoid allowing other
32-
# differences (like extra whitespace, trailing garbage, etc.)
33-
34-
debug("Writing to slave_fd")
35-
os.write(slave_fd, TEST_STRING_1)
36-
s1 = os.read(master_fd, 1024)
37-
sys.stdout.write(s1.replace("\r\n", "\n"))
38-
39-
debug("Writing chunked output")
40-
os.write(slave_fd, TEST_STRING_2[:5])
41-
os.write(slave_fd, TEST_STRING_2[5:])
42-
s2 = os.read(master_fd, 1024)
43-
sys.stdout.write(s2.replace("\r\n", "\n"))
44-
45-
os.close(slave_fd)
46-
os.close(master_fd)
58+
test_basic_pty()
59+
finally:
60+
# remove alarm, restore old alarm handler
61+
signal.alarm(0)
62+
signal.signal(signal.SIGALRM, old_alarm)
4763

4864
# basic pty passed.
4965

0 commit comments

Comments
 (0)