david@vaxwalle.UUCP (03/21/84)
In /sys/dev of 4.1BSD, there is a driver for the pseudo-device pty. The only description of it is in the source - no manual page, etc.: * A pseudo-teletype is a special device which is not unlike a pipe. * It is used to communicate between two processes. However, it allows * one to simulate a teletype, including mode setting, interrupt, and * multiple end of files (all not possible on a pipe). There are * really two drivers here. One is the device which looks like a TTY * and can be thought of as the slave device, and hence its routines * are prefixed with 'pts' (PTY Slave). The other driver can be * thought of as the controlling device, and its routines are prefixed * by 'ptc' (PTY Controller). To type on the simulated keyboard of the * PTY, one does a 'write' to the controlling device. To get the * simulated printout from the PTY, one does a 'read' on the controlling * device. Normally, the controlling device is called 'ptyx' and the * slave device is called 'ttyx' (to make programs like 'who' happy). Has anyone ever used it? What type of applications could it be used for? And (most importantly) does it work? Thanks in advance David Brown (415) 945-2199 Varian Instruments 2700 Mitchell Dr Walnut Creek CA 94598 {zehntel,fortune,amd70}!varian!david
rpw3@fortune.UUCP (03/22/84)
#R:vaxwalle:-14000:fortune:26900033:000:9520 fortune!rpw3 Mar 22 02:38:00 1984 "What is a pty?" [163 lines, but please, no flames, guys, it's history/tutorial time...] The pseudo-teletype ("pty") is not a Berkeley-ism, nor even a UNIX-ism. It's pretty widely industry standard on timesharing operating systems. (My first exposure to them was back in 1970, on DEC PDP-10's, but they were old even then. They pronounced the acronym "pity", to rhyme with "tty".) ((My apologies if I leave out earlier systems, maybe MULTICS, of which I have no direct experience.)) A pseudo-teletype is a specialized form of a "virtual device", that is, a "device" which is really manifested by a program ("Pay no attention to the [process] behind the curtain!"). As said in the excerpt you quoted, a pty normally has two ends, a "master" end and a "slave" end. Under UNIX, the "master" end is normally named "/dev/ptyNN" while the slave end is named "/dev/ttyNN". (On some systems the slaves are "/dev/ttypN".) The point is that since (if the implementation of "pty.c" is correct, and it should be) there is no way that a process can (easily) tell that the "slave" end is not a real, live, physical piece of hardware, and a process controlling the "master" end can EXACTLY emulate a physical human sitting at a terminal typing and reading. In fact, this emulation is generally so exact that the slave ends are simply listed in /etc/ttys with all the other terminals, and get a "getty/login/shell" from "init" just like the rest, with a line in /etc/ttys like "1mtty03" or "1mttyp3" (login port, 9600 baud, /dev/tty03 or /dev/ttyp3). [Here on, assume slaves named ttyNN.] So (messy details of flag handling and synchronization omitted), some process "X" opens the master side of a pty, say /dev/pty43. Since the beginning of time, some copy of the program "getty" was trying to open /dev/tty43 (since "init" forks a copy of "getty" for each line in /etc/ttys), and that open now completes, since "somebody" (process X) just "dialed in". "Getty" writes a banner on tty43, which X reads by reading pty43. X then "types" its login name by writing on pty43 which "getty" reads on tty43, and so on through the login process, running the shell, and then the user programs, etc. "Terminal input" is "typed" by X by writing on pty43, "display output" is "read" by X by reading pty43, and all the user programs are dumb and happy thinking there's a human on the other end of tty43. So why would one want to do this? Basically, in historical order of evolution, four reasons: 1. Batch (Background) Processing of Commands. On systems (not UNIX) which are NOT process oriented, and which therefore did NOT have the concept of a "fork", there was no easy way to have background (or "batch") jobs. The pty was a clever, elegant solution that left the basic "timesharing" nature of the system unchanged, while providing essentially what we now call shell scripts. Example: On a PDP-10, you said ".submit foo.ctl" and "foo.ctl" was fed to an operator program named BATCON (run from one of the operator's consoles) that opened a pty and "typed" your monitor commands in (including logging you in and out), and saved up the output in a file called "foo.log" for your later amusement and amazement (since Murphy's Law was true even back then ;-}). Even with all that convenience (;-}), systems administrators got tired of having a terminal in the machine room for EACH copy of EACH operator service program (no "fork", remember, so one tty for each line printer spooler and for each batch stream and for each card reader...), so... 2. Job Control - Multiple jobs active from one terminal. A new operator service program (named OPSER on PDP-10's, OPRCON on TOPS-20) was invented which incestuously used ptys to control all of the other operator service jobs! You could type a line into a given job by prefixing the line with the subjob number or mnemonic (set up by the operator), such as, to change forms on printer 3 you said "L3-forms payroll2" (or something). Since it was perfectly general, the operator could also do small utility tasks (like accounting, etc.) through the same terminal (except for the hassle of those other jobs sometimes yammering at you -- but there were commands to handle that). For convenience, if you typed a line that didn't start with "XX-" it assumed you meant the last one you explicitly talked to, so an extended conversation was fairly confortable. Eventually, ordinary users started using OPSER when they needed to multiplex several activities, or whenever they needed its script and logging features. (Like the "script" program.) In modern terminology, what you had there was a line-oriented "window" manager, similar to the "Maryland Windows" package, but for Teletype Model 33's. Or, somewhat like Berkeley 4.1bsd job-control under the C-shell ("csh"), but with processes NOT suspended just because you weren't typing at them (they could still type out progress reports, if you didn't disable them). [Personal aside to any wizards who have made it this far: having used both OPSER and 4.1 csh with job-control, I'll take pty-based "job control" hands down, PROVIDED it's always there and is the default. I understand the problem in S5 is you have to decide ahead of time whether you're going to need it (?).] Home stretch... 3. Network Virtual Terminals. With the advent of networks of many strange and wonderful kinds, seldom being integrated into the operating system completely on first release, the ancient pty was again drawn into service [is this getting a little thick? ;-}] as a quick, simple, effective way of implementing a basic network service -- remote logins. The operating systems (including UNIX) rarely treated network connections as full citizens, and besides, there were many versions -- which one(s) to support? The answer (even today, often) is to have a program running on the target system (the one you're trying to login on) called a "network virtual terminal protocol server" (typically named "vtpsrv") which sits around waiting for people out in the network to connect to it (via whatever net hardware and software one might have). When someone does so, the "vtpsrv" handles all the network stuff, eventually passing characters typed by a user (or a program) out in the network to the master side of a pty as if the user were local to the target machine, and "displaying" output (read from the pty) by sending it back out into the network. Because of the local (target) "vtpsrv", the target operating system doesn't have to worry about "network terminals" -- it doesn't have any! (That's the "virtual" part.) Smarter versions of "vtpsrv" (or of the corresponding program that the real user runs out there in the network, usually called "vtp") can sometimes also handle some transformations from one terminal type to another (a different meaning of "virtual terminal"). Naturally, there should be some standards around for how the various pieces talk to each other. There are, but of course they are network dependent. Within the ARPAnet (or other nets using IP/TCP protocols), the protocol between a "vtp" and a "vtpsrv" is called "Telnet" (NOT to be confused with the company Telenet!). Within the CCITT world (the "X.nn" and "V.nn" international standards), the protocol between the user and "vtp" (yes, users have to obey protocols, too!) is called X.28, the protocol between "vtp" and "vtpsrv" is called X.29, and the overall scheme is called X.3 (and sits on top of X.25 -- aren't you glad you asked?). Telenet (the company) uses protocols VERY close to the CCITT standards. Of course, as efficiency becomes an issue, it is tempting to put all of "vtpsrv" in the kernel of the operating system, and this is often cited as a mark of a "integrated" network offering. Nevertheless, the flexibility of the pty approach often wins over raw efficiency. (Various players do it various ways.) Finally (and this IS short), 4. Virtual Devices. Although the pty is a specialized virtual device, having (usually) just the set of "ioctl" calls needed to emulate a tty, sometimes people will use them to emulate hardware that hasn't been built yet (or for which the driver hasn't been written yet), in order to decouple the writing/building of the "system" side (driver/hardware) from the "user" side (applications programs). With a little tinkering (mostly just more general handling of ioctl's), ptys can be made to emulate any UNIX "character device". This hack has even been used occasionaly to execute programs that would only run on specific hardware or kernels, when equivalent (but unfortunately, different) systems were available. SUMMARY These days, #3 (networks) is the most common use of ptys, but the increasing emphasis on "windows" is reviving #2 (multiplexing). [May this lengthy, chatty, uneven reminiscence be of use to someone.] Rob Warnock UUCP: {sri-unix,amd70,hpda,harpo,ihnp4,allegra}!fortune!rpw3 DDD: (415)595-8444 USPS: Fortune Systems Corp, 101 Twin Dolphin Drive, Redwood City, CA 94065 p.s. I have completely ignored the issue of the so-called "mpx" device, found (partially) in UNIX Edition 7 (v.7) (and other UNIXs, as well as several non-UNIX systems), which could be used like a pty with one master side and many slave sides. Requicat In Pacem. Who knows, it may become "popular" again some day, eh?
chris@umcp-cs.UUCP (03/22/84)
The supplied pty driver works. It has a bug: as distributed it only runs OTTYDISC (i.e. "stty new" works but has no effect). There is a very simple fix (find the place(s?) where it calls the old tty routines directly and change the code to call the appropriate routine based on the line switch table and tp->t_ldisc). If you make nodes for these ptys and put them in your init table, you can log in by opening the control name. This is how the BBN "telnet" program for 4.1 works. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci UUCP: {seismo,allegra,brl-bmd}!umcp-cs!chris CSNet: chris@umcp-cs ARPA: chris.umcp-cs@CSNet-Relay
sdyer@bbncca.ARPA (Steve Dyer) (03/23/84)
The pty driver is a hack to allow a user-mode process to present a TTY
interface to another program. It was used by the old ARPAnet NCP Telnet
protocol, and most recently by the 4.1BSD/BBN TCP/IP Telnet protocols.
The model is as follows:
___________ _________________
| Network | <--> | Telnet Server | <---> /dev/ptcN :c:l:i:s:t:s /dev/ptyN <--> SH
----------- -----------------
Essentially, the telnet server reads characters from the network, and
writes them to the PTY controller (here, /dev/ptcN.) This action is
analogous to a DH or DZ interrupt routine, in that it puts characters on
the terminal's input queue (here, the PTY "slave", /dev/ptyN). The user
program (here, SH) will then receive them, by reading from its standard
input. In the same way, when the user program writes to its standard
output (also open on /dev/ptyN), the telnet server will be able to read
those characters from the corresponding pty controller device, and then
write them onto the network connection. This is roughly analogous to the
"output interrupt" processing of a DH or DZ. The key is that this "server"
can do anything it likes to the characters it reads or writes on the
controller. Here, it is essentially a pass-thru (excepting the minor Telnet
negotiations and protocol) serving merely to hook up a network connection
to the UNIX model of a TTY. The PTY "slave" looks exactly like any TTY to
the process which has it open, and indeed, one would usually enter such
pseudo-TTY's into the /etc/ttys file. Virtual carrier is set when the
corresponding controller device is opened.
You could, instead, use the PTY's for anything you like, not necessarily
a network. I once wrote a special filter for someone who had a DG "Dasher"
terminal which went wild when it was sent ^H characters. We set her shell
to read from a pseudo-TTY, and the process reading and writing on the
controller mapped the characters appropriately.
--
/Steve Dyer
{decvax,linus,ima}!bbncca!sdyer
sdyer@bbncca.ARPA