bpo-29070: Integration tests for pty module with patch from bpo-26228 by diekmann · Pull Request #2932 · python/cpython (original) (raw)
@@ -1,13 +1,14 @@
"""Pseudo terminal utilities."""
# Bugs: No signal handling. Doesn't set slave termios and window size.
# Only tested on Linux.
# Only tested on Linux, FreeBSD, and OS X.
# See: W. Richard Stevens. 1992. Advanced Programming in the
# UNIX Environment. Chapter 19.
# Author: Steen Lumholt -- with additions by Guido.
from select import select
import os
import sys
import tty
__all__ = ["openpty","fork","spawn"]
@@ -133,11 +134,16 @@ def _copy(master_fd, master_read=_read, stdin_read=_read):
standard input -> pty master (stdin_read)"""
fds = [master_fd, STDIN_FILENO]
while True:
# The expected path to leave this infinite loop is that the
# child exits and its slave_fd is destroyed. In this case,
# master_fd will become ready in select() and reading from
# master_fd either raises an OSError (Input/output error) on
# Linux or returns EOF on BSD.
rfds, wfds, xfds = select(fds, [], [])
if master_fd in rfds:
data = master_read(master_fd)
if not data: # Reached EOF.
fds.remove(master_fd)
return
else:
os.write(STDOUT_FILENO, data)
if STDIN_FILENO in rfds:
@@ -153,7 +159,16 @@ def spawn(argv, master_read=_read, stdin_read=_read):
argv = (argv,)
pid, master_fd = fork()
if pid == CHILD:
os.execlp(argv[0], *argv)
try:
#XXX issue17824 still open
os.execlp(argv[0], *argv)
except:
# If we wanted to be really clever, we would use
# the same method as subprocess() to pass the error
# back to the parent. For now just dump stack trace.
sys.excepthook(*sys.exc_info())
finally:
os._exit(1)
try:
mode = tty.tcgetattr(STDIN_FILENO)
tty.setraw(STDIN_FILENO)
@@ -163,6 +178,10 @@ def spawn(argv, master_read=_read, stdin_read=_read):
try:
_copy(master_fd, master_read, stdin_read)
except OSError:
# Some OSes never return an EOF on pty, just raise
# an error instead.
pass
finally:
if restore:
tty.tcsetattr(STDIN_FILENO, tty.TCSAFLUSH, mode)