annotate Lib/pty.py @ 4566:6403c94de50d legacy-trunk

Added safeguard against failure in __del__.
author Guido van Rossum <guido@python.org>
date Wed, 27 Nov 1996 19:39:58 +0000
parents 8c9cc054c5ed
children 69d89f7f530c
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1875
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1 # pty.py -- Pseudo terminal utilities.
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
2
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
3 # Bugs: No signal handling. Doesn't set slave termios and window size.
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
4 # Only tested on Linux.
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
5 # See: W. Richard Stevens. 1992. Advanced Programming in the
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
6 # UNIX Environment. Chapter 19.
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
7 # Author: Steen Lumholt -- with additions by Guido.
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
8
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
9 from select import select
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
10 import os, sys, FCNTL
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
11 import tty
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
12
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
13 STDIN_FILENO = 0
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
14 STDOUT_FILENO = 1
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
15 STDERR_FILENO = 2
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
16
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
17 CHILD = 0
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
18
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
19 # Open pty master. Returns (master_fd, tty_name). SGI and Linux/BSD version.
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
20 def master_open():
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
21 try:
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
22 import sgi
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
23 except ImportError:
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
24 pass
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
25 else:
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
26 try:
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
27 tty_name, master_fd = sgi._getpty(FCNTL.O_RDWR, 0666, 0)
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
28 except IOError, msg:
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
29 raise os.error, msg
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
30 return master_fd, tty_name
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
31 for x in 'pqrstuvwxyzPQRST':
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
32 for y in '0123456789abcdef':
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
33 pty_name = '/dev/pty' + x + y
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
34 try:
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
35 fd = os.open(pty_name, FCNTL.O_RDWR)
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
36 except os.error:
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
37 continue
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
38 return (fd, '/dev/tty' + x + y)
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
39 raise os.error, 'out of pty devices'
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
40
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
41 # Open the pty slave. Acquire the controlling terminal.
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
42 # Returns file descriptor. Linux version. (Should be universal? --Guido)
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
43 def slave_open(tty_name):
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
44 return os.open(tty_name, FCNTL.O_RDWR)
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
45
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
46 # Fork and make the child a session leader with a controlling terminal.
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
47 # Returns (pid, master_fd)
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
48 def fork():
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
49 master_fd, tty_name = master_open()
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
50 pid = os.fork()
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
51 if pid == CHILD:
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
52 # Establish a new session.
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
53 os.setsid()
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
54
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
55 # Acquire controlling terminal.
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
56 slave_fd = slave_open(tty_name)
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
57 os.close(master_fd)
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
58
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
59 # Slave becomes stdin/stdout/stderr of child.
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
60 os.dup2(slave_fd, STDIN_FILENO)
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
61 os.dup2(slave_fd, STDOUT_FILENO)
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
62 os.dup2(slave_fd, STDERR_FILENO)
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
63 if (slave_fd > STDERR_FILENO):
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
64 os.close (slave_fd)
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
65
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
66 # Parent and child process.
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
67 return pid, master_fd
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
68
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
69 # Write all the data to a descriptor.
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
70 def writen(fd, data):
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
71 while data != '':
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
72 n = os.write(fd, data)
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
73 data = data[n:]
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
74
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
75 # Default read function.
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
76 def read(fd):
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
77 return os.read(fd, 1024)
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
78
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
79 # Parent copy loop.
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
80 # Copies
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
81 # pty master -> standard output (master_read)
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
82 # standard input -> pty master (stdin_read)
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
83 def copy(master_fd, master_read=read, stdin_read=read):
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
84 while 1:
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
85 rfds, wfds, xfds = select(
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
86 [master_fd, STDIN_FILENO], [], [])
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
87 if master_fd in rfds:
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
88 data = master_read(master_fd)
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
89 os.write(STDOUT_FILENO, data)
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
90 if STDIN_FILENO in rfds:
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
91 data = stdin_read(STDIN_FILENO)
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
92 writen(master_fd, data)
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
93
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
94 # Create a spawned process.
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
95 def spawn(argv, master_read=read, stdin_read=read):
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
96 if type(argv) == type(''):
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
97 argv = (argv,)
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
98 pid, master_fd = fork()
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
99 if pid == CHILD:
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
100 apply(os.execlp, (argv[0],) + argv)
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
101 mode = tty.tcgetattr(STDIN_FILENO)
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
102 tty.setraw(STDIN_FILENO)
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
103 try:
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
104 copy(master_fd, master_read, stdin_read)
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
105 except:
8c9cc054c5ed New tty/pty modules by Steen; new urlparser.
Guido van Rossum <guido@python.org>
parents:
diff changeset
106 tty.tcsetattr(STDIN_FILENO, tty.TCSAFLUSH, mode)