[PATCH 4/6] Cygwin: pty: Apply line_edit() for transferred input to to_cyg
Takashi Yano
takashi.yano@nifty.ne.jp
Tue Mar 17 13:56:38 GMT 2026
Sorry, this patch has a bug. Please wait a while...
On Tue, 17 Mar 2026 21:23:08 +0900
Takashi Yano wrote:
> The typeahead input while non-cygwin app is running is put into
> the pipe directly by transfer_input(). So, if the shell sets the
> terminal canonical mode, erase char (such as backspace) fails to
> erase chars transferred by transfer_input(). With this patch,
> transferred input in the pipe is read and passed to line_edit()
> to handle erase chars such as VERASE, VKILL, etc.
>
> Fixes: 10d083c745dd ("Cygwin: pty: Inherit typeahead data between two input pipes.")
> Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
> Reviewed-by:
> ---
> winsup/cygwin/fhandler/pty.cc | 40 +++++++++++++++++++++++--
> winsup/cygwin/local_includes/fhandler.h | 2 ++
> winsup/cygwin/local_includes/tty.h | 1 +
> winsup/cygwin/tty.cc | 1 +
> 4 files changed, 41 insertions(+), 3 deletions(-)
>
> diff --git a/winsup/cygwin/fhandler/pty.cc b/winsup/cygwin/fhandler/pty.cc
> index bde88ab0e..1be853993 100644
> --- a/winsup/cygwin/fhandler/pty.cc
> +++ b/winsup/cygwin/fhandler/pty.cc
> @@ -2734,6 +2734,28 @@ reply:
> return 0;
> }
>
> +void
> +fhandler_pty_master::apply_line_edit_to_transferred_input ()
> +{
> + const size_t pipesize = fhandler_pty_common::pipesize;
> + if (get_ttyp ()->input_transferred_to_cyg)
> + {
> + char buf[pipesize];
> + DWORD n;
> + ReadFile (from_master, buf, pipesize, &n, NULL);
> + char *p = buf;
> + while (n)
> + {
> + ssize_t ret;
> + line_edit (p, n, get_ttyp ()->ti, &ret);
> + n -= ret;
> + p += ret;
> + }
> + SetEvent (input_available_event);
> + get_ttyp ()->input_transferred_to_cyg = false;
> + }
> +}
> +
> static DWORD
> pty_master_thread (VOID *arg)
> {
> @@ -2924,8 +2946,15 @@ fhandler_pty_master::pty_master_fwd_thread (const master_fwd_thread_param_t *p)
> {
> p->ttyp->fwd_last_time = GetTickCount64 ();
> DWORD n;
> - p->ttyp->fwd_not_empty =
> - ::bytes_available (n, p->from_slave_nat) && n;
> + while (true)
> + {
> + p->ttyp->fwd_not_empty =
> + ::bytes_available (n, p->from_slave_nat) && n;
> + if (p->ttyp->fwd_not_empty || p->ttyp->stop_fwd_thread)
> + break;
> + p->master->apply_line_edit_to_transferred_input ();
> + Sleep (1);
> + }
> if (!ReadFile (p->from_slave_nat, outbuf, NT_MAX_PATH, &rlen, NULL))
> {
> termios_printf ("ReadFile for forwarding failed, %E");
> @@ -4005,6 +4034,7 @@ fhandler_pty_master::get_master_fwd_thread_param (master_fwd_thread_param_t *p)
> p->from_slave_nat = from_slave_nat;
> p->output_mutex = output_mutex;
> p->ttyp = get_ttyp ();
> + p->master = this;
> SetEvent (thread_param_copied_event);
> }
>
> @@ -4193,7 +4223,11 @@ fhandler_pty_slave::transfer_input (tty::xfer_dir dir, HANDLE from, tty *ttyp,
> so no data available in cyg pipe. */
> ResetEvent (input_available_event);
> else if (transfered) /* There is data transfered to cyg pipe. */
> - SetEvent (input_available_event);
> + {
> + ttyp->input_transferred_to_cyg = true;
> + while (ttyp->input_transferred_to_cyg)
> + yield ();
> + }
> ttyp->pty_input_state = dir;
> ttyp->discard_input = false;
> }
> diff --git a/winsup/cygwin/local_includes/fhandler.h b/winsup/cygwin/local_includes/fhandler.h
> index 16f55b4f7..f24ae199e 100644
> --- a/winsup/cygwin/local_includes/fhandler.h
> +++ b/winsup/cygwin/local_includes/fhandler.h
> @@ -2551,6 +2551,7 @@ public:
> HANDLE from_slave_nat;
> HANDLE output_mutex;
> tty *ttyp;
> + fhandler_pty_master *master;
> };
> private:
> int pktmode; // non-zero if pty in a packet mode.
> @@ -2627,6 +2628,7 @@ public:
> void get_master_thread_param (master_thread_param_t *p);
> void get_master_fwd_thread_param (master_fwd_thread_param_t *p);
> bool need_send_ctrl_c_event ();
> + void apply_line_edit_to_transferred_input ();
> };
>
> class fhandler_dev_null: public fhandler_base
> diff --git a/winsup/cygwin/local_includes/tty.h b/winsup/cygwin/local_includes/tty.h
> index 9485e24c5..6e4460e30 100644
> --- a/winsup/cygwin/local_includes/tty.h
> +++ b/winsup/cygwin/local_includes/tty.h
> @@ -141,6 +141,7 @@ private:
> xfer_dir pty_input_state;
> bool discard_input;
> bool stop_fwd_thread;
> + volatile bool input_transferred_to_cyg;
>
> public:
> HANDLE from_master_nat () const { return _from_master_nat; }
> diff --git a/winsup/cygwin/tty.cc b/winsup/cygwin/tty.cc
> index acc21c0ca..046c02ad1 100644
> --- a/winsup/cygwin/tty.cc
> +++ b/winsup/cygwin/tty.cc
> @@ -255,6 +255,7 @@ tty::init ()
> last_sig = 0;
> discard_input = false;
> stop_fwd_thread = false;
> + input_transferred_to_cyg = false;
> }
>
> HANDLE
> --
> 2.51.0
>
--
Takashi Yano <takashi.yano@nifty.ne.jp>
More information about the Cygwin-patches
mailing list