* fhandler.h (fhandler_pty_common::bytes_available): Declare new function.
(fhandler_pty_master::flush_to_slave): Ditto. * fhandler_tty.cc (bytes_available): Define new function. (fhandler_pty_common::bytes_available): Ditto. (handler_pty_master::flush_to_slave): Ditto. (fhandler_pty_master::process_slave_output): Call flush_to_slave () here. Use bytes_available () rather than PeekNamedPipe. Cleanup sloppy logic. (fhandler_pty_slave::read): Use bytes_available () rather than PeekNamedPipe. (fhandler_pty_slave::ioctl): Ditto. (fhandler_pty_master::ioctl): Ditto. (fhandler_pty_master::cleanup): Remove ancient #if 0. * select.cc (peek_pipe): Call flush_to_slave whenever we're checking for a pty master.
This commit is contained in:
parent
ffcd2c3f89
commit
7b03b0d8ce
@ -1,3 +1,22 @@
|
|||||||
|
2012-04-04 Christopher Faylor <me.cygwin2012@cgf.cx>
|
||||||
|
|
||||||
|
* fhandler.h (fhandler_pty_common::bytes_available): Declare new
|
||||||
|
function.
|
||||||
|
(fhandler_pty_master::flush_to_slave): Ditto.
|
||||||
|
* fhandler_tty.cc (bytes_available): Define new function.
|
||||||
|
(fhandler_pty_common::bytes_available): Ditto.
|
||||||
|
(handler_pty_master::flush_to_slave): Ditto.
|
||||||
|
(fhandler_pty_master::process_slave_output): Call flush_to_slave ()
|
||||||
|
here. Use bytes_available () rather than PeekNamedPipe. Cleanup
|
||||||
|
sloppy logic.
|
||||||
|
(fhandler_pty_slave::read): Use bytes_available () rather than
|
||||||
|
PeekNamedPipe.
|
||||||
|
(fhandler_pty_slave::ioctl): Ditto.
|
||||||
|
(fhandler_pty_master::ioctl): Ditto.
|
||||||
|
(fhandler_pty_master::cleanup): Remove ancient #if 0.
|
||||||
|
* select.cc (peek_pipe): Call flush_to_slave whenever we're checking
|
||||||
|
for a pty master.
|
||||||
|
|
||||||
2012-04-04 Corinna Vinschen <corinna@vinschen.de>
|
2012-04-04 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* fhandler_nodevice.cc (fhandler_nodevice::open): Convert EROFS to
|
* fhandler_nodevice.cc (fhandler_nodevice::open): Convert EROFS to
|
||||||
|
@ -1433,6 +1433,7 @@ class fhandler_pty_common: public fhandler_termios
|
|||||||
|
|
||||||
int close ();
|
int close ();
|
||||||
_off64_t lseek (_off64_t, int);
|
_off64_t lseek (_off64_t, int);
|
||||||
|
bool bytes_available (DWORD& n);
|
||||||
void set_close_on_exec (bool val);
|
void set_close_on_exec (bool val);
|
||||||
select_record *select_read (select_stuff *);
|
select_record *select_read (select_stuff *);
|
||||||
select_record *select_write (select_stuff *);
|
select_record *select_write (select_stuff *);
|
||||||
@ -1549,6 +1550,7 @@ public:
|
|||||||
void fixup_after_fork (HANDLE parent);
|
void fixup_after_fork (HANDLE parent);
|
||||||
void fixup_after_exec ();
|
void fixup_after_exec ();
|
||||||
int tcgetpgrp ();
|
int tcgetpgrp ();
|
||||||
|
void flush_to_slave ();
|
||||||
|
|
||||||
fhandler_pty_master (void *) {}
|
fhandler_pty_master (void *) {}
|
||||||
~fhandler_pty_master ();
|
~fhandler_pty_master ();
|
||||||
|
@ -50,6 +50,25 @@ fhandler_pty_slave::get_unit ()
|
|||||||
return dev ().get_minor ();
|
return dev ().get_minor ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
bytes_available (DWORD& n, HANDLE h)
|
||||||
|
{
|
||||||
|
bool succeeded = PeekNamedPipe (h, NULL, 0, NULL, &n, NULL);
|
||||||
|
if (!succeeded)
|
||||||
|
{
|
||||||
|
termios_printf ("PeekNamedPipe(%p) failed, %E", h);
|
||||||
|
n = 0;
|
||||||
|
}
|
||||||
|
debug_only_printf ("%u bytes available", n);
|
||||||
|
return succeeded;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
fhandler_pty_common::bytes_available (DWORD &n)
|
||||||
|
{
|
||||||
|
return ::bytes_available (n, get_handle ());
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUGGING
|
#ifdef DEBUGGING
|
||||||
static class mutex_stack
|
static class mutex_stack
|
||||||
{
|
{
|
||||||
@ -62,6 +81,13 @@ public:
|
|||||||
static int osi;
|
static int osi;
|
||||||
#endif /*DEBUGGING*/
|
#endif /*DEBUGGING*/
|
||||||
|
|
||||||
|
void
|
||||||
|
fhandler_pty_master::flush_to_slave ()
|
||||||
|
{
|
||||||
|
if (get_readahead_valid () && !(get_ttyp ()->ti.c_lflag & ICANON))
|
||||||
|
accept_input ();
|
||||||
|
}
|
||||||
|
|
||||||
DWORD
|
DWORD
|
||||||
fhandler_pty_common::__acquire_output_mutex (const char *fn, int ln,
|
fhandler_pty_common::__acquire_output_mutex (const char *fn, int ln,
|
||||||
DWORD ms)
|
DWORD ms)
|
||||||
@ -194,6 +220,8 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len, int pktmode_on
|
|||||||
int column = 0;
|
int column = 0;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
|
flush_to_slave ();
|
||||||
|
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@ -210,7 +238,6 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len, int pktmode_on
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
/* Set RLEN to the number of bytes to read from the pipe. */
|
/* Set RLEN to the number of bytes to read from the pipe. */
|
||||||
@ -226,22 +253,12 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len, int pktmode_on
|
|||||||
if (rlen > sizeof outbuf)
|
if (rlen > sizeof outbuf)
|
||||||
rlen = sizeof outbuf;
|
rlen = sizeof outbuf;
|
||||||
|
|
||||||
HANDLE handle = get_io_handle ();
|
n = 0;
|
||||||
|
for (;;)
|
||||||
n = 0; // get_readahead_into_buffer (outbuf, len);
|
|
||||||
if (!n)
|
|
||||||
{
|
{
|
||||||
/* Doing a busy wait like this is quite inefficient, but nothing
|
if (!bytes_available (n))
|
||||||
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))
|
|
||||||
{
|
|
||||||
termios_printf ("PeekNamedPipe(%p) failed, %E", handle);
|
|
||||||
goto err;
|
goto err;
|
||||||
}
|
if (n)
|
||||||
if (n > 0)
|
|
||||||
break;
|
break;
|
||||||
if (hit_eof ())
|
if (hit_eof ())
|
||||||
goto out;
|
goto out;
|
||||||
@ -263,14 +280,14 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len, int pktmode_on
|
|||||||
rc = -1;
|
rc = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
flush_to_slave ();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ReadFile (handle, outbuf, rlen, &n, NULL))
|
if (!ReadFile (get_handle (), outbuf, rlen, &n, NULL))
|
||||||
{
|
{
|
||||||
termios_printf ("ReadFile failed, %E");
|
termios_printf ("ReadFile failed, %E");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
termios_printf ("bytes read %u", n);
|
termios_printf ("bytes read %u", n);
|
||||||
get_ttyp ()->write_error = 0;
|
get_ttyp ()->write_error = 0;
|
||||||
@ -668,7 +685,6 @@ fhandler_pty_slave::read (void *ptr, size_t& len)
|
|||||||
size_t readlen;
|
size_t readlen;
|
||||||
DWORD bytes_in_pipe;
|
DWORD bytes_in_pipe;
|
||||||
char buf[INP_BUFFER_SIZE];
|
char buf[INP_BUFFER_SIZE];
|
||||||
char peek_buf[INP_BUFFER_SIZE];
|
|
||||||
DWORD time_to_wait;
|
DWORD time_to_wait;
|
||||||
|
|
||||||
bg_check_types bg = bg_check (SIGTTIN);
|
bg_check_types bg = bg_check (SIGTTIN);
|
||||||
@ -785,12 +801,8 @@ fhandler_pty_slave::read (void *ptr, size_t& len)
|
|||||||
}
|
}
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (!PeekNamedPipe (get_handle (), peek_buf, sizeof (peek_buf), &bytes_in_pipe, NULL, NULL))
|
if (!bytes_available (bytes_in_pipe))
|
||||||
{
|
|
||||||
termios_printf ("PeekNamedPipe failed, %E");
|
|
||||||
raise (SIGHUP);
|
raise (SIGHUP);
|
||||||
bytes_in_pipe = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* On first peek determine no. of bytes to flush. */
|
/* On first peek determine no. of bytes to flush. */
|
||||||
if (!ptr && len == UINT_MAX)
|
if (!ptr && len == UINT_MAX)
|
||||||
@ -826,12 +838,8 @@ fhandler_pty_slave::read (void *ptr, size_t& len)
|
|||||||
number of bytes in pipe, but for some reason this number doesn't
|
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
|
change after successful read. So we have to peek into the pipe
|
||||||
again to see if input is still available */
|
again to see if input is still available */
|
||||||
if (!PeekNamedPipe (get_handle (), peek_buf, 1, &bytes_in_pipe, NULL, NULL))
|
if (!bytes_available (bytes_in_pipe))
|
||||||
{
|
|
||||||
termios_printf ("PeekNamedPipe failed, %E");
|
|
||||||
raise (SIGHUP);
|
raise (SIGHUP);
|
||||||
bytes_in_pipe = 0;
|
|
||||||
}
|
|
||||||
if (n)
|
if (n)
|
||||||
{
|
{
|
||||||
len -= n;
|
len -= n;
|
||||||
@ -999,15 +1007,15 @@ fhandler_pty_slave::ioctl (unsigned int cmd, void *arg)
|
|||||||
goto out;
|
goto out;
|
||||||
case FIONREAD:
|
case FIONREAD:
|
||||||
{
|
{
|
||||||
int n;
|
DWORD n;
|
||||||
if (!PeekNamedPipe (get_handle (), NULL, 0, NULL, (DWORD *) &n, NULL))
|
if (!bytes_available (n))
|
||||||
{
|
{
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
retval = -1;
|
retval = -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*(int *) arg = n;
|
*(int *) arg = (int) n;
|
||||||
retval = 0;
|
retval = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1265,11 +1273,6 @@ fhandler_pty_master::cleanup ()
|
|||||||
int
|
int
|
||||||
fhandler_pty_master::close ()
|
fhandler_pty_master::close ()
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
while (accept_input () > 0)
|
|
||||||
continue;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
termios_printf ("closing from_master(%p)/to_master(%p) since we own them(%d)",
|
termios_printf ("closing from_master(%p)/to_master(%p) since we own them(%d)",
|
||||||
from_master, to_master, dwProcessId);
|
from_master, to_master, dwProcessId);
|
||||||
if (cygwin_finished_initializing)
|
if (cygwin_finished_initializing)
|
||||||
@ -1420,13 +1423,13 @@ fhandler_pty_master::ioctl (unsigned int cmd, void *arg)
|
|||||||
return this->tcsetpgrp ((pid_t) arg);
|
return this->tcsetpgrp ((pid_t) arg);
|
||||||
case FIONREAD:
|
case FIONREAD:
|
||||||
{
|
{
|
||||||
int n;
|
DWORD n;
|
||||||
if (!PeekNamedPipe (to_master, NULL, 0, NULL, (DWORD *) &n, NULL))
|
if (!::bytes_available (n, to_master))
|
||||||
{
|
{
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
*(int *) arg = n;
|
*(int *) arg = (DWORD) n;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -552,11 +552,15 @@ peek_pipe (select_record *s, bool from_select)
|
|||||||
switch (fh->get_major ())
|
switch (fh->get_major ())
|
||||||
{
|
{
|
||||||
case DEV_PTYM_MAJOR:
|
case DEV_PTYM_MAJOR:
|
||||||
if (((fhandler_pty_master *) fh)->need_nl)
|
{
|
||||||
|
fhandler_pty_master *fhm = (fhandler_pty_master *) fh;
|
||||||
|
fhm->flush_to_slave ();
|
||||||
|
if (fhm->need_nl)
|
||||||
{
|
{
|
||||||
gotone = s->read_ready = true;
|
gotone = s->read_ready = true;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (fh->get_readahead_valid ())
|
if (fh->get_readahead_valid ())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user