[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