* 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.
This commit is contained in:
		| @@ -1,3 +1,18 @@ | ||||
| 2001-03-18  Egor Duda <deo@logos-m.ru> | ||||
|  | ||||
| 	* 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 <cgf@cygnus.com> | ||||
|  | ||||
| 	* external.cc (fillout_pinfo): Match windows pid, as well as cygwin pid | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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); | ||||
|  | ||||
|   | ||||
| @@ -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) | ||||
| { | ||||
|   | ||||
| @@ -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]; | ||||
|   | ||||
| @@ -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 */ | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user