[comp.sys.sgi] Timeout on serial port read

root@MCIRPS2.MED.NYU.EDU (05/03/90)

I am trying to set the ioctl call so that a raw read from a
serial port will time out after a few seconds. No matter what I
set the TIME value for in the control structure, the machine
still hangs waiting for characters. What am I doing wrong, if anything.

Code follows:
---
    new_settings.c_iflag = IGNBRK | IGNPAR;
    new_settings.c_oflag = NULL;
    new_settings.c_cflag = B9600 | CS8 | CREAD | CLOCAL;
    new_settings.c_lflag = ICANON;
    new_settings.c_line  = NULL;
    new_settings.c_cc[0] = NULL;
    new_settings.c_cc[1] = NULL;
    new_settings.c_cc[2] = NULL;
    new_settings.c_cc[3] = NULL;
    new_settings.c_cc[4] = NULL;
    new_settings.c_cc[5] = TIMEOUT;

    ioctl(fd, TCSETA, &new_settings);
-----

A read that has timed out should return with a value of 0. Right ?

dan.
--
+-----------------------------------------------------------------------------+
| karron@nyu.edu                          Dan Karron                          |
| . . . . . . . . . . . . . .             New York University Medical Center  |
| 560 First Avenue           \ \    Pager <1> (212) 397 9330                  |
| New York, New York 10016    \**\        <2> 10896   <3> <your-number-here>  |
| (212) 340 5210               \**\__________________________________________ |
+-----------------------------------------------------------------------------+

moss@BRL.MIL ("Gary S. Moss", VLD/VMB) (05/03/90)

< I am trying to set the ioctl call so that a raw read from a
< serial port will time out after a few seconds. No matter what I
< set the TIME value for in the control structure, the machine
< still hangs waiting for characters. What am I doing wrong, if anything.
<     new_settings.c_iflag = IGNBRK | IGNPAR;
<     new_settings.c_oflag = NULL;
<     new_settings.c_cflag = B9600 | CS8 | CREAD | CLOCAL;
<     new_settings.c_lflag = ICANON;
<     new_settings.c_line  = NULL;
<     new_settings.c_cc[0] = NULL;
<     new_settings.c_cc[1] = NULL;
<     new_settings.c_cc[2] = NULL;
<     new_settings.c_cc[3] = NULL;
<     new_settings.c_cc[4] = NULL;
<     new_settings.c_cc[5] = TIMEOUT;


For one thing, if you set ICANON, you will not get RAW input; do the
following instead.  Also, if you want to get 1 character at a time
without blocking, set the VMIN (element 4) of c_cc to 1, and set
TIMEOUT to 0.

new_settings.c_lflag &= ~ICANON;	/* Canonical input OFF. */
new_settings.c_cc[VMIN] = 1;
new_settings.c_cc[VTIME] = 0;

Other indices for c_cc should be written using their mnemonics as defined
in /usr/include/sys/termio.h for portability if nothing else.

CAVIAT: the VMIN/VTIME mechanism is intended for reading DMA bursts, and
does not really work for general timeouts.  What you probably need to
use poll(2) or select(2) rather than ioctl(2) (if I understand your
question).

root@sgzh.uucp (Bruno Pape) (05/04/90)

In article <9005030929.aa08086@VMB.BRL.MIL> moss@BRL.MIL ("Gary S. Moss", VLD/VMB) writes:
>< I am trying to set the ioctl call so that a raw read from a
>< serial port will time out after a few seconds. No matter what I
>< set the TIME value for in the control structure, the machine
>< still hangs waiting for characters. What am I doing wrong, if anything.
><
><     new_settings.c_iflag = IGNBRK | IGNPAR;
><     new_settings.c_oflag = NULL;
><     new_settings.c_cflag = B9600 | CS8 | CREAD | CLOCAL;
><     new_settings.c_lflag = ICANON;
><     new_settings.c_line  = NULL;
><     new_settings.c_cc[0] = NULL;
><     new_settings.c_cc[1] = NULL;
><     new_settings.c_cc[2] = NULL;
><     new_settings.c_cc[3] = NULL;
><     new_settings.c_cc[4] = NULL;
><     new_settings.c_cc[5] = TIMEOUT;
>
>
>For one thing, if you set ICANON, you will not get RAW input; do the
>following instead.  Also, if you want to get 1 character at a time
>without blocking, set the VMIN (element 4) of c_cc to 1, and set
>TIMEOUT to 0.
>
>new_settings.c_lflag &= ~ICANON;	/* Canonical input OFF. */
>new_settings.c_cc[VMIN] = 1;
>new_settings.c_cc[VTIME] = 0;
>
>Other indices for c_cc should be written using their mnemonics as defined
>in /usr/include/sys/termio.h for portability if nothing else.
>
>CAVIAT: the VMIN/VTIME mechanism is intended for reading DMA bursts, and
>does not really work for general timeouts.  What you probably need to
>use poll(2) or select(2) rather than ioctl(2) (if I understand your
>question).

While the above is along the right path it too will hang forever waiting
for one character.  If he wants it to time out at some point I believe
the following would work better.  Replace delay with the number of seconds
you want it to wait before timing out.

		tty.c_iflag	= 0;
		tty.c_oflag	= 0;
		tty.c_cflag	= B9600 | CS8 | CREAD;
		tty.c_lflag	= 0;
		tty.c_cc[VTIME]	= delay;
		tty.c_cc[VMIN]	= 0;
		if ( ioctl( descriptor, TCSETA, &tty ) < 0 ) perror("ioctl");

Bruno

With 999999 possiblities between "cooked" and "raw" you know you're not going
to have any fun.  Boo hoo.

vjs@rhyolite.wpd.sgi.com (Vernon Schryver) (05/06/90)

The VTIME parameter is in units of tenths of seconds, not seconds.

The FIONBIO ioctl works on IRIX TTY's, to give "non-block" I/O.

Using select(2) is almost certainly the best solution.



Vernon Schryver
vjs@sgi.com

root@sgzh.uucp (Bruno Pape) (05/08/90)

In article <59374@sgi.sgi.com> vjs@sgi.com (Vernon Schryver) writes:
>
>The VTIME parameter is in units of tenths of seconds, not seconds.
>
>The FIONBIO ioctl works on IRIX TTY's, to give "non-block" I/O.
>
>Using select(2) is almost certainly the best solution.
>

Opps, tenths of a seconds it is.

Non-blocking I/O and non-blocking with a delay are slightly different.

Select seems like overkill for simple tty I/O.  Why is it almost
certainly the best solution?  To all non-blocking tty I/O problems?

Just wondering,

Bruno