[comp.sys.sun] cat /dev/ttya > /dev/null &

dpointer@uicsrd.csrd.uiuc.edu (David B. Pointer) (07/21/89)

I'm running SunOS 4.0.3 on a 3/50. I send a file of HPGL commands to an HP
plotter by " cat filename > /dev/ttya ".  /dev/ttya and the plotter are
configured to use XON/XOFF protocol.  Until recently, the plotter buffer
always overflowed and it appeared that XON/XOFF wasn't recognized by the
3/50.

Now here's the good part.  Our system administrator tells me to have " cat
/dev/tty > /dev/null " running in the background when I want to " cat
filename > /dev/ttya ".  I was a bit skeptical, but I tried the fix, and
it worked.

No one here understands why this fix works. Does anyone on the net have
any ideas why this works?  This really bothers me.  I mean, UNIX at times
seems like black magic, but this looks like REAL voodoo.  Thanks for any
ideas.

*dave

----------------------------------------------------------------------
  David Pointer                    Center for Supercomputing R&D
  dpointer@uicsrd.csrd.uiuc.edu    305 Talbot Lab  104 S. Wright St.
  (217) 244-6392                   Urbana, IL  61801
----------------------------------------------------------------------

perl%step@uunet.uu.net (Robert Perlberg) (08/11/89)

In article <343@brazos.Rice.edu>, dpointer@uicsrd.csrd.uiuc.edu (David B. Pointer) writes:
> No one here understands why this fix works. Does anyone on the net have
> any ideas why this works?  This really bothers me.  I mean, UNIX at times
> seems like black magic, but this looks like REAL voodoo.  Thanks for any
> ideas.

"A sufficiently advanced technology is indistinguishable from magic.",
or words to that effect.

This is a very old problem found on many UNIX systems.  The crux of the
problem is that when you close a tty port, the tty driver drops DTR and
abandons processing on the port.  Since you almost always write data to
the tty faster than the serial port can pump it out at whatever baud rate,
a considerable queue builds up in the tty driver.  By the time your
application is finished writing and closes the port, there is still quite
a bit of data in the queue which has not yet gone out.  Whatever data is
still in the queue when the port is closed is thrown away.  This results
in the "missing pages" problem  reported by many lpr users.  On some
systems, the driver will continue to send characters, but will stop
honoring XON/XOFF.  The solution is to make sure that the tty port is not
closed until after all of the data has been transmitted.  One way of doing
this, as suggested by your guru, is to have another process hold the port
open all the time.  I remember there being a program on the ONYX called
/etc/openup which did nothing but open the specified device and pause().
The solution I use in my lpr filters is to wait for the tty queue to empty
before exiting.  I use the following code for that purpose:

#include <stdio.h>
#include <sgtty.h>

outputwait(fd)
int fd;
{
	int outchars;

	while(ioctl(fd, TIOCOUTQ, &outchars) == 0 && outchars > 0)
	{
		sleep(1);
	}
}

Robert Perlberg
Dean Witter Reynolds Inc., New York
phri!{dasys1 | philabs | mancol}!step!perl
	-- "I am not a language ... I am a free man!"

das@a.cs.uiuc.edu (David Steffens) (09/01/89)

In article <815@brazos.Rice.edu>
number1!perl%step@uunet.uu.net (Robert Perlberg) writes:

> This is a very old problem found on many UNIX systems.
Possible, but I doubt it.

> By the time your application is finished writing and closes the port,
> there is still quite a bit of data in the queue which has not yet gone out.
> Whatever data is still in the queue when the port is closed is thrown away.

Any UNIX on which this really is true is just plain _broken_.  The tty
driver is responsible for getting the chars out even _after_ the process
has gone away.

> This results in the "missing pages" problem reported by many lpr users.
Actually, I believe the problem is caused by _re-opening_ the tty line
before all of the output from the previous write has drained.

I've seen a similar problem on a hard-copy console at boot time -- the
messages from /etc/rc are truncated.  The tty driver is apparently
flushing all pending output when the _first_ open occurs on a line.  In
both the case of lpr and /etc/rc messages, no other process has the line
open for write, so every open is the first one.  Ergo, it is the "write...
last close... first open" cycle which tickles the bug.

> The solution is to make sure that the tty port is not
> closed until after all of the data has been transmitted.

You are correct... at least until Sun fixes the _real_ bug.  However, a
better way of describing the required work-around is: make sure there is
_at least one_ writer active on the line at all times.

{harvard,mit-eddie,think}!eplunix!das	David Allan Steffens
243 Charles St., Boston, MA 02114	Eaton-Peabody Laboratory
(617) 573-3748				Mass. Eye & Ear Infirmary