richk@pogo.WV.TEK.COM (Richard G. Knowles) (05/04/89)
In article <22489@ccicpg.UUCP> evans@ccicpg.UUCP ( Scott Evans) writes: >In article <98@snll-arpagw.UUCP>, paolucci@snll-arpagw.UUCP (Sam Paolucci) writes: >> Thus it appears to me that in a PC world where access to the serial >> device is easy and transparent, the only option is for the application >> program to append a ^D to the end of the PostScript output. This >> guarantees that the file will be handled properly whether it is >> redirected to the serial device, or later copied to it. >> >Can we help it if the PC is a "brain-dead" kind of machine and has no >other way telling when it gets to an "end of file"???? > >This is purely a kludge to get around a limitation on the PC. It is >especially apparent when you see a ^D not only at the end of a Postscript >file but also at the beginning!!! > >The postscript printer that is hooked up to our Unix system does not like the >^D at the beginning of the file and so we have to filter all the files that >come from a PC before they can be printed. Whoa there. Even though I hate to defend the PC, your argument for having to filter the ^D's out of PC produced PS files is misdirected. The printer doesn't care one whit about whether a job has a ^D at the start or not. What is "brain-dead" is your UNIX spooler which is relying on the ^D echo to decide when a job has finished. A ^D at the start of a job makes the spooler think the job has finished even before all it has been sent. This is one dependancy that Adobe's Transcript package has with its lpr filters (and one which I have removed to be able to effectively use both HP-GL and PS in the same printer through the same spooler). BTW, a ^D at the beginning of the file is there precisely because it makes up for those prior jobs that don't end with a ^D and would leave me with a printer whose state quite likely is not compatible with my job (like not leaving much VM or having redefined some operators that I use). -------- Whatever I say is my fault and no one elses! ----------- Richard G. Knowles richk@pogo.WV.TEK.COM Graphics Printing and Imaging (503) 685-3860 Tektronix, Inc; D/S 63-356 Wilsonville, Or 97070 or just yell "Hey, Rich!"
batcheldern@hannah.dec.com (Ned Batchelder, PostScript Eng.) (05/05/89)
In article <7207@pogo.WV.TEK.COM>, richk@pogo.WV.TEK.COM (Richard G.
Knowles) states that the Unix spooler is "brain-dead" because it cares
about ^D.
How should a spooler detect the end of the job? The entire reason the ^D
is echoed is for a spooler to be able to detect the end of the job. ^D's
are the provence of the spooler ENTIRELY. THEY DO NOT BELONG IN FILES.
THEY ARE NOT PART OF THE POSTSCRIPT LANGUAGE. PERIOD. To anyone who
believes ^D is part of the PostScript language: Show me where in the
red book it says that it is.
If no files contained ^D, and all spoolers used them, as was intended,
everything would be fine. Richard states that the reason he likes ^D at
the beginning of a file is so that if the last file didn't end with one,
then everything is ok. The correct solution to the problem is for your
printing software to use whatever signal is appropriate for end-of-file (it
may not be ^D) at the end of every job. Then everything will really be fine.
--Ned Batchelder, Digital Equipment Corp, BatchelderN@Hannah.DEC.com
wcs) (05/16/89)
In article <8905051356.AA01321@decwrl.dec.com> batcheldern@hannah.dec.com (Ned Batchelder, PostScript Eng.) writes:
]In article <7207@pogo.WV.TEK.COM>, richk@pogo.WV.TEK.COM (Richard G.Knowles)
]states that the Unix spooler is "brain-dead" because it cares about ^D.
]
]How should a spooler detect the end of the job? [...]
]^D's are the provence of the spooler ENTIRELY. THEY DO NOT BELONG IN FILES.
]THEY ARE NOT PART OF THE POSTSCRIPT LANGUAGE. PERIOD. To anyone who
But *why* should a spooler care about the end of a job? A typical
postscript program sets up some initial stuff, does some pages each ending
in showpage, and does some cleanup. The main things a spooler does that are
job-based are preloading fonts and reversing pages, which do require support
from the language to do (if you count EPSF as part of the language, and if
not, you shouldn't try reversing pages).
So if the printer gets stuff starting with EPSF introductory comments, it
should do whatever printer-setups it needs, and process stuff until it gets
to an EPSF terminating comment. If it gets stuff starting with anything
else, it should just keep reading data and doing a page at a time until
something interesting comes along to reset it. I agree that ^D is not the
ideal character to put in a file, but it's real ASCII, and should be
tolerated (albeit treated as an undefined word if nobody's used it.)
--
# Bill Stewart, AT&T Bell Labs 2G218 Holmdel NJ 201-949-0705 ho95c.att.com!wcs
# also found at 201-271-4712 tarpon.att.com!wcs
# But the treaty says we have to give Panama back to the Panamanians!
# Don't worry - we'll think of something. Corruption? Yeah, that's it!
richk@pogo.WV.TEK.COM (Richard G. Knowles) (05/18/89)
In article <645@cbnewsh.ATT.COM> wcs@cbnewsh.ATT.COM (Bill Stewart 201-949-0705 ho95c.att.com!wcs) writes: > > But *why* should a spooler care about the end of a job? The primary reason a spooler needs to know the actual end of a job (ie, when the interpreter has finished parsing/executing all input tokens and is waiting for more) is for proper resource accounting. A secondary reason is to be able to give the user some assurance that his job will not be effected by someone else's (ever had someone invoke the image/colorimage command but not supply enough data?). I have no idea how many installations actually *use* accounting info, but since the spoolers generally support the concept you need to be able to detect when the job is complete so the amount of consumables can be calculated and an appropriate charge be made to the user. There is more than one way to do that, such as: 1) adding a special message to the end of a job; cons: -- must wrap the job in a save/restore so as to protect the message from redefinitions made by the job *or* append an END-OF-JOB character/message (^D) to the job followed by your special message; -- exitserver requests could not be allowed; -- user could duplicate the message and thereby avoiding charges; -- How long do you wait?; -- Unreliable if communication channel has any chance of overrunning (quite possible on busy CPU's); 2) send status requests and watching for the "waiting" or "idle" state; pros: -- probably should be doing status requests anyway to be able to detect error conditions; cons: -- "waiting" is not a sufficient indicator (since waiting can in the middle of jobs if your comm channel is slow). Might have to append a END-OF-JOB (^D) to force the idle state, but imbedded ^D's could also confuse the issue. I'm sure there are additional ways, but using a ^D echo is much simpler. The spooler could be coded in such a way that ^D's are valid in jobs and still use it itself by just detecting any embedded ^D's. Once detected, pass it on but hold back any data that follows until the printer echos it back or the status goes idle, then continue on with the rest of the data. This way, the spooler knows that only one ^D is outstanding at any one time and can make a fairly safe assumption about the echo it gets back from the ^D it appended to the job. -------- Whatever I say is my fault and no one elses! ----------- Richard G. Knowles richk@pogo.WV.TEK.COM Graphics Printing and Imaging (503) 685-3860 Tektronix, Inc; D/S 63-356 Wilsonville, Or 97070 or just yell "Hey, Rich!"
batcheldern@hannah.dec.com (Ned Batchelder, PostScript Eng.) (05/22/89)
In article <645@cbnewsh.ATT.COM>, wcs@cbnewsh.ATT.COM (Bill Stewart) writes: > But *why* should a spooler care about the end of a job? In article <7279@pogo.WV.TEK.COM>, rick@pogo.WV.TEK.COM (Richard G. Knowles), replies that accounting is a good reason. Another good reason is that a queueing system should be able to tell when an entry has safely left the queue. For a printing system, that is only when the job has successfully printed, and that can only be determined by waiting for the ^D echo back from the printer. On VMS systems, you can PRINT/DELETE a file. Users would be extremely upset if the symbiont simply assumed that because it had sent all the data, that the job had printed, and then deleted the file. There are many ways for a printer not to complete a job. Another reason is for accurate notification of job completion. Even if we could assume that shipping the data to the printer guaranteed that the job would complete, when would it complete? By having an explicit handshake between the spooler and the printer, the spooler knows that, in fact, the job is completed, and if the user gets up from his desk and walks over to the printer, he will be able to pick the job up and walk away. Ned Batchelder, Digital Equipment Corp, BatchelderN@Hannah.DEC.com
greid@adobe.com (Glenn Reid) (05/23/89)
In article <8905221304.AA14261@decwrl.dec.com> batcheldern@hannah.dec.com (Ned Batchelder, PostScript Eng.) writes: >Another reason is for accurate notification of job completion. Even if we >could assume that shipping the data to the printer guaranteed that the job >would complete, when would it complete? By having an explicit handshake >between the spooler and the printer, the spooler knows that, in fact, the >job is completed, and if the user gets up from his desk and walks over to >the printer, he will be able to pick the job up and walk away. This is a worthy goal, but it isn't always true, unfortunately. The end-of-file (it isn't always a ^D) is echoed by the printer when an EOF is read from the input stream. Usually, this corresponds to the end of the job, since the interpreter has finished executing all the tokens it has received, and wants more. However, there are several circumstances under which a printer can consume the EOF, say "thank you" (by echoing another EOF), but not finish processing the job for quite some time. One of these is a job that reads data from the end of file itself, in which case it is not the scanner that hits EOF, it is, say, the "readhexstring" operator. If the program then turns around to process the data, it may be quite some time before it finishes, in an extreme case. It can also generate ERRORS even after the data connection has been broken with the host, which can be difficult deal with. Another instance (I think) is when the EOF follows the last token directly, without intervening white space, as in: showpage^D instead of showpage ^D The EOF then delimits the token, and is seen by the scanner while recognizing the name. I think the EOF is echoed then, by the scanner, rather than after the "showpage" name has been executed, but I'm not sure of it. In any case, it is an implementation detail. To echo what Ned Batchelder said, envision a scenario where you have a 2k communications buffer (very common), and you are sending a 1k file. The whole file will fit into the buffer (including the EOF), and theoretically you could break the connection then or send another file on its heels. But you may, instead, want to wait for the EOF to be echoed back to indicate that the job is done, or to detect an error and potentially retransmit the job instead of transmitting the next one. One way to think of it is that it is not a printer at all, but another computer connected through some communications protocol. The protocol usually has (and should have) some basic handshaking to determine when a file has been completely received, and that's what the echoing of EOF does. The "spooler" is not a traditional spooler, because it is not dealing with a dumb printer. It is really a communications program, a printer monitor, and lots of other things. Glenn Reid Adobe Systems
roy@phri.UUCP (Roy Smith) (05/23/89)
batcheldern@hannah.dec.com (Ned Batchelder, PostScript Eng.) writes: > On VMS systems, you can PRINT/DELETE a file. [...] By having an explicit > handshake between the spooler and the printer, the spooler knows that, in > fact, the job is completed, and if the user gets up from his desk and > walks over to the printer, he will be able to pick the job up and walk > away. Ned deserves lots of praise for his wonderful n-up printing work a few years ago, but I think he missed the point by a mile on this one. By having an explicit handshake between the printer and the spooler process, all the process knows is that the printer *says* the job is complete. That's better than just shoveling the data at the printer and hoping it can cope, but it sure isn't a firm promise that you can pick up the output and walk away with it. Somebody might have loaded the printer with the wrong forms. The printer might have jammed and not detected it. It might have run out of toner (our most common form of "silent failures" on print jobs). Maybe the printer had a software failure and is lying about the job status. Or, maybe somebody simply got to the printer first and took your output by mistake (or even on purpose). The point is, I think PRINT/DELETE is a *big* misfeature to put in a printer spooler. Maybe it should be some hard-to-get-at option for internal use, but not as a easily misused command line option. For once, I can't dump on VMS for this one; the Unix spoolers have similar options, with exactly the same problem. In fact, it's probably even worse on Unix. It's a lot easier to type "-r" by mistake than "/DELETE". I know. I've done it. More than once. -- Roy Smith, System Administrator Public Health Research Institute {allegra,philabs,cmcl2,rutgers,hombre}!phri!roy -or- roy@phri.nyu.edu "The connector is the network"
gore@eecs.nwu.edu (Jacob Gore) (05/23/89)
/ comp.lang.postscript / greid@adobe.com (Glenn Reid) / May 22, 1989 / [Lots of reasons why not to expect a ^D to mean "printer is done with the job"] Any suggestions? Our spooler does need to know when the job terminates (if nothing else, then to request the new page count in order to do accounting). Does it help to have the spooler strip ^D's out of output sent to the printer? Jacob Gore Gore@EECS.NWU.Edu Northwestern Univ., EECS Dept. {oddjob,chinet,att}!nucsrl!gore
CET1@phoenix.cambridge.ac.UK (Chris Thompson) (05/24/89)
Glenn Reid writes: > The end-of-file (it isn't always a ^D) is echoed by the printer when > an EOF is read from the input stream. and > I think the EOF is echoed then, by the scanner, rather than after the > "showpage" name has been executed, but I'm not sure of it. In any > case, it is an implementation detail. and much else in the same vein. I suppose it is foolish of me to argue with someone from Adobe about their own software, but I think Glenn is just plain wrong about this. The ^D (EOT) character is sent *from* the printer as part of the server loop, in the finish-off-the-current-job code, before it starts to think about where to get the next job from. Reaching the EOT in the input buffer just causes the scanner (or anyone else reading "currentfile") to see end-of-file (and you can't get past it, at least, not without trickery). Nothing is sent from the printer at this stage. As Glenn points out, if this wasn't the case then the ^D's wouldn't properly delimit the error messages produced by different jobs, and in fact they do. (I suppose I should add: on a LaserWriter, rev 0 or 2; but surely this can't be a matter of different implementations on different printers?) As others have pointed out, it would be unwise to assume that the ^D from the printer meant "I have printed that job perfectly" rather than "I have told you all I am ever going to tell you about that job", but at least it does mean the latter. Chris Thompson JANET: cet1@uk.ac.cam.phx ARPA: cet1%phx.cam.ac.uk@nsfnet-relay.ac.uk
greid@adobe.com (Glenn Reid) (05/26/89)
In article <A05B438E08C6CA70@UK.AC.CAM.PHX> CET1@phoenix.cambridge.ac.UK (Chris Thompson) writes: >Glenn Reid writes: >> The end-of-file (it isn't always a ^D) is echoed by the printer when >> an EOF is read from the input stream. >and >> I think the EOF is echoed then, by the scanner, rather than after the >> "showpage" name has been executed, but I'm not sure of it. In any >> case, it is an implementation detail. >and much else in the same vein. > >I suppose it is foolish of me to argue with someone from Adobe about >their own software, but I think Glenn is just plain wrong about this. I was mistaken. You're right. ["I'm left, she's gone..."] >The ^D (EOT) character is sent *from* the printer as part of the >server loop, in the finish-off-the-current-job code, before it starts >to think about where to get the next job from. Reaching the EOT in >the input buffer just causes the scanner (or anyone else reading >"currentfile") to see end-of-file (and you can't get past it, at least, >not without trickery). Nothing is sent from the printer at this stage. This is correct; it is handled by the server loop when the output file stream is closed. Closing a file causes the appropriate EOF to be written. >As Glenn points out, if this wasn't the case then the ^D's wouldn't >properly delimit the error messages produced by different jobs, and >in fact they do. (I suppose I should add: on a LaserWriter, rev 0 or >2; but surely this can't be a matter of different implementations on >different printers?) It's the same on all the printers that support serial communications. My error. Sorry about that. >As others have pointed out, it would be unwise to assume that the >^D from the printer meant "I have printed that job perfectly" rather >than "I have told you all I am ever going to tell you about that job", >but at least it does mean the latter. Right. Whether the job was printed to the user's satisfaction is a different issue than whether the job was printed to the printer's satisfaction. For example, many printers are happy to substitute Courier for unknown fonts. A message is sent back to the host to indicate this substitution, but a job printed in a default font is usually not to a user's satisfaction, and should be reprinted with the correct fonts downloaded or perhaps the whole print job should be rejected by the spooler as unprintable, depending on the user's wishes. It is complicated, isn't it? Maybe we should rehash the simple issues of what should be done, rather than the implementation details. Here's my opinion about it: 1. Page composition software composes page, selecting fonts (by name), placing images and text at arbitrary locations in user space. 2. Page composition software produces device-independent PostScript language file representing imaging instructions required to paint the above-mentioned page, and puts %%Comments in place to indicate the proper media and font requirements of the print file. 3. This file is handed to a print spooler, which attempts to resolve the printer-dependent issues like media selection and perhaps downloading of fonts, depending on the document requirements. A more refined print file is produced, where the %%Comments are resolved for the particular intended printer. More %%Comments are put surrounding the printer-dependent code, so that the process can be repeated by another spooler if necessary. 4. The spooler opens a communication channel with the chosen printer. 5. The spooler transmits the file to the printer, monitoring status, watching for %%[ Error ]%% messages, and other appropriate things. 6. The spooler sends the appropriate EOF indication at the end of the job, based on (4). 7. The spooler waits for confirmation of the job, in the form of an echoed EOF, from the printer. Any errors are logged or sent back to the original submittor. Job accounting may take place (counting pages, looking at wristwatch, etc.) No doubt this will stir further controversy somehow, but it does seem to be an important issue. Glenn Reid Adobe Systems
dbrooks@osf.OSF.ORG (David Brooks) (05/27/89)
As the one who wrote the Prime PostScript despooler, my problem (once I had finished) was precisely with the non-standard nature of the implementation. I interpreted Appendix D of the Red Book, and the implementations on machines that came after the LaserWriter (QMS1200/2400, QMS800, Data Products LZRsomething) to mean: "This isn't actually the PostScript standard, but we're establishing it as a de facto expectation." This I took to mean things like the serverloop execution, ^D, ^C, ^T, most of statusdict, and so on. I kind of came to rely on these, although I was nervous because I knew Adobe didn't regard them as standard (and I didn't want to go playing with printer description files). Everything went well until... Bong! the DEC LNO3 standard password wasn't 6 digits, but a string whose initial value was LN03R. And, since the software read the password out of a (protected) environment file, and assumed it was only 6 characters long, and we now had to write (LN03R) (7 characters) to get the semantics right... you fill in the rest. We found a disgusting hack to work around it. You don't want to know. I'm not at Prime any more, and I did all this without benefit of prior art. In particular, what I'm about to describe may be familiar to users of other despoolers, or not. I worried particularly about races and timeouts. That's not easy to do on a timeshared computer without multi-event wait, and some of the code is gross. Also, I don't like "unattended" software that just goes quiet or dies without telling anyone how, especially if it's because of external misbehaving hardware. It does behave sensibly if it finds a ^D embedded in the file! In case anyone is interested, here's a summary of the less obvious features: 1. Establishing contact with the printer didn't assume a printer that was alive, or even one that was quiescent. First I hit it with ^T and looked for a properly formatted reply among potential junk that could be streaming back from yesterday's job. Then ^D (wait for ^D), and if no ^D returned, ^C, ^D again (wait for ^D). This covers a printer that's quiescent, or busy, or in interactive mode. 2. A hack like Apple used: check the printer for a flag and, if it's not there, download some standard dictionaries in separate jobs. This is repeated before each user job, in case the printer was turned off and on again. 3. Print the header page with "large" characters printed in dark gray (so they don't wash out) and 84-point -- except that if the line would get too long the point size is shrunk to fit (the printer itself does these calculations). 4. Read pagecount if possible (and parseable), and start the job, offering host-based text emulation for non-PostScript files. Field all returned messages. 5. If the returned message is %%[ Flushing..., drop the job (yes, it's possible for a program to fake that, but why bother?). 6. Do the ^D negotiation. (Send one, wait for one). As I said, we stripped out embedded ^Ds, but if we hadn't it would, I think, still be OK, except you might attach messages from this job onto the next job. 7. Print in text any uplinked data, as a separate job. That way the user sees error messages and anything else he cared to "print", on sheets after the job's proper output. Any messages that are clearly meant for the operator/administrator get put in a log file (who watches system consoles these days?). Get pagecount again. 8. During jobs, execute a timeout. How do you distinguish between a user who submits "{}loop" and one who submits <8Mb of data imaged> showpage? We judged that a printer that hasn't ^D-ed about 20 minutes after the last character sent is almost certainly wedged, so we ^C after 30 minutes it and do end-of-job. If no ^D is still sent back (after 15 seconds) we declare the printer seriously dead. 9. Exception to the above: If you get a %%[ PrinterError during the timeout, the clock must be halted until the printer is well again, as determined by a healthy response to ^T. The problem is caused by paper out on last sheet of job, probably. Care is needed not to get stuck if the printer decides to croak at this point. 10. General robustness was built in. For example, I've seen a QMS1200 return a %%[ status line with no trailing newline, so we won't hang waiting for a complete line. As I said, the problem with coding like this is relying on the nonstandard semantics, and for the most part Adobe has kept things standard (even if not always sensible...want to talk about suppressing bare CR characters?). I do rely on: ^C, ^D, ^T semantics, and the text returned by ^T; exitserver semantics including password; and for convenience sake the statusdict entries pagecount, printername, product, revision, jobname and username (it won't actually break if statusdict is absent). So, Adobe, the point of all this is to ask: are you ever going to change these expectations and make Prime unhappy (since I don't think they have anyone there who understands all this stuff)? -- David Brooks dbrooks@osf.org Open Software Foundation uunet!osf.org!dbrooks 11 Cambridge Center Personal views, not necessarily those Cambridge, MA 02142, USA of OSF, its sponsors or members.