moss@cs.umass.edu (Eliot Moss) (01/23/91)
Folks -- Having had problems getting Dan Bernstein's pty program to run on my system, as well as managing to completely hang GNU Emacs (both of which are fine programs, by the way!), I have trcked down the following behaviors in Ultrix relate to ptys and solicit comments on whether they are appropriate (i.e., should I file an SPR, etc.). These all occur on VAX/Ultrix 3.1, RISC/Ultrix 3.1, and RISC Ultrix 4.1, except as noted. 1) [FIONREAD] An FIONREAD ioctl on a pty always returns 0 even when there is data available for reading. Granted, FIONREAD is described primarily for tty devices, but it would seem reasonable to have it for ptys, too. Also, there seems to be no way to flush a pty read or write queue from the pty side; you need an open tty descriptor to do that. That seems odd, too. A select call does indicate presence/absence of available pty input correctly. I have not tested SIGIO, but expect it works all right. 2) [open] More seriously, suppose a pty/tty pair is in use, the only process with the tty open is stopped (e.g., via SIGSTOP), there is data in the pty read queue (tty write queue) which the pty side has not yet picked up, and a second process attempts to open the tty. This hangs the second process. A SIGCONT to the stopped process is not adequate to break the blocking. O_NDELAY on the second process open has no effect. A SIGALRM to the opening process is also blocked. All this clears up as soon as the pty side reads the data out of the pty. Apparently there is some kind of kernel timeout, on the order of minutes, that will sometimes get you out of this. VAX/Ultrix does not exhibit this open problem, only RISC/Ultrix (3.1 and 4.1). 3) [close] Similar to 2, suppose a pty/tty pair is in use, there is data written to the tty not yet read by the pty, and a process attempts to close the last open descriptor for the tty. The close hangs until the data is read (or the kernel's long internal timeout occurs). A SIGALRM will not help this along either. If all descriptors for the pty end are closed, then the tty end will close without delay. It could be argued that the FIONREAD and close behaviors are possibly reasonable; I think the open behavior is definitely a bug. The close behavior is a problem, e.g., for GNU Emacs, as follows. Emacs uses subprocesses to run subtasks, and can collect and process the information that comes back on the pty. To start a subprocess, if obtains a pty/tty pair that are not in use, opens both, then vforks. The child side closes the pty and execs the appropriate task; the parent side closes the tty and at some appropriate later time may try to read data from the pty. The problem is that if the child writes data and exits very fast, before the parent can close its tty descriptor, the *parent* is the process that hangs, and it cannot be interrupted out of it. There may be some way to program Emacs around this (such as not opening the tty side in the parent at all and requiring the child to do that, or using a pipe or some other kludge to delay the child's exec until after the parent closes the tty), but it's not pretty and apparently this behavior either does not occur in other systems or the timing is different so the particular situation is luckily avoided. Your reactions? -- J. Eliot B. Moss, Assistant Professor Department of Computer and Information Science Lederle Graduate Research Center University of Massachusetts Amherst, MA 01003 (413) 545-4206, 545-1249 (fax); Moss@cs.umass.edu
moss@cs.umass.edu (Eliot Moss) (01/24/91)
An additional thing I would like to add to my previous posting: Under RISC/Ultrix 3.1 and 4.1, *any* open of a tty when there is data pending for the pty hangs until the data is read. Processed do not have to be stopped or anything for the tty open hang to occur. -- J. Eliot B. Moss, Assistant Professor Department of Computer and Information Science Lederle Graduate Research Center University of Massachusetts Amherst, MA 01003 (413) 545-4206, 545-1249 (fax); Moss@cs.umass.edu