This is the mail archive of the
ecos-patches@sources.redhat.com
mailing list for the eCos project.
termios - bad behaviour with VMIN
- From: Gary Thomas <gary at mlbassoc dot com>
- To: eCos patches <ecos-patches at sources dot redhat dot com>
- Date: 09 Mar 2003 09:07:41 -0700
- Subject: termios - bad behaviour with VMIN
According to my Linux manual page (I know it's not the POSIX
gospel, but it's what I have):
These symbolic subscript values are all different, except that VTIME, VMIN may have
the same value as VEOL, VEOF, respectively. (In non-canonical mode the special
character meaning is replaced by the timeout meaning. MIN represents the minimum
number of characters that should be received to satisfy the read. TIME is a
decisecond-valued timer. When both are set, a read will wait until at least one
character has been received, and then return as soon as either MIN characters have
been received or time TIME has passed since the last character was received. If
only MIN is set, the read will not return before MIN characters have been received.
If only TIME is set, the read will return as soon as either at least one character
has been received, or the timer times out. If neither is set, the read will return
immediately, only giving the currently already available characters.)
which tells me that if I have a termios device in non-canonical
mode and I set VMIN, then a read to that device will not be
satisfied until at least VMIN characters arrive. Currently,
this does not happen; it returns 0, with no error, if there
are no characters available.
This patch fixes it and gives what I think is proper behaviour:
Index: io/serial/current/src/common/termiostty.c
===================================================================
RCS file: /misc/cvsfiles/ecos/packages/io/serial/current/src/common/termiostty.c,v
retrieving revision 1.4
diff -u -5 -p -r1.4 termiostty.c
--- io/serial/current/src/common/termiostty.c 14 Feb 2003 11:50:12 -0000 1.4
+++ io/serial/current/src/common/termiostty.c 9 Mar 2003 15:39:58 -0000
@@ -659,11 +659,18 @@ termios_read(cyg_io_handle_t handle, voi
cyg_uint32 dbc_len = sizeof( dev_buf_conf );
res = cyg_io_get_config( chan,
CYG_IO_GET_CONFIG_SERIAL_BUFFER_INFO,
&dev_buf_conf, &dbc_len );
CYG_ASSERT( res == ENOERR, "Query buffer status failed!" );
- *len = *len < dev_buf_conf.rx_count ? *len : dev_buf_conf.rx_count;
+ if (dev_buf_conf.rx_count > 0) {
+ // Adjust length to be max characters currently available
+ *len = *len < dev_buf_conf.rx_count ? *len : dev_buf_conf.rx_count;
+ } else if (t->c_cc[VMIN] == 0) {
+ // No chars available - don't block
+ *len = 0;
+ return ENOERR;
+ }
} // if
while (!returnnow && size < *len) {
clen = 1;
discardc = false;
@@ -752,14 +759,11 @@ termios_read(cyg_io_handle_t handle, voi
}
if ( t->c_iflag & INLCR )
c = '\r';
returnnow = true; // FIXME: true even for INLCR?
} // else if
- } else { // non-canonical mode
- if ( t->c_cc[ VMIN ] && (size+1 >= t->c_cc[ VMIN ]) )
- returnnow = true;
- } // else
+ } // if
#ifdef CYGSEM_IO_SERIAL_TERMIOS_USE_SIGNALS
if ( (t->c_lflag & ISIG) && (t->c_cc[ VINTR ] == c) ) {
discardc = true;
if ( 0 == (t->c_lflag & NOFLSH) )
@@ -789,10 +793,16 @@ termios_read(cyg_io_handle_t handle, voi
if ( t->c_lflag & ECHO ) {
clen = 1;
// FIXME: what about error or non-blocking?
termios_write( handle, &c, &clen );
}
+ }
+
+ if ( (t->c_lflag & ICANON) == 0 ) {
+ // Check to see if read has been satisfied
+ if ( t->c_cc[ VMIN ] && (size >= t->c_cc[ VMIN ]) )
+ returnnow = true;
}
cyg_drv_mutex_unlock( &priv->lock );
} // while
*len = size;
Basically, I think the test for VMIN is in the wrong place and also a
little correct. With this change in place, the code I'm working with
(a nice, standard, portable program) behaves the same on Linux and
eCos. Comments?
--
------------------------------------------------------------
Gary Thomas |
MLB Associates | Consulting for the
+1 (970) 229-1963 | Embedded world
http://www.mlbassoc.com/ |
email: <gary at mlbassoc dot com> |
gpg: http://www.chez-thomas.org/gary/gpg_key.asc
------------------------------------------------------------