[comp.unix.questions] How can I "read" the tty port?

danno@3b2.UUCP (Daniel Notov) (10/19/88)

I hope I'm missing the obvious on this one.

Cast of characters:
	AT&T 3B2/400 UNIX SVR3.1 and/or AT&T 6386E 386/UNIX SVR3.1
	Texas Intruments Omnilaser 2115

The TI OMNILASER is a postscript printer that also has HP LaserJet+
Emulation.  Mode selection can be controlled via PS and HP commands.

I have set up my interface file to swtich into the mode wanted via command
line options.   The problem occurs when the file has spooled out to the
printer the printer is still processing,  and the next job is sent down
the line.  

The next job is stored in its buffer,  but when the printer changes modes,
it may lose that info.  To combat this problem,  I inserted sleep's in the
script at the beginning when I change modes, and at the end when the file
has completed despooling.  The first sleep is O.K. because I know
approximately how long it takes to change modes.  The ending sleep is n.g.
because, I do NOT know when the job has completed processing.

Playing with cu,  I discovered that a ^T <CNTRL-T> causes the printer to
echo the following:
	1) In postscript mode,  job status:
		%%[status: busy; source: serial 25]
			or
		%%[status: idle]
	2) In LaserJet mode, the printer echos nothing.  The ^T's are
	discarded, and don't interfere with the text being printed.

My idea:
	After the file is despooled, and the reset sequences are sent,
	periodically poll the printer by sending ^T's.  My question,  how
	do I capture the messages echoed back by the printer? Once I get
	it,  I can guess on the the following states:

	1) Captured: nothing; still processing LaserJet Job
	2) Captured: %%[...busy...]; still processing PS Job
	3) Captured: %%[...idle...]; all processing complete,  exit script.

Sorry for rambling at length.  I wanted to get all the facts in.  Please e-mail
any responses.  I'll summarize if the volume warrants.

Tx.
danno
-- 
	Daniel S. Notov		|	{monster,uunet}!onm3b2!danno     
	Ogilvy & Mather, Inc.	|	(212) 907-4255		
	New York, NY		|				

robert@shangri-la.gatech.edu (Robert Viduya) (10/20/88)

>danno@3b2.UUCP (Daniel Notov) (danno@3b2.UUCP, <288@3b2.UUCP>):
> 
> I hope I'm missing the obvious on this one.
> 
> Cast of characters:
> 	AT&T 3B2/400 UNIX SVR3.1 and/or AT&T 6386E 386/UNIX SVR3.1
> 	Texas Intruments Omnilaser 2115
> 
> The TI OMNILASER is a postscript printer that also has HP LaserJet+
> Emulation.  Mode selection can be controlled via PS and HP commands.
> 
> I have set up my interface file to swtich into the mode wanted via command
> line options.   The problem occurs when the file has spooled out to the
> printer the printer is still processing,  and the next job is sent down
> the line.  

I've not had any experience with the TI, but I've played with
LaserWriter Plus's and IINTX's and I think the solution I'm about to
present works with all PostScript printers.  I remember reading about
this trick in the Red Book, but I'm not sure if it was in the generic
language description or in the LaserWriter specific appendix.  Anyway,
try it and see if it works.

A job sent over to the laser printer via the serial line should be
terminated with a EOT (control-D).  When the printer receives the EOT,
it knows that it's got the whole job and when it has completely
finished processing and printing that job, it will echo that EOT back
to the host.  This means that all the host machine has to do to
ensure that the printer has finished printing a job before sending
another one is:

    1.	Send a job.
    2.	Send an EOT terminating job.
    3.	Wait for the EOT to be echoed back from printer.
    4.	Repeat from step one.

As an example, here's a bit of code I wrote that's part of a
LaserWriter driver for a spooling package.  The function send_file
takes two file descriptors as arguments, the first being the file to
send and the second being a file to write any data sent from the
printer to the host.  The global tty_file is the file descriptor of
the tty line attached to the printer.

send_file (src_file, result_file)
int	src_file, result_file;
{
    char	ch;
    int		chpid;
    bool	done;

    /*
     * fork.  The parent process sends the file to the printer,
     * followed by an EOT.  It then hangs around and waits for the
     * child to finish.  The child simply reads characters from the
     * printer and stuffs them in the result file until it gets an
     * EOT.  It then terminates and the parent is notified and is
     * allowed to procede.
     */
    switch (chpid = fork ()) {
	case -1:
	    syslog (LOG_NOTICE, "fork() - %m");
	    exit (EXIT_RETRY);
	case 0:		/* child - tty input -> result_file */
	    ch = '\0';
	    do{
		if (read (tty_file, &ch, 1) == 1)
		    (void) write (result_file, &ch, 1);
	    } while (ch != '\004');	/* ^D is eof indicator */
	    exit (EXIT_OK);	/* wake parent up */
	default:	/* parent - src_file -> tty output */
	    done = FALSE;
	    while (!done) {
		switch (read (src_file, &ch, 1)) {
		    case 1:
			(void) write (tty_file, &ch, 1);
			break;
		    case 0:
			(void) write (tty_file, "\004", 1);	/* send EOT */
			done = TRUE;
			break;
		    default:
			syslog (LOG_NOTICE, "read(%s) - %m", data_fn);
			exit (EXIT_RETRY);
		}
	    }
	    (void) wait ((int *) 0);	/* wait for child */
	    break;
    }
}


Hope all this helps...

				robert

--
Robert Viduya					   robert@shangri-la.gatech.edu
Office of Computing Services
Georgia Institute of Technology					 (404) 894-6296
Atlanta, Georgia	30332-0275