> From [EMAIL PROTECTED] Fri Sep 19 07:45:53 2003
> Date: Fri, 19 Sep 2003 15:19:39 +0200 (CEST)
> From: Villy Kruse <[EMAIL PROTECTED]>
> To: [EMAIL PROTECTED]
> Subject: Re: LPRng: serial port blues - solution
>
> On Fri, 19 Sep 2003, Angie Saxton wrote:
>
> > Date: Fri, 19 Sep 2003 10:28:28 +0100
> > From: Angie Saxton <[EMAIL PROTECTED]>
> > Reply-To: [EMAIL PROTECTED]
> > To: [EMAIL PROTECTED]
> > Subject: Re: LPRng: serial port blues - solution
> >
> > Dear All,
> >
> > We may have found a solution (not flow control)... It does appear to be a
> > timing issue with closing the port. One of the chaps in the office
> > suggested a sleep command, and I have one in the "if" filter now prior to
> > the :cl: evaluation. This has allowed me to print the larger test file. If
> > this sorts the problem I will post again to confirm.
> >
>
>
> That reminds me: On some unix systems, when you close a serial port
> all the settings revert back to defaylt including the bit rate, also
> while there are bytes to be transmitted. These pending bytes will then
> be sent with a wrong bit rate which will be discarded by the printer or
> result in a framing error. A possible soluting I've seen is to have a
> small program open the serial printer port and then keep it open for ever.
> Thus the serial port will never see the final close and the settings won't
> be reset. A sleep before close will do thesame if you sleep long enough.
> Also consider using tcsetattr with TCSADRAIN, which supposedly will
> block until all pending output has been sent.
>
>
>
>
> Villy
The tcdrain() function does this as well. However, I sure wish there
was a non-blocking version of this.
If you plan to use this method, you should put a wrapper around it with a timeout,
so that you can periodically check the backchannel for error messages:
This may look complicated. Right. It IS complicated.
while(1){
struct timeval tm;
fdset rd;
FD_CLEAR(&rd);
FD_SET(&rd, fd );
memset(&tm, 0, sizeof(tm));
tm.tv_sec = 1;
n = select( fd+1, &rd, 0,0,&tm); // we wait for 1 sec for backchannel infor
if( n < 0 ){
CROAK! // bad news about select failing
} else if (n >0 ){
n = read(fd,msg,sizeof(msg)-1); // we read status
if( n < 0 ){ // ooopsss. read failed
CROAK!
} else if( n == 0 ){ // EOF on printer? we must be done
break;
} else {
print message from printer;
}
} else {
/* time out waiting for response */
ualarm(1000); // set alarm value for 1 millisec seconds
n = tcdrain(fd); // we delay for at most 1 millisec or succeed immediately
ualarm(0); // turn off alarms
if( n == 0 ){
/* drained */
break;
}
}
}
close(fd);
I will put a modified version of this the LPRng code.
It will checkif the device is a serial line and then use this method
rather than doing a close.
Note that this will have to be done in both LPRng and IFHP.
Patrick Powell Astart Technologies
[EMAIL PROTECTED] 6741 Convoy Court
Network and System San Diego, CA 92111
Consulting 858-874-6543 FAX 858-751-2435
LPRng - Print Spooler (http://www.lprng.com)
-----------------------------------------------------------------------------
YOU MUST BE A LIST MEMBER IN ORDER TO POST TO THE LPRNG MAILING LIST
The address you post from MUST be your subscription address
If you need help, send email to [EMAIL PROTECTED] (or lprng-requests
or lprng-digest-requests) with the word 'help' in the body. For the impatient,
to subscribe to a list with name LIST, send mail to [EMAIL PROTECTED]
with: | example:
subscribe LIST <mailaddr> | subscribe lprng-digest [EMAIL PROTECTED]
unsubscribe LIST <mailaddr> | unsubscribe lprng [EMAIL PROTECTED]
If you have major problems, send email to [EMAIL PROTECTED] with the word
LPRNGLIST in the SUBJECT line.
-----------------------------------------------------------------------------