Date: Fri, 12 Apr 1996 04:09:40 -0400 From: hugh@mimosa.com ("D. Hugh Redelmeier") To: j@uriah.heep.sax.de Cc: chuck@bus.net, freebsd-hackers@freebsd.org, jovehacks@cs.toronto.edu Subject: short writes to pty Message-ID: <199604120809.EAA02022@mimosa.com>
next in thread | raw e-mail | index | archive | help
[Note: I'm not on freebsd-hackers@freebsd.org. Please send any replies to me, not just the list.] [Note to jovehackers: this is an outgrowth of a discussion about a pty bug in FreeBSD that JOVE exercises.] | From: J Wunsch <j@uriah.heep.sax.de> | To: FreeBSD hackers <freebsd-hackers@freebsd.org> | Cc: Chuck O'Donnell <chuck@bus.net> | Subject: Re: fbsd pty bug | | As Chuck O'Donnell wrote: [talking about JOVE's write to the master-side of a pty, in the implementation of i-shell] | > so jove is being told that the write was successful, but 0 | > bytes were written! Jove only checks whether the write was | > successful, and doesn't pay attention to the length reported by | > write. Jove will not retry this write, although that would be | > reasonable. | | I would consider this an error: | | NAME | write, writev - write output | ... | When using non-blocking I/O on objects such as sockets that are subject | to flow control, write() and writev() may write fewer bytes than request- | ed; the return value must be noted, and the remainder of the operation | should be retried when possible. | | Now it's arguable whether a pty counts as ``subject to flow control'', | but a short write is IMHO not an exception. pty facilities haven't been standardized in UNIX -- POSIX doesn't cover them (at least last time I checked). They were not part of 6th or 7th edition UNIX, so the System V release 4 and BSD flavours are different (not to mention the other variants). JOVE tries to be unadventurous to increase the chance it will work with all systems. It is a UNIX convention for cooked ttys to return no more than one line per read (at least as far back as I can remember, which is to the 5th Edition). If an eof (^D) is typed, even less will be returned. At least in some pty systems, the record structure of writes to the master side comes through on the slave side. In other words, the maximum that a slave can gulp in a single read is up to the end of the chunk that was written by the master. This even applies for writes of length 0, allowing the master to simulate typing ^D on an empty line without closing the pty. I have no idea if FreeBSD preserves the record structure in this way. Can you tell me? JOVE's pty usage is line oriented (hint: don't run vi in a JOVE i-shell window!), so it is natural for it to simulate cooked mode. Since JOVE does the line editing (erase and kill processing, generating tty signals like INTR and QUIT, etc.), it is reasonable for it to impose the line structure on its writes to the master-side of the pty. I don't think that a partial write would have the right semantics in this case. Much of this reasoning has been based on experimental results: these corners are poorly documented in most UNIX systems. If you know better, please tell me. | > Notice that the amount returned by the read was the length | > requested by bash. I think that a pty should return at most a | > line at a time, even if the read requested more. | | What does make you think this? Tty's are not inherently line-bound, | so if there were more than a line available (regardles of your actual | problem with the multiple copies here), why should a read() only | return one line? This is a property of cooked mode tty input (aka canonical mode) under UNIX. I have no idea if bash is using cooked mode. I don't even know what 4.4BSD's non-canonical-mode facilities are. System V uses VMIN and VTIME to affect how many chars can be read at a time in non-canonical mode. 7th Edition only yielded one character per read in raw mode. Here is an extract from termio(7) of Solaris 2.3 (System V release 4 variant). It is describing canonical mode: This means that a program attempting to read will be suspended until an entire line has been typed. Also, no matter how many characters are requested in the read call, at most one line will be returned. It is not necessary, however, to read a whole line at once; any number of charac- ters may be requested in a read, even one, without losing information. Here is an extract from tty(4) of SunOS 3.5 (4.[123]BSD variant): In cooked mode, terminal input is processed in units of lines. A program attempting to read will normally be suspended until an entire line has been received (but see the description of SIGTTIN in Job access control and of FIONREAD in Summary, both below.) No matter how many charac- ters are requested in the read call, at most one line will be returned. It is not, however, necessary to read a whole line at once; any number of characters may be requested in a read, even one, without losing information. Hugh Redelmeier hugh@mimosa.com voice: +1 416 482-8253
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199604120809.EAA02022>