This is the mail archive of the
ecos-patches@sources.redhat.com
mailing list for the eCos project.
Termios VMIN>0 fixes
- From: Jonathan Larmour <jlarmour at jifvik dot org>
- To: ecos-patches at sources dot redhat dot com
- Date: Fri, 14 Feb 2003 11:50:02 GMT
- Subject: Termios VMIN>0 fixes
Index: ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/io/serial/current/ChangeLog,v
retrieving revision 1.47
diff -u -5 -p -r1.47 ChangeLog
--- ChangeLog 10 Dec 2002 15:29:00 -0000 1.47
+++ ChangeLog 14 Feb 2003 11:50:00 -0000
@@ -1,5 +1,9 @@
+2003-02-14 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/common/termiostty.c: Support VMIN > 0 properly.
+
2002-12-10 Gary Thomas <gthomas@ecoscentric.com>
* src/common/tty.c (tty_write): Only return number of characters
in original string which were written - don't include any CR/LF
expansion characters.
Index: src/common/termiostty.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/io/serial/current/src/common/termiostty.c,v
retrieving revision 1.3
diff -u -5 -p -r1.3 termiostty.c
--- src/common/termiostty.c 23 May 2002 23:06:28 -0000 1.3
+++ src/common/termiostty.c 14 Feb 2003 11:50:01 -0000
@@ -7,10 +7,11 @@
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Jonathan Larmour
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
@@ -521,14 +522,11 @@ set_attr( struct termios *t, struct term
#endif
ICRNL|IGNBRK|IGNCR|IGNPAR|
INLCR|INPCK|ISTRIP|PARMRK );
ptermios->c_oflag &= ~(OPOST|ONLCR);
- ptermios->c_oflag |= t->c_oflag & ONLCR;
-#ifdef NOTYET
- ptermios->c_oflag |= t->c_oflag & OPOST;
-#endif
+ ptermios->c_oflag |= t->c_oflag & (OPOST|ONLCR);
ptermios->c_cflag &= ~(CLOCAL|CREAD|HUPCL);
ptermios->c_cflag |= t->c_cflag & (CLOCAL|CREAD|HUPCL);
ptermios->c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|ICANON|
@@ -597,36 +595,35 @@ static Cyg_ErrNo
termios_write(cyg_io_handle_t handle, const void *_buf, cyg_uint32 *len)
{
cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)handle;
struct termios_private_info *priv = (struct termios_private_info *)t->priv;
cyg_io_handle_t chan = (cyg_io_handle_t)priv->dev_handle;
- cyg_int32 size, bytes_successful, actually_written;
+ cyg_int32 xbufsize, input_bytes_read;
cyg_uint8 xbuf[WRITE_BUFSIZE];
cyg_uint8 *buf = (cyg_uint8 *)_buf;
Cyg_ErrNo res;
- size = 0;
- bytes_successful = 0;
- actually_written = 0;
- while (bytes_successful++ < *len) {
- xbuf[size] = *buf++;
- if ( (xbuf[size] == '\n') && (priv->termios.c_oflag & ONLCR) ) {
- xbuf[size] = '\r';
- }
- size++;
- if ((size == (WRITE_BUFSIZE-1)) ||
- (bytes_successful == *len)) {
+ xbufsize = input_bytes_read = 0;
+ while (input_bytes_read++ < *len) {
+ if ( (*buf == '\n') && (priv->termios.c_oflag & (OPOST|ONLCR)) ) {
+ xbuf[xbufsize++] = '\r';
+ }
+ xbuf[xbufsize++] = *buf;
+ if ((xbufsize >= (WRITE_BUFSIZE-1)) || (input_bytes_read == *len) ||
+ (*buf == '\n'))
+ {
+ cyg_int32 size = xbufsize;
res = cyg_io_write(chan, xbuf, &size);
if (res != ENOERR) {
- *len = actually_written;
+ *len = input_bytes_read - (xbufsize - size);
return res;
}
- actually_written += size;
- size = 0;
+ xbufsize = 0;
}
+ buf++;
}
- *len = actually_written;
+ // Everything sent, so *len is correct.
return ENOERR;
}
//==========================================================================
@@ -756,13 +753,12 @@ 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
- /* This is completely wrong:
- if ( size+1 >= t->c_cc[ VMIN ] )
- returnnow = true;*/
+ if ( t->c_cc[ VMIN ] && (size+1 >= t->c_cc[ VMIN ]) )
+ returnnow = true;
} // else
#ifdef CYGSEM_IO_SERIAL_TERMIOS_USE_SIGNALS
if ( (t->c_lflag & ISIG) && (t->c_cc[ VINTR ] == c) ) {
discardc = true;
@@ -791,11 +787,11 @@ termios_read(cyg_io_handle_t handle, voi
if (!discardc) {
buf[size++] = c;
if ( t->c_lflag & ECHO ) {
clen = 1;
// FIXME: what about error or non-blocking?
- cyg_io_write( chan, &c, &clen );
+ termios_write( handle, &c, &clen );
}
}
cyg_drv_mutex_unlock( &priv->lock );
} // while