pty Program
The goal in writing the pty program is to be able to type
pty prog arg1 arg2
instead of
prog arg1 arg2
When we use pty to execute another program, that program is executed in a session of its own, connected to a pseudo terminal.
这里写代码片
The loop function
Using the pty Program
If our shell is the Korn shell, we can execute the command
pty ksh
and get a brand-new invocation of the shell, running under a pseudo terminal.
utmp File
In the case of remote logins, with telnetd and rlogind, obviously an entry should be made in the utmp file for the user logged in on the pseudo terminal. There is little agreement, however, whether users running a shell on a pseudo terminal from a window system or from a program, such as script, should have entries made in the utmp file. Some systems record these; others don’t. If a system doesn’t record these entries in the utmp file, the who(1) program normally won’t show the corresponding pseudo terminals as being used.
Job Control Interaction
If we run a job-control shell under pty, it works normally. For example,
pty ksh
runs the Korn shell under pty. We can run programs under this new shell and use job control just as we do with our login shell. But if we run an interactive program other than a job-control shell under pty, as in
pty cat
everything is fine until we type the job-control suspend character. At that point, the job-control character is echoed as ˆZ and is ignored. Under earlier BSD-based systems, the cat process terminates, the pty process terminates, and we’re back to our original shell. To understand what’s going on here, we need to examine all the processes involved, their process groups, and sessions.
Historically, implementations have handled this condition differently. POSIX.1 says only that the SIGTSTP signal can’t be delivered to the process. Systems derived from 4.3BSD delivered SIGKILL instead, which the process can’t even catch. In 4.4BSD, this behavior was changed to conform to POSIX.1. Instead of sending SIGKILL, the 4.4BSD kernel silently discards the SIGTSTP signal if it has the default disposition and is to be delivered to a process in an orphaned process group. Most current implementations follow this behavior.
Running Coprocesses
In Figure 15.18, the coprocess couldn’t use the standard I/O functions, because standard input and standard output do not refer to a terminal, so the standard I/O functions treat them as fully buffered. If we run the coprocess under pty by replacing the line
if (execl("./add2", "add2", (char *)0) < 0)
with
if (execl("./pty", "pty", "-e", "add2", (char *)0) < 0)
the program now works, even if the coprocess uses standard I/O. Figure 19.15 shows the arrangement of processes when we run coprocess with a pseudo terminal as its input and output.