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); rtems_semaphore_release (rtems_termios_ttyMutex);
return RTEMS_NO_MEMORY; 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 * link tty
*/ */
@@ -497,6 +505,7 @@ rtems_termios_ioctl (void *arg)
{ {
rtems_libio_ioctl_args_t *args = arg; rtems_libio_ioctl_args_t *args = arg;
struct rtems_termios_tty *tty = args->iop->data1; struct rtems_termios_tty *tty = args->iop->data1;
struct ttywakeup *wakeup = (struct ttywakeup *)args->buffer;
rtems_status_code sc; rtems_status_code sc;
args->ioctl_return = 0; args->ioctl_return = 0;
@@ -561,6 +570,14 @@ rtems_termios_ioctl (void *arg)
drainOutput (tty); drainOutput (tty);
break; 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 * FIXME: add various ioctl code handlers
*/ */
@@ -1059,6 +1076,7 @@ rtems_termios_read (void *arg)
return sc; return sc;
if (linesw[tty->t_line].l_read != NULL) { if (linesw[tty->t_line].l_read != NULL) {
sc = linesw[tty->t_line].l_read(tty,args); sc = linesw[tty->t_line].l_read(tty,args);
tty->tty_rcvwakeup = 0;
rtems_semaphore_release (tty->isem); rtems_semaphore_release (tty->isem);
return sc; return sc;
} }
@@ -1078,6 +1096,7 @@ rtems_termios_read (void *arg)
count--; count--;
} }
args->bytes_moved = args->count - count; args->bytes_moved = args->count - count;
tty->tty_rcvwakeup = 0;
rtems_semaphore_release (tty->isem); rtems_semaphore_release (tty->isem);
return sc; return sc;
} }
@@ -1116,6 +1135,14 @@ rtems_termios_enqueue_raw_characters (void *ttyp, char *buf, int len)
c = *buf++; c = *buf++;
linesw[tty->t_line].l_rint(c,tty); 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; return 0;
} }
@@ -1201,6 +1228,14 @@ rtems_termios_enqueue_raw_characters (void *ttyp, char *buf, int len)
else { else {
tty->rawInBuf.theBuf[newTail] = c; tty->rawInBuf.theBuf[newTail] = c;
tty->rawInBuf.Tail = newTail; 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; tty->rawOutBufState = rob_idle;
nToSend = 0; 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 */ /* check, whether output should stop due to received XOFF */
else if ((tty->flow_ctrl & (FL_MDXON | FL_ORCVXOF)) else if ((tty->flow_ctrl & (FL_MDXON | FL_ORCVXOF))

View File

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

View File

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