* 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.
+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
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
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;
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];
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);
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;
}
}
- if (readlen != bytes_in_pipe)
- SetEvent (input_available_event);
+ if (!bytes_in_pipe)
+ ResetEvent (input_available_event);
ReleaseMutex (input_mutex);
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)
{
}
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 */
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];
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 */