1 """Pseudo terminal utilities."""
9 from select
import select
24 __all__ = [
"openpty",
"fork",
"spawn"]
33 """openpty() -> (master_fd, slave_fd)
34 Open a pty master/slave pair, using os.openpty() if possible."""
38 except (AttributeError, OSError):
40 master_fd, slave_name = _open_terminal()
42 return master_fd, slave_fd
45 """master_open() -> (master_fd, slave_name)
46 Open a pty master and return the fd, and the filename of the slave end.
47 Deprecated, use openpty() instead."""
50 master_fd, slave_fd = os.openpty()
51 except (AttributeError, OSError):
54 slave_name = os.ttyname(slave_fd)
56 return master_fd, slave_name
58 return _open_terminal()
61 """Open pty master and return (master_fd, tty_name).
62 SGI and generic BSD version, for when openpty() fails."""
69 tty_name, master_fd = sgi._getpty(os.O_RDWR, 0666, 0)
72 return master_fd, tty_name
73 for x
in 'pqrstuvwxyzPQRST':
74 for y
in '0123456789abcdef':
75 pty_name =
'/dev/pty' + x + y
77 fd = os.open(pty_name, os.O_RDWR)
80 return (fd,
'/dev/tty' + x + y)
81 raise os.error,
'out of pty devices'
84 """slave_open(tty_name) -> slave_fd
85 Open the pty slave and acquire the controlling terminal, returning
86 opened filedescriptor.
87 Deprecated, use openpty() instead."""
89 return os.open(tty_name, os.O_RDWR)
92 """fork() -> (pid, master_fd)
93 Fork and make the child a session leader with a controlling terminal."""
96 pid, fd = os.forkpty()
97 except (AttributeError, OSError):
108 master_fd, slave_fd =
openpty()
116 os.dup2(slave_fd, STDIN_FILENO)
117 os.dup2(slave_fd, STDOUT_FILENO)
118 os.dup2(slave_fd, STDERR_FILENO)
119 if (slave_fd > STDERR_FILENO):
123 return pid, master_fd
125 def _writen(fd, data):
126 """Write all the data to a descriptor."""
128 n = os.write(fd, data)
132 """Default read function."""
133 return os.read(fd, 1024)
135 def _copy(master_fd, master_read=_read, stdin_read=_read):
138 pty master -> standard output (master_read)
139 standard input -> pty master (stdin_read)"""
141 rfds, wfds, xfds = select(
142 [master_fd, STDIN_FILENO], [], [])
143 if master_fd
in rfds:
144 data = master_read(master_fd)
145 os.write(STDOUT_FILENO, data)
146 if STDIN_FILENO
in rfds:
147 data = stdin_read(STDIN_FILENO)
148 _writen(master_fd, data)
150 def spawn(argv, master_read=_read, stdin_read=_read):
151 """Create a spawned process."""
152 if type(argv) == type(
''):
154 pid, master_fd =
fork()
156 apply(os.execlp, (argv[0],) + argv)
157 mode = tty.tcgetattr(STDIN_FILENO)
160 _copy(master_fd, master_read, stdin_read)
162 tty.tcsetattr(STDIN_FILENO, tty.TCSAFLUSH, mode)