* 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> Sat Mar 11 22:47:43 2000 Christopher Faylor <cgf@cygnus.com>
* fhandler_console.cc (fhandler_console::read): Don't even think about * 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; 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 uid_t __stdcall
get_file_owner (int use_ntsec, const char *filename) 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); 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); } int has_acls () { return FHISSETF (HASACLS); }
void set_has_acls (int val) { FHCONDSETF (val, 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. int pktmode; // non-zero if pty in a packet mode.
public: public:
int neednl_; // Next read should start with \n int need_nl; // Next read should start with \n
/* Constructor */ /* Constructor */
fhandler_pty_master (const char *name, DWORD devtype = FH_PTYM, int unit = -1); 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); void doecho (const void *str, DWORD len);
int accept_input (); int accept_input ();
int open (const char *path, int flags, mode_t mode = 0); 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; return 0;
HANDLE h = get_io_handle (); HANDLE h = get_io_handle ();
int copied_chars = 0;
#define buf ((char *) pv) #define buf ((char *) pv)
int ch; int ch;
set_input_state (); set_input_state ();
while (buflen)
if ((ch = get_readahead ()) < 0) int copied_chars = get_readahead_into_buffer (buf, buflen);
break;
else
{
buf[copied_chars++] = (unsigned char)(ch & 0xff);
buflen--;
}
if (copied_chars) if (copied_chars)
return copied_chars; return copied_chars;

View File

@ -214,10 +214,10 @@ fhandler_pty_master::hit_eof ()
/* Process tty output requests */ /* Process tty output requests */
int 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; size_t rlen;
char outbuf[OUT_BUFFER_SIZE]; char outbuf[OUT_BUFFER_SIZE + 1];
DWORD n; DWORD n;
int column = 0; int column = 0;
int rc = 0; int rc = 0;
@ -225,20 +225,20 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len)
if (len == 0) if (len == 0)
goto out; 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 (;;) 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. */ /* Set RLEN to the number of bytes to read from the pipe. */
rlen = len; rlen = len;
if (get_ttyp ()->ti.c_oflag & OPOST && get_ttyp ()->ti.c_oflag & ONLCR) 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 (); HANDLE handle = get_io_handle ();
/* Doing a busy wait like this is quite inefficient, but nothing n = 0; // get_readahead_into_buffer (outbuf, len);
else seems to work completely. Windows should provide some sort if (!n)
of overlapped I/O for pipes, or something, but it doesn't. */
while (1)
{ {
DWORD avail; /* Doing a busy wait like this is quite inefficient, but nothing
if (!PeekNamedPipe (handle, NULL, 0, NULL, &avail, NULL)) 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; goto err;
if (avail > 0)
break;
if (hit_eof ())
goto out;
Sleep (10);
} }
if (ReadFile (handle, outbuf, rlen, &n, NULL) == FALSE) termios_printf ("bytes read %u", n);
goto err;
termios_printf ("rlen %u", n);
if (get_ttyp ()->ti.c_lflag & FLUSHO) 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"); 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 if (!(get_ttyp ()->ti.c_oflag & OPOST)) // post-process output
{ {
memcpy (buf, outbuf, n); memcpy (optr, outbuf, n);
rc = n; optr += n;
} }
else // raw output mode else // raw output mode
{ {
char *iptr = outbuf, *optr = buf; char *iptr = outbuf;
while (n--) while (n--)
{ {
@ -332,16 +347,16 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len)
doing \r\n expansion. */ doing \r\n expansion. */
if (optr - buf >= (int) len) if (optr - buf >= (int) len)
{ {
neednl_ = 1;
if (*iptr != '\n' || n != 0) if (*iptr != '\n' || n != 0)
system_printf ("internal error: %d unexpected characters", n); system_printf ("internal error: %d unexpected characters", n);
need_nl = 1;
break; break;
} }
*optr++ = *iptr++; *optr++ = *iptr++;
} }
rc = optr - buf;
} }
rc = optr - buf;
break; break;
err: err:
@ -364,11 +379,10 @@ static DWORD WINAPI
process_output (void *) process_output (void *)
{ {
char buf[OUT_BUFFER_SIZE*2]; 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) if (n < 0)
{ {
termios_printf ("ReadFile %E"); termios_printf ("ReadFile %E");
@ -592,14 +606,18 @@ fhandler_tty_slave::read (void *ptr, size_t len)
while (len) while (len)
{ {
size_t readlen = min ((unsigned) vmin, min (len, sizeof (buf)));
termios_printf ("reading %d bytes (vtime %d)", termios_printf ("reading %d bytes (vtime %d)",
min ((unsigned) vmin, min (len, sizeof (buf))), vtime); 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"); termios_printf ("read failed, %E");
_raise (SIGHUP); _raise (SIGHUP);
} }
if (get_ttyp ()->read_retval < 0) // read error if (get_ttyp ()->read_retval < 0) // read error
{ {
set_errno (-get_ttyp ()->read_retval); 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_request_event = NULL;
ioctl_done_event = NULL; ioctl_done_event = NULL;
restart_output_event = NULL; restart_output_event = NULL;
pktmode = neednl_ = 0; pktmode = need_nl = 0;
inuse = NULL; inuse = NULL;
} }
@ -908,39 +926,11 @@ fhandler_pty_master::write (const void *ptr, size_t len)
int int
fhandler_pty_master::read (void *ptr, size_t len) fhandler_pty_master::read (void *ptr, size_t len)
{ {
DWORD n; int x = process_slave_output ((char *) ptr, len, pktmode);
char *cptr = (char *) ptr;
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) if (output_done_event != NULL)
SetEvent (output_done_event); SetEvent (output_done_event);
if (pktmode && x > 0)
x++;
return x; return x;
} }

View File

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

View File

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