diff options
author | Christopher Faylor <me@cgf.cx> | 2000-03-12 06:29:54 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2000-03-12 06:29:54 +0000 |
commit | 3f0b4935404f01ab19ecab559a3201d4bb1ec5ca (patch) | |
tree | cc60ec7a05e57f8a4049bff0959bdd3ae24ae04c /winsup | |
parent | 774ea162116fcb08278c5efbe287848f5b5dd431 (diff) | |
download | newlib-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/ChangeLog | 14 | ||||
-rw-r--r-- | winsup/cygwin/fhandler.cc | 18 | ||||
-rw-r--r-- | winsup/cygwin/fhandler.h | 6 | ||||
-rw-r--r-- | winsup/cygwin/fhandler_console.cc | 11 | ||||
-rw-r--r-- | winsup/cygwin/fhandler_tty.cc | 130 | ||||
-rw-r--r-- | winsup/cygwin/select.cc | 24 | ||||
-rw-r--r-- | winsup/cygwin/tty.cc | 2 |
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 */ |