Article View: comp.lang.postscript
Article #8507Re: ^D embedded in PS files
From: David Brooks
Date: Fri, 26 May 1989 19:33
Date: Fri, 26 May 1989 19:33
107 lines
5715 bytes
5715 bytes
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.
Technical Details
Message-ID:
<1005@osf.OSF.ORG>Path:
arc1-ca.pugleaf.net!utzoo!attcan!uunet!husc6!osf!dbrooksReferences:
<A05B438E08C6CA70@UK.AC.CAM.PHX> <864@adobe.UUCP>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!attcan!uunet!husc6!osf!dbrooks From: dbrooks@osf.OSF.ORG (David Brooks) Newsgroups: comp.lang.postscript Subject: Re: ^D embedded in PS files Message-ID: <1005@osf.OSF.ORG> Date: 26 May 89 19:33:17 GMT References: <A05B438E08C6CA70@UK.AC.CAM.PHX> <864@adobe.UUCP> Reply-To: dbrooks@osf.org (David Brooks) Organization: Open Software Foundation Lines: 107