Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!mailrus!ncar!husc6!rice!sun-spots-request From: number1!perl%step@uunet.uu.net (Robert Perlberg) Newsgroups: comp.sys.sun Subject: Re: cat /dev/ttya > /dev/null & Keywords: SunOS Message-ID: <815@brazos.Rice.edu> Date: 10 Aug 89 17:15:50 GMT Sender: root@rice.edu Organization: Sun-Spots Lines: 45 Approved: Sun-Spots@rice.edu X-Sun-Spots-Digest: Volume 8, Issue 97, message 2 of 14 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 #include 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!"