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"]

Expand Down Expand Up

@@ -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:

Expand All

@@ -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)

Expand All

@@ -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)

Expand Down