Previsouly, CSI6n was not handled correctly if the some sequences
are appended after the responce for CSI6n. Especially, if the
appended sequence is a ESC sequence, which is longer than the
expected maximum length of the CSI6n responce, the sequence will
not be written atomically. With this patch, pcon_start state
is cleared at the end of CSI6n responce, and appended sequence
will be written outside of the CSI&n handling block.

Fixes: f20641789427 ("Cygwin: pty: Reduce unecessary input transfer.")
Signed-off-by: Takashi Yano <[email protected]>
Reviewed-by:
---
 winsup/cygwin/fhandler/pty.cc | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/winsup/cygwin/fhandler/pty.cc b/winsup/cygwin/fhandler/pty.cc
index 838be4a2b..c1e03db41 100644
--- a/winsup/cygwin/fhandler/pty.cc
+++ b/winsup/cygwin/fhandler/pty.cc
@@ -2137,6 +2137,8 @@ fhandler_pty_master::close (int flag)
 ssize_t
 fhandler_pty_master::write (const void *ptr, size_t len)
 {
+  size_t towrite = len;
+
   ssize_t ret;
   char *p = (char *) ptr;
   termios &ti = tc ()->ti;
@@ -2171,6 +2173,8 @@ fhandler_pty_master::write (const void *ptr, size_t len)
            }
          if (state == 1)
            {
+             towrite--;
+             ptr = p + i + 1;
              if (ixput < wpbuf_len)
                wpbuf[ixput++] = p[i];
              else
@@ -2184,7 +2188,10 @@ fhandler_pty_master::write (const void *ptr, size_t len)
          else
            line_edit (p + i, 1, ti, &ret);
          if (state == 1 && p[i] == 'R')
-           state = 2;
+           {
+             state = 2;
+             break;
+           }
        }
       if (state == 2)
        {
@@ -2220,8 +2227,8 @@ fhandler_pty_master::write (const void *ptr, size_t len)
            }
          get_ttyp ()->pcon_start_pid = 0;
        }
-
-      return len;
+      if (towrite == 0)
+       return len;
     }
 
   /* Write terminal input to to_slave_nat pipe instead of output_handle
@@ -2233,15 +2240,14 @@ fhandler_pty_master::write (const void *ptr, size_t len)
         is activated. */
       tmp_pathbuf tp;
       char *buf = (char *) ptr;
-      size_t nlen = len;
+      size_t nlen = towrite;
       if (get_ttyp ()->term_code_page != CP_UTF8)
        {
          static mbstate_t mbp;
          buf = tp.c_get ();
          nlen = NT_MAX_PATH;
-         convert_mb_str (CP_UTF8, buf, &nlen,
-                         get_ttyp ()->term_code_page, (const char *) ptr, len,
-                         &mbp);
+         convert_mb_str (CP_UTF8, buf, &nlen, get_ttyp ()->term_code_page,
+                         (const char *) ptr, towrite, &mbp);
        }
 
       for (size_t i = 0; i < nlen; i++)
-- 
2.51.0

Reply via email to