[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