+2003-09-18 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler_tty.cc (fhandler_pty_master::process_slave_output):
+ Handle buf == NULL as flushing the buffer.
+ (fhandler_tty_slave::read): Handle ptr == NULL as flushing the buffer.
+ (fhandler_tty_slave::tcflush): Implement input queue flushing by
+ calling read with NULL buffer.
+ (fhandler_pty_master::tcflush): Ditto, calling process_slave_output.
+ * termios.cc (tcflush): Check for legal `queue' value. Return
+ EINVAL otherwise.
+
2003-09-16 Brian Ford <ford@vss.fsi.com>
* syscalls.cc (gethostid): Add lpFreeBytesAvailable argument to
\r\n conversion. Note that we already checked for FLUSHO and
output_stopped at the time that we read the character, so we
don't check again here. */
- buf[0] = '\n';
+ if (buf)
+ buf[0] = '\n';
need_nl = 0;
rc = 1;
goto out;
break;
if (hit_eof ())
goto out;
+ /* DISCARD (FLUSHO) and tcflush can finish here. */
+ if (n == 0 && (get_ttyp ()->ti.c_lflag & FLUSHO || !buf))
+ goto out;
if (n == 0 && is_nonblocking ())
{
set_errno (EAGAIN);
if (output_done_event != NULL)
SetEvent (output_done_event);
- if (get_ttyp ()->ti.c_lflag & FLUSHO)
+ if (get_ttyp ()->ti.c_lflag & FLUSHO || !buf)
continue;
char *optr;
termios_printf ("read(%x, %d) handle %p", ptr, len, get_handle ());
- if ((get_ttyp ()->ti.c_lflag & ICANON))
+ if (!ptr) /* Indicating tcflush(). */
+ time_to_wait = 0;
+ else if ((get_ttyp ()->ti.c_lflag & ICANON))
time_to_wait = INFINITE;
else
{
w4[0] = signal_arrived;
w4[1] = input_available_event;
- DWORD waiter = INFINITE;
+ DWORD waiter = !ptr ? 0 : INFINITE;
while (len)
{
rc = WaitForMultipleObjects (2, w4, FALSE, waiter);
bytes_in_pipe = 0;
}
- if (!vmin && !time_to_wait)
+ /* On first peek determine no. of bytes to flush. */
+ if (!ptr && len == UINT_MAX)
+ len = (size_t) bytes_in_pipe;
+
+ if (ptr && !vmin && !time_to_wait)
{
ReleaseMutex (input_mutex);
len = (size_t) bytes_in_pipe;
readlen = min (bytes_in_pipe, min (len, sizeof (buf)));
- if (vmin && readlen > (unsigned) vmin)
+ if (ptr && vmin && readlen > (unsigned) vmin)
readlen = vmin;
DWORD n = 0;
{
len -= n;
totalread += n;
- memcpy (ptr, buf, n);
- ptr = (char *) ptr + n;
+ if (ptr)
+ {
+ memcpy (ptr, buf, n);
+ ptr = (char *) ptr + n;
+ }
}
}
ReleaseMutex (input_mutex);
+ if (!ptr)
+ {
+ if (!bytes_in_pipe)
+ break;
+ continue;
+ }
+
if (get_ttyp ()->read_retval < 0) // read error
{
set_errno (-get_ttyp ()->read_retval);
}
int
-fhandler_tty_slave::tcflush (int)
+fhandler_tty_slave::tcflush (int queue)
{
- return 0;
+ int ret = 0;
+
+ termios_printf ("tcflush(%d) handle %p", queue, get_handle ());
+
+ if (queue == TCIFLUSH || queue == TCIOFLUSH)
+ {
+ size_t len = UINT_MAX;
+ read (NULL, len);
+ ret = len >= 0;
+ }
+ if (queue == TCOFLUSH || queue == TCIOFLUSH)
+ {
+ /* do nothing for now. */
+ }
+
+ termios_printf ("%d=tcflush(%d)", ret, queue);
+ return ret;
}
int
}
int
-fhandler_pty_master::tcflush (int)
+fhandler_pty_master::tcflush (int queue)
{
- return 0;
+ int ret = 0;
+
+ termios_printf ("tcflush(%d) handle %p", queue, get_handle ());
+
+ if (queue == TCIFLUSH || queue == TCIOFLUSH)
+ ret = process_slave_output (NULL, OUT_BUFFER_SIZE, 0);
+ else if (queue == TCIFLUSH || queue == TCIOFLUSH)
+ {
+ /* do nothing for now. */
+ }
+
+ termios_printf ("%d=tcflush(%d)", ret, queue);
+ return ret;
}
int