Skip site navigation (1)Skip section navigation (2)
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>