aboutsummaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2000-03-12 06:29:54 +0000
committerChristopher Faylor <me@cgf.cx>2000-03-12 06:29:54 +0000
commit3f0b4935404f01ab19ecab559a3201d4bb1ec5ca (patch)
treecc60ec7a05e57f8a4049bff0959bdd3ae24ae04c /winsup
parent774ea162116fcb08278c5efbe287848f5b5dd431 (diff)
downloadnewlib-3f0b4935404f01ab19ecab559a3201d4bb1ec5ca.zip
newlib-3f0b4935404f01ab19ecab559a3201d4bb1ec5ca.tar.gz
newlib-3f0b4935404f01ab19ecab559a3201d4bb1ec5ca.tar.bz2
* 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')
-rw-r--r--winsup/cygwin/ChangeLog14
-rw-r--r--winsup/cygwin/fhandler.cc18
-rw-r--r--winsup/cygwin/fhandler.h6
-rw-r--r--winsup/cygwin/fhandler_console.cc11
-rw-r--r--winsup/cygwin/fhandler_tty.cc130
-rw-r--r--winsup/cygwin/select.cc24
-rw-r--r--winsup/cygwin/tty.cc2
7 files changed, 113 insertions, 92 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 0e7c859..5ed1682 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,17 @@
+Sun Mar 12 01:14:33 2000 Christopher Faylor <cgf@cygnus.com>
+
+ * 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.
+
Sat Mar 11 22:47:43 2000 Christopher Faylor <cgf@cygnus.com>
* fhandler_console.cc (fhandler_console::read): Don't even think about
diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc
index c9a493f..4fbe8d3 100644
--- a/winsup/cygwin/fhandler.cc
+++ b/winsup/cygwin/fhandler.cc
@@ -96,6 +96,24 @@ fhandler_base::eat_readahead (int n)
return oralen;
}
+int
+fhandler_base::get_readahead_into_buffer (char *buf, size_t buflen)
+{
+ int ch;
+ int copied_chars = 0;
+
+ while (buflen)
+ if ((ch = get_readahead ()) < 0)
+ break;
+ else
+ {
+ buf[copied_chars++] = (unsigned char)(ch & 0xff);
+ buflen--;
+ }
+
+ return copied_chars;
+}
+
uid_t __stdcall
get_file_owner (int use_ntsec, const char *filename)
{
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 94a4bdb..9ebfa10 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -222,6 +222,8 @@ public:
void set_readahead_valid (int val, int ch = -1);
+ int get_readahead_into_buffer (char *buf, size_t buflen);
+
int has_acls () { return FHISSETF (HASACLS); }
void set_has_acls (int val) { FHCONDSETF (val, HASACLS); }
@@ -663,12 +665,12 @@ class fhandler_pty_master: public fhandler_tty_common
{
int pktmode; // non-zero if pty in a packet mode.
public:
- int neednl_; // Next read should start with \n
+ int need_nl; // Next read should start with \n
/* Constructor */
fhandler_pty_master (const char *name, DWORD devtype = FH_PTYM, int unit = -1);
- int process_slave_output (char *buf, size_t len);
+ int process_slave_output (char *buf, size_t len, int pktmode_on);
void doecho (const void *str, DWORD len);
int accept_input ();
int open (const char *path, int flags, mode_t mode = 0);
diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc
index 54d8da6..c7b9a6e 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -115,20 +115,13 @@ fhandler_console::read (void *pv, size_t buflen)
return 0;
HANDLE h = get_io_handle ();
- int copied_chars = 0;
#define buf ((char *) pv)
int ch;
set_input_state ();
- while (buflen)
- if ((ch = get_readahead ()) < 0)
- break;
- else
- {
- buf[copied_chars++] = (unsigned char)(ch & 0xff);
- buflen--;
- }
+
+ int copied_chars = get_readahead_into_buffer (buf, buflen);
if (copied_chars)
return copied_chars;
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 14da2bb..0cc9b52 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;
}
diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc
index b3d3560..5067006 100644
--- a/winsup/cygwin/select.cc
+++ b/winsup/cygwin/select.cc
@@ -409,20 +409,24 @@ peek_pipe (select_record *s, int ignra)
if (!s->read_selected && !s->except_selected)
goto out;
- if (s->read_selected && fh->bg_check (SIGTTIN) <= 0)
+ if (s->read_selected)
{
- gotone = s->read_ready = 1;
- goto out;
- }
+ if (fh->bg_check (SIGTTIN) <= 0)
+ {
+ gotone = s->read_ready = 1;
+ goto out;
+ }
- if (!ignra && fh->get_readahead_valid ())
- {
- select_printf ("readahead");
- gotone = s->read_ready = 1;
- goto out;
+ if (!ignra && fh->get_device () != FH_PTYM && fh->get_device () != FH_TTYM &&
+ fh->get_readahead_valid ())
+ {
+ select_printf ("readahead");
+ gotone = s->read_ready = 1;
+ goto out;
+ }
}
- else if (!PeekNamedPipe (h, NULL, 0, NULL, (DWORD *) &n, NULL))
+ if (!PeekNamedPipe (h, NULL, 0, NULL, (DWORD *) &n, NULL))
{
select_printf ("%s, PeekNamedPipe failed, %E", fh->get_name ());
n = -1;
diff --git a/winsup/cygwin/tty.cc b/winsup/cygwin/tty.cc
index ef9bec5..ec020b1 100644
--- a/winsup/cygwin/tty.cc
+++ b/winsup/cygwin/tty.cc
@@ -366,7 +366,7 @@ tty::common_init (fhandler_pty_master *ptym)
if (!make_pipes (ptym))
return FALSE;
- ptym->neednl_ = 0;
+ ptym->need_nl = 0;
/* Save our pid */