From 9a06eab1197a505f90fd83f1bbdd6e859d2facb0 Mon Sep 17 00:00:00 2001 From: duda Date: Sun, 18 Mar 2001 18:05:01 +0000 Subject: [PATCH] * fhandler.h (fhandler_tty_slave): Declare new methods. * select.cc (fhandler_tty_slave::select_read): New method. * select.cc (fhandler_tty_slave::ready_for_read): Ditto. * select.cc (verify_tty_slave): New function. * fhandler_termios.cc (fhandler_termios::line_edit): Empty input buffer on signal. * fhandler_tty.cc (fhandler_tty_slave::read): Check for input data after reading from pipe. Reset event if input pipe is empty. * tty.h (class tty): Allow creating events with manual reset. * tty.cc (tty::get_event): Use manual_reset flag. * tty.cc (tty::common_init): Create input_available_event with manual reset. --- winsup/cygwin/ChangeLog | 15 +++++++++++++ winsup/cygwin/fhandler.h | 2 ++ winsup/cygwin/fhandler_termios.cc | 1 + winsup/cygwin/fhandler_tty.cc | 17 +++++++++++--- winsup/cygwin/select.cc | 47 +++++++++++++++++++++++++++++++++++++++ winsup/cygwin/tty.cc | 6 ++--- winsup/cygwin/tty.h | 2 +- 7 files changed, 83 insertions(+), 7 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 9d90160460..6c95644e30 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,18 @@ +2001-03-18 Egor Duda + + * fhandler.h (fhandler_tty_slave): Declare new methods. + * select.cc (fhandler_tty_slave::select_read): New method. + * select.cc (fhandler_tty_slave::ready_for_read): Ditto. + * select.cc (verify_tty_slave): New function. + * fhandler_termios.cc (fhandler_termios::line_edit): Empty input + buffer on signal. + * fhandler_tty.cc (fhandler_tty_slave::read): Check for input data + after reading from pipe. Reset event if input pipe is empty. + * tty.h (class tty): Allow creating events with manual reset. + * tty.cc (tty::get_event): Use manual_reset flag. + * tty.cc (tty::common_init): Create input_available_event with + manual reset. + Sat Mar 17 21:48:03 2001 Christopher Faylor * external.cc (fillout_pinfo): Match windows pid, as well as cygwin pid diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 7e827571ea..90ded24bd3 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -761,6 +761,8 @@ public: int ioctl (unsigned int cmd, void *); off_t lseek (off_t, int) { return 0; } + select_record *select_read (select_record *s); + int ready_for_read (int fd, DWORD howlong, int ignra); }; class fhandler_pty_master: public fhandler_tty_common diff --git a/winsup/cygwin/fhandler_termios.cc b/winsup/cygwin/fhandler_termios.cc index 948de94dc6..6d4e4e9a82 100644 --- a/winsup/cygwin/fhandler_termios.cc +++ b/winsup/cygwin/fhandler_termios.cc @@ -209,6 +209,7 @@ fhandler_termios::line_edit (const char *rptr, int nread, int always_accept) goto not_a_sig; termios_printf ("got interrupt %d, sending signal %d", c, sig); + eat_readahead (-1); kill_pgrp (tc->getpgid (), sig); tc->ti.c_lflag &= ~FLUSHO; sawsig = 1; diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc index 5cca97b4de..a2e815e66f 100644 --- a/winsup/cygwin/fhandler_tty.cc +++ b/winsup/cygwin/fhandler_tty.cc @@ -614,6 +614,7 @@ fhandler_tty_slave::read (void *ptr, size_t len) size_t readlen; DWORD bytes_in_pipe; char buf[INP_BUFFER_SIZE]; + char peek_buf[INP_BUFFER_SIZE]; DWORD time_to_wait; DWORD rc; HANDLE w4[2]; @@ -667,7 +668,7 @@ fhandler_tty_slave::read (void *ptr, size_t len) termios_printf ("failed to acquire input mutex after input event arrived"); break; } - if (!PeekNamedPipe (get_handle (), NULL, 0, NULL, &bytes_in_pipe, NULL)) + if (!PeekNamedPipe (get_handle (), peek_buf, sizeof(peek_buf), &bytes_in_pipe, NULL, NULL)) { termios_printf ("PeekNamedPipe failed, %E"); _raise (SIGHUP); @@ -682,6 +683,16 @@ fhandler_tty_slave::read (void *ptr, size_t len) termios_printf ("read failed, %E"); _raise (SIGHUP); } + /* MSDN states that 5th prameter can be used to determine total + number of bytes in pipe, but for some reason this number doesn't + change after successful read. So we have to peek into the pipe + again to see if input is still available */ + if (!PeekNamedPipe (get_handle (), peek_buf, 1, &bytes_in_pipe, NULL, NULL)) + { + termios_printf ("PeekNamedPipe failed, %E"); + _raise (SIGHUP); + bytes_in_pipe = 0; + } if (n) { len -= n; @@ -691,8 +702,8 @@ fhandler_tty_slave::read (void *ptr, size_t len) } } - if (readlen != bytes_in_pipe) - SetEvent (input_available_event); + if (!bytes_in_pipe) + ResetEvent (input_available_event); ReleaseMutex (input_mutex); diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index 64c6ebb472..1823cd1c43 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -743,6 +743,53 @@ fhandler_tty_common::select_except (select_record *s) return ((fhandler_pipe *)this)->fhandler_pipe::select_except (s); } +static int +verify_tty_slave (select_record *me, fd_set *readfds, fd_set *writefds, + fd_set *exceptfds) +{ + if (WaitForSingleObject (me->h, 0) == WAIT_OBJECT_0) + me->read_ready = 1; + return set_bits (me, readfds, writefds, exceptfds); +} + +select_record * +fhandler_tty_slave::select_read (select_record *s) +{ + if (!s) + s = new select_record; + s->h = input_available_event; + s->startup = no_startup; + s->poll = poll_pipe; + s->verify = verify_tty_slave; + s->read_selected = TRUE; + s->cleanup = NULL; + return s; +} + +int +fhandler_tty_slave::ready_for_read (int fd, DWORD howlong, int ignra) +{ + HANDLE w4[2]; + if (!ignra && get_readahead_valid ()) + { + select_printf ("readahead"); + return 1; + } + w4[0] = signal_arrived; + w4[1] = input_available_event; + switch (WaitForMultipleObjects (2, w4, FALSE, howlong)) + { + case WAIT_OBJECT_0 + 1: + return 1; + case WAIT_FAILED: + select_printf ( "wait failed %E" ); + case WAIT_OBJECT_0: + case WAIT_TIMEOUT: + default: + return 0; + } +} + select_record * fhandler_dev_null::select_read (select_record *s) { diff --git a/winsup/cygwin/tty.cc b/winsup/cygwin/tty.cc index 798984418f..424cf7112c 100644 --- a/winsup/cygwin/tty.cc +++ b/winsup/cygwin/tty.cc @@ -325,13 +325,13 @@ tty::init (void) } HANDLE -tty::get_event (const char *fmt, BOOL inherit) +tty::get_event (const char *fmt, BOOL inherit, BOOL manual_reset) { HANDLE hev; char buf[40]; __small_sprintf (buf, fmt, ntty); - if (!(hev = CreateEvent (inherit ? &sec_all : &sec_all_nih, FALSE, FALSE, buf))) + if (!(hev = CreateEvent (inherit ? &sec_all : &sec_all_nih, manual_reset, FALSE, buf))) { termios_printf ("couldn't create %s", buf); set_errno (ENOENT); /* FIXME this can't be the right errno */ @@ -408,7 +408,7 @@ tty::common_init (fhandler_pty_master *ptym) return FALSE; } - if (!(ptym->input_available_event = get_event (INPUT_AVAILABLE_EVENT, FALSE))) + if (!(ptym->input_available_event = get_event (INPUT_AVAILABLE_EVENT, FALSE, TRUE))) return FALSE; char buf[40]; diff --git a/winsup/cygwin/tty.h b/winsup/cygwin/tty.h index 36f7ae19d0..43a82e0e49 100644 --- a/winsup/cygwin/tty.h +++ b/winsup/cygwin/tty.h @@ -86,7 +86,7 @@ class fhandler_pty_master; class tty: public tty_min { - HANDLE get_event (const char *fmt, BOOL inherit); + HANDLE get_event (const char *fmt, BOOL inherit, BOOL manual_reset = FALSE); public: HWND hwnd; /* Console window handle tty belongs to */ -- 2.11.0