[PATCH v5 3/3] Cygwin: pty: Add workaround for handling of Ctrl-H when pcon enabled
Johannes Schindelin
Johannes.Schindelin@gmx.de
Mon Mar 16 09:03:58 GMT 2026
Hi Takashi,
On Thu, 12 Mar 2026, Takashi Yano wrote:
> OpenConsole.exe has a bug(?) that the Ctrl-H is translated into
> Ctrl-Backspace (not Backspace). This is a workaround for that issue
> which pushes the Ctrl-H as a ConsoleInput event.
I still consider this work-around too brittle to merge.
> Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
> Reviewed-by:
> ---
> winsup/cygwin/fhandler/pty.cc | 44 +++++++++++++++++++++++++++++++++++
> 1 file changed, 44 insertions(+)
>
> diff --git a/winsup/cygwin/fhandler/pty.cc b/winsup/cygwin/fhandler/pty.cc
> index bd5c24625..6b353c954 100644
> --- a/winsup/cygwin/fhandler/pty.cc
> +++ b/winsup/cygwin/fhandler/pty.cc
> @@ -2513,9 +2513,53 @@ fhandler_pty_master::write (const void *ptr, size_t len)
> }
> }
>
> + /* OpenConsole.exe has a bug(?) that Ctrl-H is translated into
> + Ctrl-Backspace (not Backspace). The following code is a
> + workaround for that issue. */
> + char *bs_pos = (char *) memchr (buf, '\010' /* ^H */, nlen);
> + HANDLE pcon_owner = NULL;
> + HANDLE h_pcon_in = NULL;
> + DWORD resume_pid = 0;
> + if (bs_pos)
> + {
> + pcon_owner = OpenProcess (PROCESS_DUP_HANDLE, FALSE,
> + get_ttyp ()->nat_pipe_owner_pid);
> + DuplicateHandle (pcon_owner, get_ttyp ()->h_pcon_in,
> + GetCurrentProcess (), &h_pcon_in,
> + 0, FALSE, DUPLICATE_SAME_ACCESS);
> + resume_pid =
> + attach_console_temporarily (get_ttyp()->nat_pipe_owner_pid);
> + }
> +
> DWORD n;
> + while (bs_pos)
> + {
> + if (bs_pos - buf > 0)
> + WriteFile (to_slave_nat, buf, bs_pos - buf, &n, NULL);
> + INPUT_RECORD r;
> + r.EventType = KEY_EVENT;
> + r.Event.KeyEvent.bKeyDown = 1;
> + r.Event.KeyEvent.wRepeatCount = 0;
> + r.Event.KeyEvent.wVirtualKeyCode = 0;
> + r.Event.KeyEvent.wVirtualScanCode = 0;
> + r.Event.KeyEvent.uChar.AsciiChar = '\010'; /* ^H */
> + r.Event.KeyEvent.dwControlKeyState = LEFT_CTRL_PRESSED;
> + WriteConsoleInput(h_pcon_in, &r, 1, &n);
> + r.Event.KeyEvent.bKeyDown = 0;
> + WriteConsoleInput(h_pcon_in, &r, 1, &n);
> + nlen -= bs_pos - buf + 1;
> + buf = bs_pos + 1;
> + bs_pos = (char *) memchr (buf, '\010' /* ^H */, nlen);
> + }
This still has timing issues because the design is essentially assuming
that it is the only process using that Console, in a single-threaded
scenario. Such a scenario is increasingly rare nowadays.
Besides, OpenConsole.exe _still_ is open source, and therefore it is still
a better idea to fix the issue properly.
I had a go at it (assisted by Claude Opus 4.6):
https://github.com/dscho/terminal/commit/1b3d526428c86b9357275f11149d736f8928d64b
Here is a build including an artifact for that fix in case you still have
trouble building OpenConsole.exe locally:
https://github.com/dscho/terminal/actions/runs/23135369360
Let's prefer a proper fix if at all possible.
Ciao,
Johannes
> if (nlen)
> WriteFile (to_slave_nat, buf, nlen, &n, NULL);
> +
> + if (resume_pid)
> + resume_from_temporarily_attach (resume_pid);
> + if (h_pcon_in)
> + CloseHandle(h_pcon_in);
> + if (pcon_owner)
> + CloseHandle(pcon_owner);
> ReleaseMutex (input_mutex);
>
> return orig_len;
> --
> 2.51.0
>
>
More information about the Cygwin-patches
mailing list