[comp.sys.att] termio

vern@zebra.UUCP (Vernon C. Hoxie) (01/06/89)

	I have been trying to write a test program for a Trailblazer.
It is connected to /dev/tty000.  The program opens this file with:

	fd = open("/dev/tty000", O_RDWR | O_NDELAY);

I then do:

	if (ioctl(fd, TCGETA, &tsavetty) == -1) exit();

Then after some other housekeeping:

	char buf[512];
	.
	.
	k = read(fd, buf, 211);

It is written:

	 "When attempting to read a file associated with a tty that has
	  no data currently available."

This infers that when data is available, the number of characters will
be returned.  Sure enough, when a command is sent to the modem, various
numbers are returned depending upon the command sent.  So far so good.

	When 'buf' is read out, all I get are ^@'s.  Between reads,
the buffer is rewritten with 'z's so the ^@'s are indeed the characters
which are in the buffer.  I have tried this with every configuration of
the 'struct termio' that is possible and still all I get are ^@'s!
(^@ = NUL = 0 = 0x0000).

	I tried connecting a stream with the fdopen(fd, strm) where
FILE *strm.  Then using ch = fgetc(strm) I get ^A's.
(^A = SOH = 1 = 0x0001).

	Another tactic I thought about was to access the clist directly.
When I referred to /usr/include/sys/tty.h I read:

	/* Macro to find clist structure given pointer into it	*/

Nowhere can I find out how to grab that "given pointer".  The author of
that header didn't even include a smiley face! :-)

	There ought to be a more standard method of recovering the
returned characters.  Oh, by the way, the modem does work when running
on pcomm2.  I am confident that it will also work under uucp but I would
like to finish this test program before I put it into operation.

	I will certainly appreciate any help you can suggest.  Yes, I
will offer the program to the net if I can get it to work.

-- 
Vernon C. Hoxie		       {ncar,nbires,boulder,isis}!scicom!zebra!vern
3975 W. 29th Ave.					voice: 303-477-1780
Denver, Colo., 80212					 uucp: 303-455-2670

les@chinet.chi.il.us (Leslie Mikesell) (01/10/89)

In article <137@zebra.UUCP> vern@zebra.UUCP (Vernon C. Hoxie) writes:
>
>	I have been trying to write a test program for a Trailblazer.
>It is connected to /dev/tty000.  The program opens this file with:
>
>	fd = open("/dev/tty000", O_RDWR | O_NDELAY);

