[comp.unix.xenix] Writing Xenix serial I/O routine

sws@holin.ATT.COM (Steve Spear) (02/09/90)

I've been trying to write a simple single character I/O routine for Xenix
serial ports to port a FIDO-net bbs package to Xenix.  Unfortunately I've
only been sucessfull with writing out the port - I never see anything come
back.  I open the modem line with open( "/dev/tty1A", O_RDWR | O_NDELAY )
and the handle comes back just fine.  Then I set the line settings with IOCTL
and do a write( handle, "ATZ\r", 4 ).  I see the data go out the port on the
data scope and the modem flashes and returns OK on the data scope, but when
I do a read( handle, &ch, 1 ) I never get anything.  Does someone have a small
sample program I could look at to get this working?  

Also just out of curiosity what do the devices /dev/ttyp0 - /dev/ttyp7 do?

Any help would be greatly appreciated. 

karl@ddsw1.MCS.COM (Karl Denninger) (02/13/90)

In article <890@holin.ATT.COM> sws@holin.ATT.COM (Steve Spear) writes:
>I've been trying to write a simple single character I/O routine for Xenix
>serial ports to port a FIDO-net bbs package to Xenix.  Unfortunately I've
>only been sucessfull with writing out the port - I never see anything come
>back.  I open the modem line with open( "/dev/tty1A", O_RDWR | O_NDELAY )
>and the handle comes back just fine.  Then I set the line settings with IOCTL
>and do a write( handle, "ATZ\r", 4 ).  I see the data go out the port on the
>data scope and the modem flashes and returns OK on the data scope, but when
>I do a read( handle, &ch, 1 ) I never get anything.  Does someone have a small
>sample program I could look at to get this working?  
>
>Also just out of curiosity what do the devices /dev/ttyp0 - /dev/ttyp7 do?
>
>Any help would be greatly appreciated. 

Don't use "O_NDELAY" except to open the port initially.

Then, turn it OFF with a fcntl() call (turn on CLOCAL with an ioctl()
first).  Now you can read/write to the port, and have it block correctly for
input.

Once you have a connection (ie: "CONNECT" from a modem), turn off CLOCAL
with another ioctl so you can sense the carrier detect.

A rough order of operations is:

#include	<fcntl.h>
#include	<termio.h>

struct	termio	tbuf;
int	oldflag, x;

x = open("/dev/tty1A", O_RDWR|O_NDELAY);	/* It's a good idea to check */
						/* and make sure you do open! */
ioctl(x, TCGETA, &tbuf);
tbuf.c_cflag |= CLOCAL;
ioctl(x, TCSETAW, &tbuf);		/* Turn on CLOCAL, no carrier detect */
oldflag = fcntl(x, F_GETFL, 0);		/* Disable NDELAY */
fcntl(x, F_SETFL, oldflag & ~O_NDELAY);

..... (read/write the port you just opened)

Once you detect a carrier from the modem (ie: "CONNECT"), you do:

ioctl(x, TCGETA, &tbuf);
tbuf.c_cflag &= ~CLOCAL;		/* Clear CLOCAL */
ioctl(x, TCSETAW, &tbuf);		/* Now carrier is sensed */

..... continue onward .....

This ensures that you will get a signal if the carrier drops (ie: the modem
hangs up for no good reason).  You MUST be sure you have a connection before
you turn the CLOCAL off, else you'll get that signal immediately (which if
not trapped terminates your process!)

It's a good idea to do the clocal thing, although not strictly necessary --
if you don't mind the line hanging for a nice long time (until your program
either times out or you find it hung :-).

Do be aware that at least one "smart" board manufacturer (name deleted to
protect the guilty) botches the handling of this particular sequence....

If you don't turn off O_NDELAY, you should effectively be "busy-waiting";
the reads will return zero unless there is a character in the buffer right
>now<.  Then, you should get the character.  O_NDELAY means literally "no
delay", and you get exactly that -- no waiting for the characters to enter
the stream.

Sometimes this is what you want.  Most (95+%) of the time it is NOT what you
want, as you effectively are busy-waiting (which is a very bad programming
practice under a multitasking operating system!)

--
Karl Denninger (karl@ddsw1.MCS.COM, <well-connected>!ddsw1!karl)
Public Access Data Line: [+1 708 566-8911], Voice: [+1 708 566-8910]
Macro Computer Solutions, Inc.		"Quality Solutions at a Fair Price"