2001-08-16 Mike Siers <mikes@poliac.com>

* libc/termios.c: Fix a bug in the termios implementation in
	the following scenario:
	  The General Terminal Interface document that me states that
	  if VMIN = 0 and VTIME = 0, then read() should return the minimum
	  of two values:
  		a) number of bytes available
  		b) number of bytes requested (I assume from the read call)

	  The current implementation of the fillBufferQueue() in termios.c is
	  always return 1 character with these setting values.  I know the
	  termios buffer has more than one character available and my read()
	  call is requesting 1024 bytes.
This commit is contained in:
Joel Sherrill
2001-08-16 20:58:14 +00:00
parent b9ff276c35
commit c0af4e4799
3 changed files with 126 additions and 0 deletions

View File

@@ -190,6 +190,14 @@ rtems_termios_open (
rtems_semaphore_release (rtems_termios_ttyMutex);
return RTEMS_NO_MEMORY;
}
/*
* Initialize wakeup callbacks
*/
tty->tty_snd.sw_pfn = NULL;
tty->tty_snd.sw_arg = NULL;
tty->tty_rcv.sw_pfn = NULL;
tty->tty_rcv.sw_arg = NULL;
tty->tty_rcvwakeup = 0;
/*
* link tty
*/
@@ -497,6 +505,7 @@ rtems_termios_ioctl (void *arg)
{
rtems_libio_ioctl_args_t *args = arg;
struct rtems_termios_tty *tty = args->iop->data1;
struct ttywakeup *wakeup = (struct ttywakeup *)args->buffer;
rtems_status_code sc;
args->ioctl_return = 0;
@@ -561,6 +570,14 @@ rtems_termios_ioctl (void *arg)
drainOutput (tty);
break;
case RTEMS_IO_SNDWAKEUP:
tty->tty_snd = *wakeup;
break;
case RTEMS_IO_RCVWAKEUP:
tty->tty_rcv = *wakeup;
break;
/*
* FIXME: add various ioctl code handlers
*/
@@ -1059,6 +1076,7 @@ rtems_termios_read (void *arg)
return sc;
if (linesw[tty->t_line].l_read != NULL) {
sc = linesw[tty->t_line].l_read(tty,args);
tty->tty_rcvwakeup = 0;
rtems_semaphore_release (tty->isem);
return sc;
}
@@ -1078,6 +1096,7 @@ rtems_termios_read (void *arg)
count--;
}
args->bytes_moved = args->count - count;
tty->tty_rcvwakeup = 0;
rtems_semaphore_release (tty->isem);
return sc;
}
@@ -1116,6 +1135,14 @@ rtems_termios_enqueue_raw_characters (void *ttyp, char *buf, int len)
c = *buf++;
linesw[tty->t_line].l_rint(c,tty);
}
/*
* check to see if rcv wakeup callback was set
*/
if (( !tty->tty_rcvwakeup ) && ( tty->tty_rcv.sw_pfn != NULL )) {
(*tty->tty_rcv.sw_pfn)(&tty->termios, tty->tty_rcv.sw_arg);
tty->tty_rcvwakeup = 1;
}
return 0;
}
@@ -1201,6 +1228,14 @@ rtems_termios_enqueue_raw_characters (void *ttyp, char *buf, int len)
else {
tty->rawInBuf.theBuf[newTail] = c;
tty->rawInBuf.Tail = newTail;
/*
* check to see if rcv wakeup callback was set
*/
if (( !tty->tty_rcvwakeup ) && ( tty->tty_rcv.sw_pfn != NULL )) {
(*tty->tty_rcv.sw_pfn)(&tty->termios, tty->tty_rcv.sw_arg);
tty->tty_rcvwakeup = 1;
}
}
}
}
@@ -1288,6 +1323,13 @@ rtems_termios_refill_transmitter (struct rtems_termios_tty *tty)
*/
tty->rawOutBufState = rob_idle;
nToSend = 0;
/*
* check to see if snd wakeup callback was set
*/
if ( tty->tty_snd.sw_pfn != NULL) {
(*tty->tty_snd.sw_pfn)(&tty->termios, tty->tty_snd.sw_arg);
}
}
/* check, whether output should stop due to received XOFF */
else if ((tty->flow_ctrl & (FL_MDXON | FL_ORCVXOF))

View File

@@ -190,6 +190,14 @@ rtems_termios_open (
rtems_semaphore_release (rtems_termios_ttyMutex);
return RTEMS_NO_MEMORY;
}
/*
* Initialize wakeup callbacks
*/
tty->tty_snd.sw_pfn = NULL;
tty->tty_snd.sw_arg = NULL;
tty->tty_rcv.sw_pfn = NULL;
tty->tty_rcv.sw_arg = NULL;
tty->tty_rcvwakeup = 0;
/*
* link tty
*/
@@ -497,6 +505,7 @@ rtems_termios_ioctl (void *arg)
{
rtems_libio_ioctl_args_t *args = arg;
struct rtems_termios_tty *tty = args->iop->data1;
struct ttywakeup *wakeup = (struct ttywakeup *)args->buffer;
rtems_status_code sc;
args->ioctl_return = 0;
@@ -561,6 +570,14 @@ rtems_termios_ioctl (void *arg)
drainOutput (tty);
break;
case RTEMS_IO_SNDWAKEUP:
tty->tty_snd = *wakeup;
break;
case RTEMS_IO_RCVWAKEUP:
tty->tty_rcv = *wakeup;
break;
/*
* FIXME: add various ioctl code handlers
*/
@@ -1059,6 +1076,7 @@ rtems_termios_read (void *arg)
return sc;
if (linesw[tty->t_line].l_read != NULL) {
sc = linesw[tty->t_line].l_read(tty,args);
tty->tty_rcvwakeup = 0;
rtems_semaphore_release (tty->isem);
return sc;
}
@@ -1078,6 +1096,7 @@ rtems_termios_read (void *arg)
count--;
}
args->bytes_moved = args->count - count;
tty->tty_rcvwakeup = 0;
rtems_semaphore_release (tty->isem);
return sc;
}
@@ -1116,6 +1135,14 @@ rtems_termios_enqueue_raw_characters (void *ttyp, char *buf, int len)
c = *buf++;
linesw[tty->t_line].l_rint(c,tty);
}
/*
* check to see if rcv wakeup callback was set
*/
if (( !tty->tty_rcvwakeup ) && ( tty->tty_rcv.sw_pfn != NULL )) {
(*tty->tty_rcv.sw_pfn)(&tty->termios, tty->tty_rcv.sw_arg);
tty->tty_rcvwakeup = 1;
}
return 0;
}
@@ -1201,6 +1228,14 @@ rtems_termios_enqueue_raw_characters (void *ttyp, char *buf, int len)
else {
tty->rawInBuf.theBuf[newTail] = c;
tty->rawInBuf.Tail = newTail;
/*
* check to see if rcv wakeup callback was set
*/
if (( !tty->tty_rcvwakeup ) && ( tty->tty_rcv.sw_pfn != NULL )) {
(*tty->tty_rcv.sw_pfn)(&tty->termios, tty->tty_rcv.sw_arg);
tty->tty_rcvwakeup = 1;
}
}
}
}
@@ -1288,6 +1323,13 @@ rtems_termios_refill_transmitter (struct rtems_termios_tty *tty)
*/
tty->rawOutBufState = rob_idle;
nToSend = 0;
/*
* check to see if snd wakeup callback was set
*/
if ( tty->tty_snd.sw_pfn != NULL) {
(*tty->tty_snd.sw_pfn)(&tty->termios, tty->tty_snd.sw_arg);
}
}
/* check, whether output should stop due to received XOFF */
else if ((tty->flow_ctrl & (FL_MDXON | FL_ORCVXOF))

View File

@@ -190,6 +190,14 @@ rtems_termios_open (
rtems_semaphore_release (rtems_termios_ttyMutex);
return RTEMS_NO_MEMORY;
}
/*
* Initialize wakeup callbacks
*/
tty->tty_snd.sw_pfn = NULL;
tty->tty_snd.sw_arg = NULL;
tty->tty_rcv.sw_pfn = NULL;
tty->tty_rcv.sw_arg = NULL;
tty->tty_rcvwakeup = 0;
/*
* link tty
*/
@@ -497,6 +505,7 @@ rtems_termios_ioctl (void *arg)
{
rtems_libio_ioctl_args_t *args = arg;
struct rtems_termios_tty *tty = args->iop->data1;
struct ttywakeup *wakeup = (struct ttywakeup *)args->buffer;
rtems_status_code sc;
args->ioctl_return = 0;
@@ -561,6 +570,14 @@ rtems_termios_ioctl (void *arg)
drainOutput (tty);
break;
case RTEMS_IO_SNDWAKEUP:
tty->tty_snd = *wakeup;
break;
case RTEMS_IO_RCVWAKEUP:
tty->tty_rcv = *wakeup;
break;
/*
* FIXME: add various ioctl code handlers
*/
@@ -1059,6 +1076,7 @@ rtems_termios_read (void *arg)
return sc;
if (linesw[tty->t_line].l_read != NULL) {
sc = linesw[tty->t_line].l_read(tty,args);
tty->tty_rcvwakeup = 0;
rtems_semaphore_release (tty->isem);
return sc;
}
@@ -1078,6 +1096,7 @@ rtems_termios_read (void *arg)
count--;
}
args->bytes_moved = args->count - count;
tty->tty_rcvwakeup = 0;
rtems_semaphore_release (tty->isem);
return sc;
}
@@ -1116,6 +1135,14 @@ rtems_termios_enqueue_raw_characters (void *ttyp, char *buf, int len)
c = *buf++;
linesw[tty->t_line].l_rint(c,tty);
}
/*
* check to see if rcv wakeup callback was set
*/
if (( !tty->tty_rcvwakeup ) && ( tty->tty_rcv.sw_pfn != NULL )) {
(*tty->tty_rcv.sw_pfn)(&tty->termios, tty->tty_rcv.sw_arg);
tty->tty_rcvwakeup = 1;
}
return 0;
}
@@ -1201,6 +1228,14 @@ rtems_termios_enqueue_raw_characters (void *ttyp, char *buf, int len)
else {
tty->rawInBuf.theBuf[newTail] = c;
tty->rawInBuf.Tail = newTail;
/*
* check to see if rcv wakeup callback was set
*/
if (( !tty->tty_rcvwakeup ) && ( tty->tty_rcv.sw_pfn != NULL )) {
(*tty->tty_rcv.sw_pfn)(&tty->termios, tty->tty_rcv.sw_arg);
tty->tty_rcvwakeup = 1;
}
}
}
}
@@ -1288,6 +1323,13 @@ rtems_termios_refill_transmitter (struct rtems_termios_tty *tty)
*/
tty->rawOutBufState = rob_idle;
nToSend = 0;
/*
* check to see if snd wakeup callback was set
*/
if ( tty->tty_snd.sw_pfn != NULL) {
(*tty->tty_snd.sw_pfn)(&tty->termios, tty->tty_snd.sw_arg);
}
}
/* check, whether output should stop due to received XOFF */
else if ((tty->flow_ctrl & (FL_MDXON | FL_ORCVXOF))