Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2000-03-12 09:29:54 +0300
committerChristopher Faylor <me@cgf.cx>2000-03-12 09:29:54 +0300
commit3f0b4935404f01ab19ecab559a3201d4bb1ec5ca (patch)
treecc60ec7a05e57f8a4049bff0959bdd3ae24ae04c /winsup/cygwin/fhandler_tty.cc
parent774ea162116fcb08278c5efbe287848f5b5dd431 (diff)
* fhandler.cc (fhandler_base::get_readahead_into_buffer): New function.
* fhandler.h: Declare new function. Add extra argument to process_slave_output. * fhandler_console.cc (fhandler_console::read): Move read ahead code to new function. * fhandler_tty.cc (fhandler_pty_master::process_slave_output): Move common code here. (fhandler_tty_slave::read): Understand readahead. (fhandler_pty_master::read): Move code to process_slave_output. * select.cc (peek_pipe): Avoid performing certain checks when non-read and on inappropriate fh types.
Diffstat (limited to 'winsup/cygwin/fhandler_tty.cc')
-rw-r--r--winsup/cygwin/fhandler_tty.cc130
1 files changed, 60 insertions, 70 deletions
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 14da2bbbd..0cc9b5284 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -214,10 +214,10 @@ fhandler_pty_master::hit_eof ()
/* Process tty output requests */
int
-fhandler_pty_master::process_slave_output (char *buf, size_t len)
+fhandler_pty_master::process_slave_output (char *buf, size_t len, int pktmode_on)
{
size_t rlen;
- char outbuf[OUT_BUFFER_SIZE];
+ char outbuf[OUT_BUFFER_SIZE + 1];
DWORD n;
int column = 0;
int rc = 0;
@@ -225,20 +225,20 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len)
if (len == 0)
goto out;
- for (;;)
+ if (need_nl)
{
- if (neednl_)
- {
- /* We need to return a left over \n character, resulting from
- \r\n conversion. Note that we already checked for FLUSHO and
- OutputStopped at the time that we read the character, so we
- don't check again here. */
- buf[0] = '\n';
- neednl_ = 0;
- rc = 1;
- break;
- }
+ /* We need to return a left over \n character, resulting from
+ \r\n conversion. Note that we already checked for FLUSHO and
+ OutputStopped at the time that we read the character, so we
+ don't check again here. */
+ buf[0] = '\n';
+ need_nl = 0;
+ goto out;
+ }
+
+ for (;;)
+ {
/* Set RLEN to the number of bytes to read from the pipe. */
rlen = len;
if (get_ttyp ()->ti.c_oflag & OPOST && get_ttyp ()->ti.c_oflag & ONLCR)
@@ -254,25 +254,35 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len)
HANDLE handle = get_io_handle ();
- /* Doing a busy wait like this is quite inefficient, but nothing
- else seems to work completely. Windows should provide some sort
- of overlapped I/O for pipes, or something, but it doesn't. */
- while (1)
+ n = 0; // get_readahead_into_buffer (outbuf, len);
+ if (!n)
{
- DWORD avail;
- if (!PeekNamedPipe (handle, NULL, 0, NULL, &avail, NULL))
+ /* Doing a busy wait like this is quite inefficient, but nothing
+ else seems to work completely. Windows should provide some sort
+ of overlapped I/O for pipes, or something, but it doesn't. */
+ while (1)
+ {
+ if (!PeekNamedPipe (handle, NULL, 0, NULL, &n, NULL))
+ goto err;
+ if (n > 0)
+ break;
+ if (hit_eof ())
+ goto out;
+ if (n == 0 && (get_flags () & (O_NONBLOCK | O_NDELAY)) != 0)
+ {
+ set_errno (EAGAIN);
+ rc = -1;
+ break;
+ }
+
+ Sleep (10);
+ }
+
+ if (ReadFile (handle, outbuf, rlen, &n, NULL) == FALSE)
goto err;
- if (avail > 0)
- break;
- if (hit_eof ())
- goto out;
- Sleep (10);
}
- if (ReadFile (handle, outbuf, rlen, &n, NULL) == FALSE)
- goto err;
-
- termios_printf ("rlen %u", n);
+ termios_printf ("bytes read %u", n);
if (get_ttyp ()->ti.c_lflag & FLUSHO)
{
@@ -289,14 +299,19 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len)
termios_printf ("done waiting for restart_output_event");
}
+ char *optr;
+ optr = buf;
+ if (pktmode_on)
+ *optr++ = TIOCPKT_DATA;
+
if (!(get_ttyp ()->ti.c_oflag & OPOST)) // post-process output
{
- memcpy (buf, outbuf, n);
- rc = n;
+ memcpy (optr, outbuf, n);
+ optr += n;
}
else // raw output mode
{
- char *iptr = outbuf, *optr = buf;
+ char *iptr = outbuf;
while (n--)
{
@@ -332,16 +347,16 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len)
doing \r\n expansion. */
if (optr - buf >= (int) len)
{
- neednl_ = 1;
if (*iptr != '\n' || n != 0)
system_printf ("internal error: %d unexpected characters", n);
+ need_nl = 1;
break;
}
*optr++ = *iptr++;
}
- rc = optr - buf;
}
+ rc = optr - buf;
break;
err:
@@ -364,11 +379,10 @@ static DWORD WINAPI
process_output (void *)
{
char buf[OUT_BUFFER_SIZE*2];
- int n;
- while (1)
+ for (;;)
{
- n = tty_master->process_slave_output (buf, OUT_BUFFER_SIZE);
+ int n = tty_master->process_slave_output (buf, OUT_BUFFER_SIZE, 0);
if (n < 0)
{
termios_printf ("ReadFile %E");
@@ -592,14 +606,18 @@ fhandler_tty_slave::read (void *ptr, size_t len)
while (len)
{
+ size_t readlen = min ((unsigned) vmin, min (len, sizeof (buf)));
termios_printf ("reading %d bytes (vtime %d)",
min ((unsigned) vmin, min (len, sizeof (buf))), vtime);
- if (ReadFile (get_handle (), (unsigned *) buf,
- min ((unsigned) vmin, min (len, sizeof (buf))), &n, NULL) == FALSE)
+
+ n = get_readahead_into_buffer (buf, readlen);
+
+ if (!n && ReadFile (get_handle (), buf, readlen, &n, NULL) == FALSE)
{
termios_printf ("read failed, %E");
_raise (SIGHUP);
}
+
if (get_ttyp ()->read_retval < 0) // read error
{
set_errno (-get_ttyp ()->read_retval);
@@ -827,7 +845,7 @@ fhandler_pty_master::fhandler_pty_master (const char *name, DWORD devtype, int u
ioctl_request_event = NULL;
ioctl_done_event = NULL;
restart_output_event = NULL;
- pktmode = neednl_ = 0;
+ pktmode = need_nl = 0;
inuse = NULL;
}
@@ -908,39 +926,11 @@ fhandler_pty_master::write (const void *ptr, size_t len)
int
fhandler_pty_master::read (void *ptr, size_t len)
{
- DWORD n;
- char *cptr = (char *) ptr;
+ int x = process_slave_output ((char *) ptr, len, pktmode);
- if (!PeekNamedPipe (get_handle (), NULL, 0, NULL, &n, NULL))
- {
- if (GetLastError () == ERROR_BROKEN_PIPE)
- {
- /* On Unix, a read from a broken pipe returns EOF. */
- return 0;
- }
- __seterrno ();
- return -1;
- }
- if (n == 0
- && (get_flags () & (O_NONBLOCK | O_NDELAY)) != 0)
- {
- set_errno (EAGAIN);
- return -1;
- }
- if (pktmode)
- {
- *cptr++ = TIOCPKT_DATA;
- len--;
- }
-
- int x;
- x = process_slave_output (cptr, len);
- if (x < 0)
- return -1;
if (output_done_event != NULL)
SetEvent (output_done_event);
- if (pktmode && x > 0)
- x++;
+
return x;
}