[newlib-cygwin/cygwin-3_6-branch] Cygwin: pty: Prevent unintended conversion for cursor position report
Takashi Yano via Cygwin-cvs <[email protected]> Tue, 23 Jun 2026 01:14:13 +0000 (GMT)
| Newsgroups | gmane.os.cygwin.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://sourceware.org/git/gitweb.cgi?p=3Dnewlib-cygwin.git;h=3D1c5c82a215a= bcd44e5d82ee4128c468baf20821f commit 1c5c82a215abcd44e5d82ee4128c468baf20821f Author: Takashi Yano <[email protected]> Date: Mon Jun 8 22:21:19 2026 +0900 Cygwin: pty: Prevent unintended conversion for cursor position report =20 When the cursor position report ("CSI m;n R") is transferred from cyg-pipe to nat-pipe, it is undesirably converted into Fn3 key by pseudo console. This patch adds a workaround to prevent this unintended conversion for cursor position report by enabling ENABLE_VIRTUAL_TERMINAL_INPUT flag temporarily. =20 Addresses: https://cygwin.com/pipermail/cygwin/2026-June/259776.html Reported-by: Koichi Murase <[email protected]> Signed-off-by: Takashi Yano <[email protected]> Reviewed-by: Mark Geisert <[email protected]> (cherry picked from commit ad65bc9742f2c232a2b8744f69fc31923965d768) Diff: --- winsup/cygwin/fhandler/pty.cc | 53 ++++++++++++++++++++++++++++++++++= +++- winsup/cygwin/local_includes/tty.h | 1 + 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/fhandler/pty.cc b/winsup/cygwin/fhandler/pty.cc index f21647718..c3895aac8 100644 --- a/winsup/cygwin/fhandler/pty.cc +++ b/winsup/cygwin/fhandler/pty.cc @@ -2251,7 +2251,6 @@ fhandler_pty_master::write (const void *ptr, size_t l= en) ixput =3D 0; state =3D 0; wp_tid =3D 0; - get_ttyp ()->req_xfer_input =3D false; get_ttyp ()->pcon_start =3D false; break; } @@ -2265,6 +2264,20 @@ fhandler_pty_master::write (const void *ptr, size_t = len) && pp && pp->pgid =3D=3D get_ttyp ()->getpgid () && get_ttyp ()->pty_input_state_eq (tty::to_cyg)) { + if (!get_ttyp ()->req_xfer_input) + { + HANDLE pcon_handle_ready_event =3D + get_ttyp ()->pcon_handle_ready_event; + get_handle_from_process (get_ttyp ()->nat_pipe_owner_pid, + pcon_handle_ready_event); + if (pcon_handle_ready_event) + { + cygwait (pcon_handle_ready_event, INFINITE); + ResetEvent (pcon_handle_ready_event); + CloseHandle (pcon_handle_ready_event); + } + } + /* This accept_input() call is needed in order to transfer input which is not accepted yet to non-cygwin pipe. */ WaitForSingleObject (input_mutex, mutex_timeout); @@ -2278,6 +2291,7 @@ fhandler_pty_master::write (const void *ptr, size_t l= en) release_attach_mutex (); ReleaseMutex (input_mutex); } + get_ttyp ()->req_xfer_input =3D false; get_ttyp ()->pcon_start_pid =3D 0; } if (len =3D=3D 0) @@ -3567,6 +3581,8 @@ fhandler_pty_slave::setup_pseudoconsole () si.StartupInfo.hStdOutput =3D NULL; si.StartupInfo.hStdError =3D NULL; =20 + get_ttyp ()->pcon_handle_ready_event =3D + CreateEvent (&sec_none_nih, TRUE, FALSE, NULL); get_ttyp ()->pcon_activated =3D true; get_ttyp ()->pcon_start =3D true; get_ttyp ()->pcon_start_pid =3D myself->pid; @@ -3653,6 +3669,7 @@ skip_create: /* Discard the pseudo console handler container here. Reconstruct it temporary when it is needed. */ HeapFree (GetProcessHeap (), 0, hp); + SetEvent (get_ttyp ()->pcon_handle_ready_event); } =20 acquire_attach_mutex (mutex_timeout); @@ -3860,6 +3877,11 @@ fhandler_pty_slave::close_pseudoconsole (tty *ttyp, = DWORD force_switch_to) ttyp->pcon_start =3D false; ttyp->pcon_start_pid =3D 0; } + if (ttyp->pcon_handle_ready_event) + { + CloseHandle (ttyp->pcon_handle_ready_event); + ttyp->pcon_handle_ready_event =3D NULL; + } } else { /* Just detach from the pseudo console if I am not owner. */ @@ -4108,6 +4130,26 @@ fhandler_pty_slave::transfer_input (tty::xfer_dir di= r, HANDLE from, tty *ttyp, =20 UINT cp_from =3D 0, cp_to =3D 0; =20 + HANDLE h_pcon_in =3D NULL; + DWORD con_mode =3D 0; + if (ttyp->pcon_activated && dir =3D=3D tty::to_nat) + { + /* Escape sequences such as the cursor position report ("CSI m;n R") + are undesirably converted into an Fn3 key by pseudo console. + To privent this unintended conversion, temporarily enable + ENABLE_VIRTUAL_TERMINAL_INPUT flag. */ + h_pcon_in =3D + get_handle_from_process (ttyp->nat_pipe_owner_pid, ttyp->h_pcon_in); + if (h_pcon_in) + { + DWORD target_pid =3D ttyp->nat_pipe_owner_pid; + DWORD resume_pid =3D attach_console_temporarily (target_pid); + GetConsoleMode (h_pcon_in, &con_mode); + SetConsoleMode (h_pcon_in, con_mode | ENABLE_VIRTUAL_TERMINAL_INPUT); + resume_from_temporarily_attach (resume_pid); + } + } + if (dir =3D=3D tty::to_nat) { cp_from =3D ttyp->term_code_page; @@ -4222,6 +4264,15 @@ fhandler_pty_slave::transfer_input (tty::xfer_dir di= r, HANDLE from, tty *ttyp, } CloseHandle (to); =20 + if (h_pcon_in) + { + DWORD target_pid =3D ttyp->nat_pipe_owner_pid; + DWORD resume_pid =3D attach_console_temporarily (target_pid); + SetConsoleMode (h_pcon_in, con_mode); + resume_from_temporarily_attach (resume_pid); + CloseHandle (h_pcon_in); + } + ttyp->pty_input_state =3D dir; /* Fix input_available_event which indicates availability in cyg pipe. */ if (dir =3D=3D tty::to_nat) /* all data is transfered to nat pipe, diff --git a/winsup/cygwin/local_includes/tty.h b/winsup/cygwin/local_inclu= des/tty.h index 6e70a74cd..a03e965e4 100644 --- a/winsup/cygwin/local_includes/tty.h +++ b/winsup/cygwin/local_includes/tty.h @@ -120,6 +120,7 @@ private: pid_t pcon_start_pid; bool switch_to_nat_pipe; DWORD nat_pipe_owner_pid; + HANDLE pcon_handle_ready_event; UINT term_code_page; ULONGLONG fwd_last_time; bool fwd_not_empty;