shore@adobe.UUCP (Andrew Shore) (08/06/85)
Both the 4.2BSD and System V line printer spoolers invoke a printer-specific interface program with one file descriptor already open to "the device" (the printer). On both systems the fd is open for writing, but the documentation states that the device can be opened for reading also under certain circumstances (specifying "rw" in the BSD printcap entry, or having the file (device) readable on SysV); however, you still only get one fd when you get called. You do NOT get passed the name of the device (so you can't do your own open(2)). The days of printers-as-stupid-data-sinks are long gone. More and more printers are sophisticated devices which may want to carry on detailed dialogs with a host -- passing status information, requesting certain operations, etc. Some may generate asynchronous messages (e.g., "out of paper"). I am implementing spooler interfaces for such printers, and have to be able to read from and write to the printer independently. My spooler interface starts off by doing a fork with the parent continuing as "sender" and the child as "listener". Each of these needs a stream to (from) the device respectively. If I try to read and write from the single fd I got started with, things mess up (the fd has only one buffer and file pointer which gets confused if you try to share arbitrary reads and writes to it). I find that I have to have 2 fd's to the same device. The way I currently accomplish this is: /* Before the fork (stdout is the device) ... */ fdsend = fileno(stdout); /* the printer (write) */ fdlisten = dup(fdsend); /* the printer (read) */ /* Do the fork */ /* parent can write to fdsend (stdout) */ /* child does the following ... */ psin = fdopen(fdlisten,"r"); /* make a FILE out of an fd */ /* child now has fdlisten (psin) to read from */ This seems to work fine on both 4.2BSD and SysV, but it is not at all obvious that this is correct or that it should work at all. I've been warned that this technique will NOT work for non-character (non-terminal?) devices. If the device is really a socket (like a PUP connection to an ethertip) this supposedly fails. Will this work for block devices, FIFOs, etc? Is there a better, cleaner, more general solution? Or am I really doing things OK and just beening paranoid? I can't change the way I get invoked -- the spoolers just do it that way. Thanks in advance, --Andy Shore Adobe Systems Incorporated (415)852-0271 {decwrl,glacier,sun}!adobe!shore
chris@umcp-cs.UUCP (Chris Torek) (08/07/85)
Why not simply avoid stdio within the despoolers? It tends to create more problems than it's worth when you need exact control over what happens when. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 4251) UUCP: seismo!umcp-cs!chris CSNet: chris@umcp-cs ARPA: chris@maryland