* 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:
		@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -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  */
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user