* 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:
Egor Duda 2001-03-18 18:05:01 +00:00
parent ca1cea7ed3
commit 5e8e21d938
7 changed files with 83 additions and 7 deletions

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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)
{

View File

@ -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];

View File

@ -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 */