In Windows 11, the command "rlwrap cmd" outputs garbaged screen.
This is because rlwrap treats text between NLs as a line, while
pseudo console sometimes ommits NL before "CISm;nH". This issue
does not happen in Windows 10. This patch fixes the issue.

Reviewed-by:
Signed-off-by: Takashi Yano <[email protected]>
---
 winsup/cygwin/fhandler/pty.cc | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/winsup/cygwin/fhandler/pty.cc b/winsup/cygwin/fhandler/pty.cc
index 3b0b4f073..5c02a4111 100644
--- a/winsup/cygwin/fhandler/pty.cc
+++ b/winsup/cygwin/fhandler/pty.cc
@@ -2775,6 +2775,40 @@ fhandler_pty_master::pty_master_fwd_thread (const 
master_fwd_thread_param_t *p)
            else
              state = 0;
 
+         /* Workaround for rlwrap */
+         /* rlwarp treats text between NLs as a line, however,
+            pseudo console somtimes ommits NL before "CSIm;nH". */
+         state = 0;
+         for (DWORD i = 0; i < rlen; i++)
+           if (state == 0 && outbuf[i] == '\033')
+             {
+               start_at = i;
+               state++;
+               continue;
+             }
+           else if (state == 1 && outbuf[i] == '[')
+             {
+               state++;
+               continue;
+             }
+           else if (state == 2 && (isdigit (outbuf[i]) || outbuf[i] == ';'))
+             continue;
+           else if (state == 2 && outbuf[i] == 'H')
+             {
+               /* Add "CSI H" before CR NL to avoid unexpected scroll */
+               const char *ins = "\033[H\r\n";
+               const int ins_len = strlen (ins);
+               memmove (&outbuf[start_at + ins_len], &outbuf[start_at],
+                        rlen - start_at);
+               memcpy (&outbuf[start_at], ins, ins_len);
+               rlen += ins_len;
+               i += ins_len;
+               state = 0;
+               continue;
+             }
+           else
+             state = 0;
+
          if (p->ttyp->term_code_page != CP_UTF8)
            {
              size_t nlen = NT_MAX_PATH;
-- 
2.51.0

Reply via email to