* fhandler.h (fhandler_termios::line_edit): Add parameter to return

written bytes.
	* fhandler_termios.cc (fhandler_termios::tcinit): Fix formatting.
	(fhandler_termios::line_edit): Return bytes actually written.  Write
	in 32 byte chunks in non-canonical mode to reduce number of WriteFile
	calls.  Don't just eat unwritten bytes in case of an error condition.
	Especially, don't report them back to the caller as written.
	* fhandler_tty.cc (fhandler_pty_slave::read): Disable code reducing
	the number of bytes read from the pipe to vmin.  Add comment.
	(fhandler_pty_master::write): Convert ret to ssize_t type.  Just call
	line_edit once, not in a loop once for each byte.  Return bytes written
	as returned by line_edit.
This commit is contained in:
Corinna Vinschen 2014-11-13 18:37:15 +00:00
parent d544f256d1
commit 73742508fc
4 changed files with 54 additions and 23 deletions

View File

@ -1,3 +1,18 @@
2014-11-13 Corinna Vinschen <corinna@vinschen.de>
* fhandler.h (fhandler_termios::line_edit): Add parameter to return
written bytes.
* fhandler_termios.cc (fhandler_termios::tcinit): Fix formatting.
(fhandler_termios::line_edit): Return bytes actually written. Write
in 32 byte chunks in non-canonical mode to reduce number of WriteFile
calls. Don't just eat unwritten bytes in case of an error condition.
Especially, don't report them back to the caller as written.
* fhandler_tty.cc (fhandler_pty_slave::read): Disable code reducing
the number of bytes read from the pipe to vmin. Add comment.
(fhandler_pty_master::write): Convert ret to ssize_t type. Just call
line_edit once, not in a loop once for each byte. Return bytes written
as returned by line_edit.
2014-11-13 Corinna Vinschen <corinna@vinschen.de> 2014-11-13 Corinna Vinschen <corinna@vinschen.de>
* include/cygwin/version.h (CYGWIN_VERSION_DLL_MINOR): Bump to 34. * include/cygwin/version.h (CYGWIN_VERSION_DLL_MINOR): Bump to 34.

View File

@ -1204,7 +1204,8 @@ class fhandler_termios: public fhandler_base
need_fork_fixup (true); need_fork_fixup (true);
} }
HANDLE& get_output_handle () { return output_handle; } HANDLE& get_output_handle () { return output_handle; }
line_edit_status line_edit (const char *rptr, int nread, termios&); line_edit_status line_edit (const char *rptr, size_t nread, termios&,
ssize_t *bytes_read = NULL);
void set_output_handle (HANDLE h) { output_handle = h; } void set_output_handle (HANDLE h) { output_handle = h; }
void tcinit (bool force); void tcinit (bool force);
bool is_tty () const { return true; } bool is_tty () const { return true; }

View File

