[newlib-cygwin] Cygwin: console: Fix typeahead input for bash

Takashi Yano via Cygwin-cvs <[email protected]> Wed, 24 Jun 2026 12:45:51 +0000 (GMT)
Newsgroups gmane.os.cygwin.cvs
Message-ID <[email protected]>
https://sourceware.org/git/gitweb.cgi?p=3Dnewlib-cygwin.git;h=3Dfac73911f5a=
0732922168df216dc84cc730fe144

commit fac73911f5a0732922168df216dc84cc730fe144
Author: Takashi Yano <[email protected]>
Date:   Thu Jun 11 00:00:34 2026 +0900

    Cygwin: console: Fix typeahead input for bash
   =20
    Currently, following misbehaviour occurs in bash.
      1) Run "sleep 10".
      2) Type "cmd<enter>ps<enter>" while "sleep is running".
      3) After "sleep" ends, "ps" does not run in "cmd".
      4) exit from "cmd". Then, "ps" is executed.
    This is because process_input_message() handles all the events in
    the console input buffer, and stores key input into readahead buffer.
    However, since the readahead buffer is unique to process, "cmd"
    cannot read it. Since "ps<enter>" is stored in bash's readahead
    buffer, it is executed by bash after "cmd" exits. With this patch,
    process_input_message() handles only the requested amount of events
    by read().
   =20
    Fixes: 8382778cdb57 ("Cygwin: console: fix select() behaviour")
    Signed-off-by: Takashi Yano <[email protected]>
    Reviewed-by: Mark Geisert <[email protected]>

Diff:
---
 winsup/cygwin/fhandler/console.cc       | 15 ++++++++++++---
 winsup/cygwin/local_includes/fhandler.h |  2 +-
 winsup/cygwin/release/3.6.10            |  2 ++
 winsup/cygwin/select.cc                 |  2 +-
 4 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/winsup/cygwin/fhandler/console.cc b/winsup/cygwin/fhandler/con=
sole.cc
index 9ac492980..1e4367816 100644
--- a/winsup/cygwin/fhandler/console.cc
+++ b/winsup/cygwin/fhandler/console.cc
@@ -1273,7 +1273,7 @@ wait_retry:
=20
       int ret;
       acquire_input_mutex (mutex_timeout);
-      ret =3D process_input_message ();
+      ret =3D process_input_message (buflen);
       switch (ret)
 	{
 	case input_error:
@@ -1328,9 +1328,10 @@ sig_exit:
 }
=20
 fhandler_console::input_states
-fhandler_console::process_input_message (void)
+fhandler_console::process_input_message (size_t len)
 {
   char tmp[60];
+  size_t num_chars =3D 0;
=20
   if (!shared_console_info[unit])
     return input_error;
@@ -1717,6 +1718,7 @@ fhandler_console::process_input_message (void)
 	  continue;
 	}
=20
+      num_chars +=3D nread;
       if (toadd)
 	{
 	  ssize_t ret;
@@ -1734,15 +1736,22 @@ fhandler_console::process_input_message (void)
 		goto out;
 	    }
 	}
+      /* len =3D=3D 0 if called from select.cc:peek_console() */
+      if (len && num_chars >=3D len)
+	goto out;
     }
 out:
+  if (len =3D=3D 0)
+    /* If len =3D=3D 0, cancel reading from console input buffer.
+       Clear readahead buffer. */
+    eat_readahead (-1);
   /* Discard processed recored. */
   DWORD discard_len =3D min (total_read, i + 1);
   /* If input is signalled, do not discard input here because
      tcflush() is already called from line_edit(). */
   if (stat =3D=3D input_signalled && !(ti->c_lflag & NOFLSH))
     discard_len =3D 0;
-  if (discard_len)
+  if (discard_len && (len || stat !=3D input_ok))
     {
       acquire_attach_mutex (mutex_timeout);
       DWORD resume_pid =3D attach_console (con.owner);
diff --git a/winsup/cygwin/local_includes/fhandler.h b/winsup/cygwin/local_=
includes/fhandler.h
index 98bec80c6..6c358a570 100644
--- a/winsup/cygwin/local_includes/fhandler.h
+++ b/winsup/cygwin/local_includes/fhandler.h
@@ -2327,7 +2327,7 @@ private:
     fh->copy_from (this);
     return fh;
   }
-  input_states process_input_message ();
+  input_states process_input_message (size_t len);
   bg_check_types bg_check (int sig, bool dontsignal =3D false);
   void setup_io_mutex (void);
   DWORD __acquire_input_mutex (const char *fn, int ln, DWORD ms);
diff --git a/winsup/cygwin/release/3.6.10 b/winsup/cygwin/release/3.6.10
index c583e7746..3f4b25abf 100644
--- a/winsup/cygwin/release/3.6.10
+++ b/winsup/cygwin/release/3.6.10
@@ -22,3 +22,5 @@ Fixes:
 - Ensure the cons_master_thread runs only when it is really supposed to.
=20
 - Fix NOFLSH behaviour in console a bit.
+
+- Fix typeahead input in console for bash.
diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc
index 523c46ee6..b72083447 100644
--- a/winsup/cygwin/select.cc
+++ b/winsup/cygwin/select.cc
@@ -1172,7 +1172,7 @@ peek_console (select_record *me, bool)
 	  if (!r || !events_read)
 	    break;
 	}
-      if (fhandler_console::input_winch =3D=3D fh->process_input_message ()
+      if (fhandler_console::input_winch =3D=3D fh->process_input_message (=
0)
 	  && global_sigs[SIGWINCH].sa_handler !=3D SIG_IGN
 	  && global_sigs[SIGWINCH].sa_handler !=3D SIG_DFL)
 	{