home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!auspex-gw!guy
- From: guy@Auspex.COM (Guy Harris)
- Newsgroups: comp.sys.sun.hardware
- Subject: Re: Additional RS232 ports
- Message-ID: <14050@auspex-gw.auspex.com>
- Date: 14 Aug 92 02:48:37 GMT
- References: <1992Aug12.141935.18721@aristo.tau.ac.il> <l8lqs1INNd7b@appserv.Eng.Sun.COM>
- Sender: news@auspex-gw.auspex.com
- Organization: Auspex Systems, Santa Clara
- Lines: 93
- Nntp-Posting-Host: bootme.auspex.com
-
- >The root cause of the problem,
- >however, has to do with AT&T's STREAMS code not honoring a non-blocking
- >close() call nor following the STREAMS close() semantics of timing out after
- >a certain period of time from when the user application did a close() to the
- >serial port and there was still data to be sent to the device.
-
- Eh?
-
- AT&T's code *does* honor closes on non-blocking descriptors, and *does*
- time out after STRTIMOUT seconds, as of SVR3.1.
-
- The SunOS 4.x code is derived from the SVR3.1 code, and it does the
- same.
-
- *HOWEVER*:
-
- That very behavior caused *bugs* to be filed against SunOS 4.0. The
- problem is that if you have a printer (or other output device; I think
- one complaint was about a plotter) attached to a serial port, and that
- printer requires flow control, and the software that drives the printer
- writes a bunch of stuff to the printer and then closes the printer, then
- if the printer takes too long to print out the last stuff written to it,
- the stream gets dismantled while stuff is still queued up to get sent to
- the printer, and Bad Things Happen.
-
- In particular, once "ldterm" is popped off the stream, you don't get
- ^S/^Q flow control any more, and you run the risk of overrunning the
- printer.
-
- The workaround I suggested when those bugs started arriving was to have
- some other process hold the serial port open, so that the stream *isn't*
- dismantled when the close is done.
-
- I think that kept the problem from occurring, but it's kind of ugly, and
- I guess the tech support people may have gotten tired of explaining it
- over and over again, so the ^S/^Q flow control stuff was moved down to
- the driver, at least in one of the serial port patches.
-
- In 4.1, the flow control stuff was moved out of the driver, and "ldterm"
- was changed so that, in its close routine, it sent an "ioctl" streams
- message downstream, doing a TCSBRK "ioctl" with a non-zero argument. A
- TCSBRK with a non-zero argument blocks waiting for all output to drain.
- This means that the "ldterm" close routine will block until output
- drains - no matter how long that takes.
-
- Now, at least in the case of printers like that, the STREAMS close
- semantics are Very Bad, as indicated (anyone who disagrees with that
- will be sentenced to 100 years in purgatory answering calls from SunOS
- 4.0 customers whose printers don't work :-)). (In fact, my first
- unpleasant encounter with AT&T-style tty close semantics was with System
- III, long before any System N release had STREAMS; the problem described
- above occurred, because the printer in question required ^S/^Q to be
- honored.)
-
- Unfortunately, that means that if the port *never* drains, a close can
- hang forever.
-
- In part, that can be fixed by making sure that if carrier drops, all
- queued-up data is flushed, *and* any TCSBRK "ioctl"s waiting for output
- to drain get an acknowledgement sent upstream, so that the close can
- continue. A quick look at the "zs" driver indicates that this might not
- happen; the code that sends the M_HANGUP message upstream when carrier
- drops doesn't flush all queued-up data. If so, that might be the cause
- of the problem.
-
- That fix should mean that if some ^S'ed output was pending when carrier
- dropped, and a close was blocked waiting for the output to drain, the
- close would unblock. It would have to be applied to all serial port
- drivers.
-
- It still doesn't handle the case where the line has soft carrier, and
- somebody ^S's output and then turns the terminal off, say. If somebody
- then kills off that person's session, the close will, I think, hang
- until somebody turns the terminal back on again and does a ^Q.
-
- To handle *that* problem, the "wait for output to drain" must be made
- optional. This could be done by:
-
- 1) having some "ioctl" to specify whether a close should do that
- or not.
-
- If wait-for-output-to-drain were made the default, "getty" or
- "ttymon" or whatever would presumably turn it off.
-
- If it were *not* the default, any code doing printing would
- probably want to turn it *on* if the printer required flow
- control, unless the mode is "sticky" (i.e., unlike most UNIX
- tty modes, persists even after the last close), in which case
- you could have one of the "/etc/rc" files set that mode on
- the ports with printers of that sort on them.
-
- 2) having any code doing printing explicitly do the TCSBRK
- "ioctl" before closing the port.
-