[newlib-cygwin] Cygwin: pty: Handle CSIc in pcon_start phase
Takashi Yano via Cygwin-cvs <[email protected]> Tue, 7 Apr 2026 10:15:47 +0000 (GMT)
| Newsgroups | gmane.os.cygwin.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://sourceware.org/git/gitweb.cgi?p=3Dnewlib-cygwin.git;h=3D9c2ea0805fb= f4c183c9b7ee4d4e4d7c57044e7bf commit 9c2ea0805fbf4c183c9b7ee4d4e4d7c57044e7bf Author: Takashi Yano <[email protected]> Date: Tue Apr 7 08:59:52 2026 +0900 Cygwin: pty: Handle CSIc in pcon_start phase =20 OpenConsole.exe sends CSIc in addition to CSI6n in pcon_start phase (in initialization of pseudo console). This patch adds code to handle CSIc and its response. =20 Signed-off-by: Takashi Yano <[email protected]> Reviewed-by: Johannes Schindelin <[email protected]> Diff: --- winsup/cygwin/fhandler/pty.cc | 60 +++++++++++++++++++++++++----= ---- winsup/cygwin/local_includes/fhandler.h | 1 + winsup/cygwin/local_includes/tty.h | 1 + winsup/cygwin/tty.cc | 1 + 4 files changed, 49 insertions(+), 14 deletions(-) diff --git a/winsup/cygwin/fhandler/pty.cc b/winsup/cygwin/fhandler/pty.cc index d6b783ae0..e9191aaad 100644 --- a/winsup/cygwin/fhandler/pty.cc +++ b/winsup/cygwin/fhandler/pty.cc @@ -1349,7 +1349,8 @@ fhandler_pty_slave::reset_switch_to_nat_pipe (void) } if (isHybrid) return; - if (get_ttyp ()->pcon_start) /* Pseudo console initialization is on goin= g */ + if (get_ttyp ()->pcon_start || get_ttyp ()->pcon_start_csi_c) + /* Pseudo console initialization is on going */ return; DWORD wait_ret =3D WaitForSingleObject (pipe_sw_mutex, mutex_timeout); if (wait_ret =3D=3D WAIT_TIMEOUT) @@ -1456,7 +1457,8 @@ fhandler_pty_common::to_be_read_from_nat_pipe (void) to CSI6n should be go to cyg-pipe. So, wait for pcon_start and return false. */ while (WaitForSingleObject (pipe_sw_mutex, 0) =3D=3D WAIT_TIMEOUT) - if (get_ttyp ()->pcon_start || get_ttyp ()->pcon_start_pid) + if (get_ttyp ()->pcon_start || get_ttyp ()->pcon_start_csi_c + || get_ttyp ()->pcon_start_pid) return false; else yield (); @@ -1780,7 +1782,7 @@ fhandler_pty_slave::tcgetattr (struct termios *t) if (cfd->get_major () =3D=3D DEV_PTYM_MAJOR && cfd->get_minor () =3D=3D get_minor ()) { - if (get_ttyp ()->pcon_start) + if (get_ttyp ()->pcon_start || get_ttyp ()->pcon_start_csi_c) t->c_lflag &=3D ~(ICANON | ECHO); if (get_ttyp ()->pcon_activated) t->c_iflag &=3D ~ICRNL; @@ -2362,13 +2364,16 @@ fhandler_pty_master::write (const void *ptr, size_t= len) =20 get_ttyp ()->discard_input =3D false; =20 - if (get_ttyp ()->pcon_start) + int pcon_start_mode =3D + get_ttyp ()->pcon_start ? 1 : (get_ttyp ()->pcon_start_csi_c ? 2 : 0); + if (pcon_start_mode) { /* Reaches here when pseudo console initialization is on going. */ /* Pseudo condole support uses "CSI6n" to get cursor position. If the reply for "CSI6n" is divided into multiple writes, pseudo console sometimes does not recognize it. Therefore, put them together into wpbuf and write all at once. */ - static const int wpbuf_len =3D strlen ("\033[32768;32868R"); + /* Do the same for CSIc. */ + static const int wpbuf_len =3D 64; /* Enough space for CSIc response= */ static char wpbuf[wpbuf_len]; static int ixput =3D 0; static int state =3D 0; @@ -2404,7 +2409,15 @@ fhandler_pty_master::write (const void *ptr, size_t = len) len =3D orig_len - i - 1; ptr =3D p + i + 1; if (state =3D=3D 1 && wp_tid =3D=3D _my_tls.thread_id && p[i] =3D=3D 'R= ') - state =3D 2; + { + get_ttyp ()->pcon_start =3D false; + state =3D 2; + } + if (state =3D=3D 1 && wp_tid =3D=3D _my_tls.thread_id && p[i] =3D=3D 'c= ') + { + get_ttyp ()->pcon_start_csi_c =3D false; + state =3D 2; + } if (state =3D=3D 2) { /* req_xfer_input is true if "ESC[6n" was sent just for @@ -2416,13 +2429,14 @@ fhandler_pty_master::write (const void *ptr, size_t= len) state =3D 0; wp_tid =3D 0; get_ttyp ()->req_xfer_input =3D false; - get_ttyp ()->pcon_start =3D false; - break; + if (!get_ttyp ()->pcon_start && !get_ttyp ()->pcon_start_csi_c) + break; } } ReleaseMutex (input_mutex); =20 - if (!get_ttyp ()->pcon_start) + if (pcon_start_mode + && !get_ttyp ()->pcon_start && !get_ttyp ()->pcon_start_csi_c) { /* Pseudo console initialization has been done in above code. */ pinfo pp (get_ttyp ()->pcon_start_pid); if (get_ttyp ()->switch_to_nat_pipe @@ -2580,7 +2594,7 @@ fhandler_pty_master::tcgetattr (struct termios *t) { *t =3D cygwin_shared->tty[get_minor ()]->ti; /* Workaround for rlwrap v0.40 or later */ - if (get_ttyp ()->pcon_start) + if (get_ttyp ()->pcon_start || get_ttyp ()->pcon_start_csi_c) t->c_lflag &=3D ~(ICANON | ECHO); if (get_ttyp ()->pcon_activated) t->c_iflag &=3D ~ICRNL; @@ -2947,8 +2961,10 @@ pty_master_thread (VOID *arg) #define CONSOLE_HELPER "\\bin\\cygwin-console-helper.exe" #define CONSOLE_HELPER_LEN (sizeof (CONSOLE_HELPER) - 1) =20 -inline static DWORD -workarounds_for_pseudo_console_output (char *outbuf, DWORD rlen) +DWORD +fhandler_pty_master::workarounds_for_pseudo_console_output (char *outbuf, + DWORD rlen, + tty *ttyp) { int state =3D 0; int start_at =3D 0; @@ -2957,6 +2973,7 @@ workarounds_for_pseudo_console_output (char *outbuf, = DWORD rlen) int arg =3D 0; bool saw_greater_than_sign =3D false; bool saw_question_mark =3D false; + static bool in_pcon_start =3D false; for (DWORD i=3D0; i<rlen; i++) if (state =3D=3D 0 && outbuf[i] =3D=3D '\033') { @@ -3038,8 +3055,21 @@ workarounds_for_pseudo_console_output (char *outbuf,= DWORD rlen) start_at =3D i; state =3D 1; } + else if (arg =3D=3D 6 && outbuf[i] =3D=3D 'n' && ttyp->pcon_start) + { + in_pcon_start =3D true; + state =3D 0; + } + else if (arg =3D=3D 0 && outbuf[i] =3D=3D 'c' && in_pcon_start) + { + ttyp->pcon_start_csi_c =3D true; + state =3D 0; + } else - state =3D 0; + { + in_pcon_start =3D false; + state =3D 0; + } =20 if (state < 2) { @@ -3097,6 +3127,7 @@ workarounds_for_pseudo_console_output (char *outbuf, = DWORD rlen) is_osc =3D false; saw_greater_than_sign =3D false; saw_question_mark =3D false; + in_pcon_start =3D false; arg =3D 0; state =3D 0; } @@ -3155,7 +3186,8 @@ wait_event: char *ptr =3D outbuf; if (p->ttyp->pcon_activated) { - wlen =3D rlen =3D workarounds_for_pseudo_console_output (outbuf, rlen); + wlen =3D rlen =3D + workarounds_for_pseudo_console_output (outbuf, rlen, p->ttyp); =20 if (p->ttyp->term_code_page !=3D CP_UTF8) { diff --git a/winsup/cygwin/local_includes/fhandler.h b/winsup/cygwin/local_= includes/fhandler.h index 974e39698..4f5605524 100644 --- a/winsup/cygwin/local_includes/fhandler.h +++ b/winsup/cygwin/local_includes/fhandler.h @@ -2580,6 +2580,7 @@ public: =20 static DWORD pty_master_thread (const master_thread_param_t *p); static DWORD pty_master_fwd_thread (const master_fwd_thread_param_t *p); + static DWORD workarounds_for_pseudo_console_output (char *, DWORD, tty *= ); int process_slave_output (char *buf, size_t len, int pktmode_on); void doecho (const void *str, DWORD len); int accept_input (); diff --git a/winsup/cygwin/local_includes/tty.h b/winsup/cygwin/local_inclu= des/tty.h index 962697782..4fbebd820 100644 --- a/winsup/cygwin/local_includes/tty.h +++ b/winsup/cygwin/local_includes/tty.h @@ -122,6 +122,7 @@ private: bool pcon_activated; bool pcon_start; pid_t pcon_start_pid; + bool pcon_start_csi_c; bool switch_to_nat_pipe; DWORD nat_pipe_owner_pid; UINT term_code_page; diff --git a/winsup/cygwin/tty.cc b/winsup/cygwin/tty.cc index 0c49dc2bd..40b270309 100644 --- a/winsup/cygwin/tty.cc +++ b/winsup/cygwin/tty.cc @@ -243,6 +243,7 @@ tty::init () fwd_not_empty =3D false; pcon_start =3D false; pcon_start_pid =3D 0; + pcon_start_csi_c =3D false; pcon_cap_checked =3D false; has_csi6n =3D false; need_invisible_console =3D false;