* fhandler.cc (fhandler_base::get_readahead_into_buffer): New function.

* fhandler.h: Declare new function.  Add extra argument to
process_slave_output.
* fhandler_console.cc (fhandler_console::read): Move read ahead code to new
function.
* fhandler_tty.cc (fhandler_pty_master::process_slave_output): Move common code
here.
(fhandler_tty_slave::read): Understand readahead.
(fhandler_pty_master::read): Move code to process_slave_output.
* select.cc (peek_pipe): Avoid performing certain checks when non-read and on
inappropriate fh types.
This commit is contained in:
Christopher Faylor 2000-03-12 06:29:54 +00:00
parent 774ea16211
commit 3f0b493540
7 changed files with 114 additions and 93 deletions

View File

@ -1,3 +1,17 @@
Sun Mar 12 01:14:33 2000 Christopher Faylor <cgf@cygnus.com>
* fhandler.cc (fhandler_base::get_readahead_into_buffer): New function.
* fhandler.h: Declare new function. Add extra argument to
process_slave_output.
* fhandler_console.cc (fhandler_console::read): Move read ahead code to
new function.
* fhandler_tty.cc (fhandler_pty_master::process_slave_output): Move
common code here.
(fhandler_tty_slave::read): Understand readahead.
(fhandler_pty_master::read): Move code to process_slave_output.
* select.cc (peek_pipe): Avoid performing certain checks when non-read
and on inappropriate fh types.
Sat Mar 11 22:47:43 2000 Christopher Faylor <cgf@cygnus.com>
* fhandler_console.cc (fhandler_console::read): Don't even think about

View File

