gdmr@uunet.uu.net (George D M Ross) (01/27/89)
xilinx!sol!kevin@uunet.uu.net (Kevin Kelleher) writes: >I have been having similar with problems with my printer dropping pieces >of files on an HP Laserjet printer to my Sun 3/280 under OS 4.0.1. After >some experimentation I have decided it is probably a tty driver problem. We came to much the same conclusion when we upgraded to 4.0 -- printers and plotters would lose the end of files sent to them. After some experimentation with cat and dumb terminals we decided that XON/XOFF was being zapped when the final close of the device was done. To test it, hang a terminal on a serial port and cat a largish file to it. Observe that flow control works while the cat is executing but not for the tail of the file which is still in the output buffer after the cat terminates. If you then try again, but this time cat from the terminal as well as to it you will find that flow control works all the way through. We "solved" the problem by having our output filters wait around a while (device dependent) after the last of the output has gone before closing the output device. There may be some option settings which we missed which would fix this -- we didn't try too hard as we had a filter which did more-or-less the right job. An alternative for dumb printers might be to cat the device to /dev/null in your rc file (we didn't bother trying this, but based on our tests it seems plausible). When we come to installing our laser printers we'll probably have to write some trivial program which simply opens the device and then sleeps forever, as the two suggestions above either won't be feasible or won't work. George D M Ross ..!mcvax!ukc!ecsvax!gdmr Department of Computer Science gdmr@ecsvax.ed.ac.uk Edinburgh University +44 31 667-1081 x2730
perl@philabs.philips.com (Robert Perlberg) (02/16/89)
In my HP filter, I wait for the output to flush with this code: #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
guy@uunet.uu.net (Guy Harris) (03/02/89)
>In my HP filter, I wait for the output to flush with this code: >... > while(ioctl(fd, TIOCOUTQ, &outchars) == 0 && outchars > 0) Wow. That probably works (although I don't know that TIOCOUTQ will always give the right answer), but under 3.x or 4.0 (or any V7/BSD-style tty driver) the following should work better: struct sgtty sgttyb; (void) ioctl(fd, TIOCGETP, &sgttyb); (void) ioctl(fd, TIOCSETP, &sgttyb); since, as it says in the 4.3-tahoe TTY(4): TIOCSETP Set the parameters according to the pointed-to "sgttyb" structure. The interface delays until output is quiescent, then throws away any unread characters, before changing the modes. Since you do a TIOCGETP followed immediately by a TIOCSETP, the modes aren't changed; the only effects of the TIOCSETP are 1) it waits for output to drain and 2) it flushes all input. The latter is an unfortunate side-effect, but it may not be a problem here. I think all of the variants mentioned above, except 4.0, say much the same thing. 4.0's TTCOMPAT(4M) basically says "TIOCSETP gets turned into a TCSETSF", and 4.0's TERMIO(4) says about TCSETSF: TCSETSF The argument is a pointer to a termios struc- ture. The current terminal parameters are set from the values stored in that structure. The change occurs after all characters queued for output have been transmitted; all charac- ters queued for input are discarded and then the change occurs. which is basically the same set of side-effects as TIOCSETP. In 4.0, though, and other systems that offer an S5-compatible tty driver, there is an even better way; again from TERMIO(4): TCSBRK The argument is an int value. Wait for the output to drain. If the argument is 0, then send a break (zero-valued bits for 0.25 seconds). If the argument is *not* zero, no break is sent, so ioctl(fd, TCSBRK, 666); /* insert your number here - beastly, eh? */ will just wait for output to drain.