You probably need to use fcntl() to turn off the O_NDELAY before
trying to use the port (set CLOCAL first if you need it).  Write()s
don't wait for the hardware to be ready if you leave O_NDELAY
set and strange things happen.  I have seen code that indicated that
a close(open(/dev/ttywhatever,2) was needed to force the mode to
changed.  Does anyone know which versions of unix require this?

Les Mikesell

john@polyof.UUCP ( John Buck ) (01/10/89)

In article <137@zebra.UUCP>, vern@zebra.UUCP (Vernon C. Hoxie) writes:
> It is connected to /dev/tty000.  The program opens this file with:
> 	fd = open("/dev/tty000", O_RDWR | O_NDELAY);
> Then after some other housekeeping:
> 	char buf[512];
> 	.
> 	.
> 	k = read(fd, buf, 211);
> Vernon C. Hoxie		       {ncar,nbires,boulder,isis}!scicom!zebra!vern

Yeah, this is a common problem.  the open(...O_NDELAY) is the culprit,
for lack of a better word.  After the open(), do a

	if(fcntl(fd, F_SETFL, 0) == -1){
		perror("F_SETFL");
		....
	}

The O_NDELAY, while causing the open() to return without waiting for
CARRIER, also causes read()'s to return without waiting for data.
Had you bothered to read the manual:
READ(2)...
	When attempting to read a file associated with a tty that has no
	data currently available:

		If O_NDELAY is set, the read will return -1 (or 0 on
			some systems... JB)
		If O_NDELAY is clear, the read will block until data
			becomes available.

The latter is the normal case.

FCNTL(2) explains how to turn certain file flags on and off...

Hope this helps.

John Buck
john@polyof.poly.edu
john@polygraf.bitnet
trixie!polyof!john  (UUCP)
Polytechnic University
Farmingdale, NY

michael@stb.UUCP (Michael) (02/08/89)

In article <7411@chinet.chi.il.us> les@chinet.chi.il.us (Leslie Mikesell) writes:
>In article <137@zebra.UUCP> vern@zebra.UUCP (Vernon C. Hoxie) writes:
>>
>>	I have been trying to write a test program for a Trailblazer.
>>It is connected to /dev/tty000.  The program opens this file with:
>>
>>	fd = open("/dev/tty000", O_RDWR | O_NDELAY);
>
>You probably need to use fcntl() to turn off the O_NDELAY before
>trying to use the port (set CLOCAL first if you need it).  Write()s
>don't wait for the hardware to be ready if you leave O_NDELAY
>set and strange things happen.  I have seen code that indicated that
>a close(open(/dev/ttywhatever,2) was needed to force the mode to
>changed.  Does anyone know which versions of unix require this?
>
>Les Mikesell

Does anyone know how to turn ON NDELAY for an already open file?
			Michael
: --- 
: Michael Gersten			 uunet.uu.net!stb!michael
:					crash!gryphon!denwa!stb!michael
: Coff Coff <=== Stop smoking.

ditto@cbmvax.UUCP (Michael "Ford" Ditto) (02/09/89)

In article <10652@stb.UUCP> michael@stb.UUCP (Michael) writes:
>Does anyone know how to turn ON NDELAY for an already open file?

Use fcntl(2):

	int oldmode = fcntl(fd, F_GETFL);
	if (oldmode == -1)
	    perror("fcntl(F_GETFL)");
	else
	    if (fcntl(fd, F_SETFL, oldmode|O_NDELAY) == -1)
		perror("fcntl(F_SETFL)");

Or, if you're not a fan of error checking:

	fcntl(fd, F_SETFL, fcntl(fd, F_GETFL)|O_NDELAY);

-- 
					-=] Ford [=-

"The number of Unix installations	(In Real Life:  Mike Ditto)
has grown to 10, with more expected."	ford@kenobi.cts.com
- The Unix Programmer's Manual,		...!sdcsvax!crash!elgar!ford
  2nd Edition, June, 1972.		ditto@cbmvax.commodore.com

lenny@icus.islp.ny.us (Lenny Tropiano) (02/10/89)

In article <10652@stb.UUCP> michael@stb.UUCP (Michael) writes:
|>In article <7411@chinet.chi.il.us> les@chinet.chi.il.us (Leslie Mikesell) writes:
|>>In article <137@zebra.UUCP> vern@zebra.UUCP (Vernon C. Hoxie) writes:
|>>>
|>>>	I have been trying to write a test program for a Trailblazer.
|>>>It is connected to /dev/tty000.  The program opens this file with:
|>>>
|>>>	fd = open("/dev/tty000", O_RDWR | O_NDELAY);
|>>
|>>You probably need to use fcntl() to turn off the O_NDELAY before
...
|>
|>Does anyone know how to turn ON NDELAY for an already open file?
|>			Michael
...

Use the fcntl(2) system call.

#include <fcntl.h>

int	oflags;

	/* assume a file descriptor (fd) is already open and in use */
	...
	fcntl(fd, F_GETFL, &oflags);	/* get the current open flags */
				/* set the flags to have O_NDELAY too */
	fcntl(fd, F_SETFL, oflags | O_NDELAY);	

I assume that would do it for ya...

-Lenny
-- 
Lenny Tropiano             ICUS Software Systems         [w] +1 (516) 582-5525
lenny@icus.islp.ny.us      Telex; 154232428 ICUS         [h] +1 (516) 968-8576
{talcott,decuac,boulder,hombre,pacbell,sbcs}!icus!lenny  attmail!icus!lenny
        ICUS Software Systems -- PO Box 1; Islip Terrace, NY  11752

lenny@icus.islp.ny.us (Lenny Tropiano) (02/10/89)

In article <599@icus.islp.ny.us> lenny@icus.islp.ny.us (Lenny Tropiano) writes:
|>
|>Use the fcntl(2) system call.
|>
|>#include <fcntl.h>
|>
|>int	oflags;
|>
|>	/* assume a file descriptor (fd) is already open and in use */
|>	...
|>	fcntl(fd, F_GETFL, &oflags);	/* get the current open flags */
|>				/* set the flags to have O_NDELAY too */
|>	fcntl(fd, F_SETFL, oflags | O_NDELAY);	
|>
|>I assume that would do it for ya...
|>
I guess next time I should look in the manual first.  It's been a while 
since I did fcntl, and the "DIAGNOSTICS" section of the manual page fcntl(2)
says that the return value of F_GETFL is the file flags.  Therefore there is
*no* argument ...  Thanks Mike, you enlightened me again :-)  

	oflags = fcntl(fd, F_GETFL);
	if (oflags != -1)
		fcntl(fd, F_SETFL, oflags | O_NDELAY);	

-Lenny

-- 
Lenny Tropiano             ICUS Software Systems         [w] +1 (516) 582-5525
lenny@icus.islp.ny.us      Telex; 154232428 ICUS         [h] +1 (516) 968-8576
{talcott,decuac,boulder,hombre,pacbell,sbcs}!icus!lenny  attmail!icus!lenny
        ICUS Software Systems -- PO Box 1; Islip Terrace, NY  11752