@ -96,6 +96,24 @@ fhandler_base::eat_readahead (int n)
return oralen;
}
int
fhandler_base::get_readahead_into_buffer (char *buf, size_t buflen)
{
int ch;
int copied_chars = 0;
while (buflen)
if ((ch = get_readahead ()) < 0)
break;
else
{
buf[copied_chars++] = (unsigned char)(ch & 0xff);
buflen--;
}
return copied_chars;
}
uid_t __stdcall
get_file_owner (int use_ntsec, const char *filename)
{

View File

@ -222,6 +222,8 @@ public:
void set_readahead_valid (int val, int ch = -1);
int get_readahead_into_buffer (char *buf, size_t buflen);
int has_acls () { return FHISSETF (HASACLS); }
void set_has_acls (int val) { FHCONDSETF (val, HASACLS); }
@ -663,12 +665,12 @@ class fhandler_pty_master: public fhandler_tty_common
{
int pktmode; // non-zero if pty in a packet mode.
public:
int neednl_; // Next read should start with \n
int need_nl; // Next read should start with \n
/* Constructor */
fhandler_pty_master (const char *name, DWORD devtype = FH_PTYM, int unit = -1);
int process_slave_output (char *buf, size_t len);
int process_slave_output (char *buf, size_t len, int pktmode_on);
void doecho (const void *str, DWORD len);
int accept_input ();
int open (const char *path, int flags, mode_t mode = 0);

View File

@ -115,20 +115,13 @@ fhandler_console::read (void *pv, size_t buflen)
return 0;
HANDLE h = get_io_handle ();
int copied_chars = 0;
#define buf ((char *) pv)
int ch;
set_input_state ();
while (buflen)
if ((ch = get_readahead ()) < 0)
break;
else
{
buf[copied_chars++] = (unsigned char)(ch & 0xff);
buflen--;
}
int copied_chars = get_readahead_into_buffer (buf, buflen);
if (copied_chars)
return copied_chars;

View File

@ -214,10 +214,10 @@ fhandler_pty_master::hit_eof ()
/* Process tty output requests */
int
fhandler_pty_master::process_slave_output (char *buf, size_t len)
fhandler_pty_master::process_slave_output (char *buf, size_t len, int pktmode_on)
{
size_t rlen;
char outbuf[OUT_BUFFER_SIZE];
char outbuf[OUT_BUFFER_SIZE + 1];
DWORD n;
int column = 0;
int rc = 0;
@ -225,20 +225,20 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len)
if (len == 0)
goto out;
if (need_nl)
{
/* We need to return a left over \n character, resulting from
\r\n conversion. Note that we already checked for FLUSHO and
OutputStopped at the time that we read the character, so we
don't check again here. */
buf[0] = '\n';
need_nl = 0;
goto out;
}
for (;;)
{
if (neednl_)
{
/* We need to return a left over \n character, resulting from
\r\n conversion. Note that we already checked for FLUSHO and
OutputStopped at the time that we read the character, so we
don't check again here. */
buf[0] = '\n';
neednl_ = 0;
rc = 1;
break;
}
/* Set RLEN to the number of bytes to read from the pipe. */
rlen = len;
if (get_ttyp ()->ti.c_oflag & OPOST && get_ttyp ()->ti.c_oflag & ONLCR)
@ -254,25 +254,35 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len)
HANDLE handle = get_io_handle ();
/* Doing a busy wait like this is quite inefficient, but nothing
else seems to work completely. Windows should provide some sort
of overlapped I/O for pipes, or something, but it doesn't. */
while (1)
n = 0; // get_readahead_into_buffer (outbuf, len);
if (!n)
{
DWORD avail;
if (!PeekNamedPipe (handle, NULL, 0, NULL, &avail, NULL))
/* Doing a busy wait like this is quite inefficient, but nothing
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))
goto err;
if (n > 0)
break;
if (hit_eof ())
goto out;
if (n == 0 && (get_flags () & (O_NONBLOCK | O_NDELAY)) != 0)
{
set_errno (EAGAIN);
rc = -1;
break;
}
Sleep (10);
}
if (ReadFile (handle, outbuf, rlen, &n, NULL) == FALSE)
goto err;
if (avail > 0)
break;
if (hit_eof ())
goto out;
Sleep (10);
}
if (ReadFile (handle, outbuf, rlen, &n, NULL) == FALSE)
goto err;
termios_printf ("rlen %u", n);
termios_printf ("bytes read %u", n);
if (get_ttyp ()->ti.c_lflag & FLUSHO)
{
@ -289,14 +299,19 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len)
termios_printf ("done waiting for restart_output_event");
}
char *optr;
optr = buf;
if (pktmode_on)
*optr++ = TIOCPKT_DATA;
if (!(get_ttyp ()->ti.c_oflag & OPOST)) // post-process output
{
memcpy (buf, outbuf, n);
rc = n;
memcpy (optr, outbuf, n);
optr += n;
}
else // raw output mode
{
char *iptr = outbuf, *optr = buf;
char *iptr = outbuf;
while (n--)
{
@ -332,16 +347,16 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len)
doing \r\n expansion. */
if (optr - buf >= (int) len)
{
neednl_ = 1;
if (*iptr != '\n' || n != 0)
system_printf ("internal error: %d unexpected characters", n);
need_nl = 1;
break;
}
*optr++ = *iptr++;
}
rc = optr - buf;
}
rc = optr - buf;
break;
err:
@ -364,11 +379,10 @@ static DWORD WINAPI
process_output (void *)
{
char buf[OUT_BUFFER_SIZE*2];
int n;
while (1)
for (;;)
{
n = tty_master->process_slave_output (buf, OUT_BUFFER_SIZE);
int n = tty_master->process_slave_output (buf, OUT_BUFFER_SIZE, 0);
if (n < 0)
{
termios_printf ("ReadFile %E");
@ -592,14 +606,18 @@ fhandler_tty_slave::read (void *ptr, size_t len)
while (len)
{
size_t readlen = min ((unsigned) vmin, min (len, sizeof (buf)));
termios_printf ("reading %d bytes (vtime %d)",
min ((unsigned) vmin, min (len, sizeof (buf))), vtime);
if (ReadFile (get_handle (), (unsigned *) buf,
min ((unsigned) vmin, min (len, sizeof (buf))), &n, NULL) == FALSE)
n = get_readahead_into_buffer (buf, readlen);
if (!n && ReadFile (get_handle (), buf, readlen, &n, NULL) == FALSE)
{
termios_printf ("read failed, %E");
_raise (SIGHUP);
}
if (get_ttyp ()->read_retval < 0) // read error
{
set_errno (-get_ttyp ()->read_retval);
@ -827,7 +845,7 @@ fhandler_pty_master::fhandler_pty_master (const char *name, DWORD devtype, int u
ioctl_request_event = NULL;
ioctl_done_event = NULL;
restart_output_event = NULL;
pktmode = neednl_ = 0;
pktmode = need_nl = 0;
inuse = NULL;
}
@ -908,39 +926,11 @@ fhandler_pty_master::write (const void *ptr, size_t len)
int
fhandler_pty_master::read (void *ptr, size_t len)
{
DWORD n;
char *cptr = (char *) ptr;
int x = process_slave_output ((char *) ptr, len, pktmode);
if (!PeekNamedPipe (get_handle (), NULL, 0, NULL, &n, NULL))
{
if (GetLastError () == ERROR_BROKEN_PIPE)
{
/* On Unix, a read from a broken pipe returns EOF. */
return 0;
}
__seterrno ();
return -1;
}
if (n == 0
&& (get_flags () & (O_NONBLOCK | O_NDELAY)) != 0)
{
set_errno (EAGAIN);
return -1;
}
if (pktmode)
{
*cptr++ = TIOCPKT_DATA;
len--;
}
int x;
x = process_slave_output (cptr, len);
if (x < 0)
return -1;
if (output_done_event != NULL)
SetEvent (output_done_event);
if (pktmode && x > 0)
x++;
return x;
}

View File

@ -409,20 +409,24 @@ peek_pipe (select_record *s, int ignra)
if (!s->read_selected && !s->except_selected)
goto out;
if (s->read_selected && fh->bg_check (SIGTTIN) <= 0)
if (s->read_selected)
{
gotone = s->read_ready = 1;
goto out;
if (fh->bg_check (SIGTTIN) <= 0)
{
gotone = s->read_ready = 1;
goto out;
}
if (!ignra && fh->get_device () != FH_PTYM && fh->get_device () != FH_TTYM &&
fh->get_readahead_valid ())
{
select_printf ("readahead");
gotone = s->read_ready = 1;
goto out;
}
}
if (!ignra && fh->get_readahead_valid ())
{
select_printf ("readahead");
gotone = s->read_ready = 1;
goto out;
}
else if (!PeekNamedPipe (h, NULL, 0, NULL, (DWORD *) &n, NULL))
if (!PeekNamedPipe (h, NULL, 0, NULL, (DWORD *) &n, NULL))
{
select_printf ("%s, PeekNamedPipe failed, %E", fh->get_name ());
n = -1;

View File

@ -366,7 +366,7 @@ tty::common_init (fhandler_pty_master *ptym)
if (!make_pipes (ptym))
return FALSE;
ptym->neednl_ = 0;
ptym->need_nl = 0;
/* Save our pid */