@ -1,7 +1,7 @@
/* fhandler_termios.cc /* fhandler_termios.cc
Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010, Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010,
2011, 2012 Red Hat, Inc. 2011, 2012, 2014 Red Hat, Inc.
This file is part of Cygwin. This file is part of Cygwin.
@ -39,14 +39,14 @@ fhandler_termios::tcinit (bool is_pty_master)
tc ()->ti.c_lflag = ISIG | ICANON | ECHO | IEXTEN; tc ()->ti.c_lflag = ISIG | ICANON | ECHO | IEXTEN;
tc ()->ti.c_cc[VDISCARD] = CFLUSH; tc ()->ti.c_cc[VDISCARD] = CFLUSH;
tc ()->ti.c_cc[VEOL] = CEOL; tc ()->ti.c_cc[VEOL] = CEOL;
tc ()->ti.c_cc[VEOL2] = CEOL2; tc ()->ti.c_cc[VEOL2] = CEOL2;
tc ()->ti.c_cc[VEOF] = CEOF; tc ()->ti.c_cc[VEOF] = CEOF;
tc ()->ti.c_cc[VERASE] = CERASE; tc ()->ti.c_cc[VERASE] = CERASE;
tc ()->ti.c_cc[VINTR] = CINTR; tc ()->ti.c_cc[VINTR] = CINTR;
tc ()->ti.c_cc[VKILL] = CKILL; tc ()->ti.c_cc[VKILL] = CKILL;
tc ()->ti.c_cc[VLNEXT] = CLNEXT; tc ()->ti.c_cc[VLNEXT] = CLNEXT;
tc ()->ti.c_cc[VMIN] = 1; tc ()->ti.c_cc[VMIN] = 1;
tc ()->ti.c_cc[VQUIT] = CQUIT; tc ()->ti.c_cc[VQUIT] = CQUIT;
tc ()->ti.c_cc[VREPRINT] = CRPRNT; tc ()->ti.c_cc[VREPRINT] = CRPRNT;
tc ()->ti.c_cc[VSTART] = CSTART; tc ()->ti.c_cc[VSTART] = CSTART;
@ -234,7 +234,8 @@ fhandler_termios::echo_erase (int force)
} }
line_edit_status line_edit_status
fhandler_termios::line_edit (const char *rptr, int nread, termios& ti) fhandler_termios::line_edit (const char *rptr, size_t nread, termios& ti,
ssize_t *bytes_read)
{ {
line_edit_status ret = line_edit_ok; line_edit_status ret = line_edit_ok;
char c; char c;
@ -242,11 +243,13 @@ fhandler_termios::line_edit (const char *rptr, int nread, termios& ti)
bool sawsig = false; bool sawsig = false;
int iscanon = ti.c_lflag & ICANON; int iscanon = ti.c_lflag & ICANON;
if (*bytes_read)
*bytes_read = nread;
while (nread-- > 0) while (nread-- > 0)
{ {
c = *rptr++; c = *rptr++;
paranoid_printf ("char %0c", c); paranoid_printf ("char %0o", c);
if (ti.c_iflag & ISTRIP) if (ti.c_iflag & ISTRIP)
c &= 0x7f; c &= 0x7f;
@ -370,13 +373,15 @@ fhandler_termios::line_edit (const char *rptr, int nread, termios& ti)
put_readahead (c); put_readahead (c);
if (ti.c_lflag & ECHO) if (ti.c_lflag & ECHO)
doecho (&c, 1); doecho (&c, 1);
if (!iscanon || input_done) /* Write in chunks of 32 bytes to reduce the number of WriteFile calls
in non-canonical mode. */
if ((!iscanon && ralen >= 32) || input_done)
{ {
int status = accept_input (); int status = accept_input ();
if (status != 1) if (status != 1)
{ {
ret = status ? line_edit_error : line_edit_pipe_full; ret = status ? line_edit_error : line_edit_pipe_full;
eat_readahead (1); nread += ralen;
break; break;
} }
ret = line_edit_input_done; ret = line_edit_input_done;
@ -384,8 +389,21 @@ fhandler_termios::line_edit (const char *rptr, int nread, termios& ti)
} }
} }
/* If we didn't write all bytes in non-canonical mode, write them now. */
if (!iscanon && ralen > 0) if (!iscanon && ralen > 0)
ret = line_edit_input_done; {
if (ret == line_edit_ok)
{
int status = accept_input ();
if (status != 1)
nread += ralen;
}
ret = line_edit_input_done;
}
/* Adding one compensates for the postdecrement in the above loop. */
if (*bytes_read)
*bytes_read -= (nread + 1);
if (sawsig) if (sawsig)
ret = line_edit_signalled; ret = line_edit_signalled;

View File

@ -829,8 +829,13 @@ fhandler_pty_slave::read (void *ptr, size_t& len)
readlen = MIN (bytes_in_pipe, MIN (len, sizeof (buf))); readlen = MIN (bytes_in_pipe, MIN (len, sizeof (buf)));
#if 0
/* Why on earth is the read length reduced to vmin, even if more bytes
are available *and* len is bigger *and* the local buf is big enough?
Disable this code for now, it looks like a remnant of old. */
if (ptr && vmin && readlen > (unsigned) vmin) if (ptr && vmin && readlen > (unsigned) vmin)
readlen = vmin; readlen = vmin;
#endif
DWORD n = 0; DWORD n = 0;
if (readlen) if (readlen)
@ -1330,7 +1335,7 @@ fhandler_pty_master::close ()
ssize_t __stdcall ssize_t __stdcall
fhandler_pty_master::write (const void *ptr, size_t len) fhandler_pty_master::write (const void *ptr, size_t len)
{ {
int i; ssize_t ret;
char *p = (char *) ptr; char *p = (char *) ptr;
termios ti = tc ()->ti; termios ti = tc ()->ti;
@ -1339,18 +1344,10 @@ fhandler_pty_master::write (const void *ptr, size_t len)
return (ssize_t) bg; return (ssize_t) bg;
push_process_state process_state (PID_TTYOU); push_process_state process_state (PID_TTYOU);
line_edit_status status = line_edit (p++, len, ti, &ret);
for (i = 0; i < (int) len; i++) if (status > line_edit_signalled && status != line_edit_pipe_full)
{ ret = -1;
line_edit_status status = line_edit (p++, 1, ti); return ret;
if (status > line_edit_signalled)
{
if (status != line_edit_pipe_full)
i = -1;
break;
}
}
return i;
} }
void __reg3 void __reg3