[newlib-cygwin/cygwin-3_6-branch] Cygwin: console: Fix NOFLSH behaviour a bit

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

commit 56dfa4db988c89ce9d216541e683cf65a294d8eb
Author: Takashi Yano <[email protected]>
Date:   Wed Jun 10 23:42:27 2026 +0900

    Cygwin: console: Fix NOFLSH behaviour a bit
   =20
    If you run "stty noflsh; cat" in "bash", and stop "cat" by Ctrl-C,
    a stray ^C is passed to "bash". The current code calls tcflush() if
    NOFLSH is not set, however, tcflush() is not called when NOFLSH is
    set. So, Ctrl-C remains in console input buffer. This should be
    discarded even in NOFLSH mode. This patch introduces a helper
    function discard_key_events() and call it to erase Ctrl-C in the
    console input buffer.
   =20
    Note that even with this patch, NOFLSH is not fully functional in
    console because the readahead buffer is unique to process, so it
    cannot be inherited to other processes. However, it should work
    intra process.
   =20
    Fixes: 118e51be1d04 ("(tty_min::kill_pgrp): Handle tty flush when signa=
l detected.")
    Signed-off-by: Takashi Yano <[email protected]>
    Reviewed-by: Mark Geisert <[email protected]>
    (cherry picked from commit 66324edf64a9ef0672e445c870b5a38c091f7b38)

Diff:
---
 winsup/cygwin/fhandler/console.cc       | 20 +++++++++++++++++---
 winsup/cygwin/fhandler/termios.cc       | 10 +++++++---
 winsup/cygwin/local_includes/fhandler.h |  2 ++
 winsup/cygwin/release/3.6.10            |  2 ++
 4 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/winsup/cygwin/fhandler/console.cc b/winsup/cygwin/fhandler/con=
sole.cc
index e27955629..acdccac60 100644
--- a/winsup/cygwin/fhandler/console.cc
+++ b/winsup/cygwin/fhandler/console.cc
@@ -1691,17 +1691,31 @@ out:
     discard_len =3D 0;
   if (discard_len)
     {
-      DWORD discarded;
       acquire_attach_mutex (mutex_timeout);
       DWORD resume_pid =3D attach_console (con.owner);
-      ReadConsoleInputW (get_handle (), input_rec, discard_len, &discarded=
);
+      discard_key_events (discard_len);
       detach_console (resume_pid, con.owner);
       release_attach_mutex ();
-      con.num_processed -=3D min (con.num_processed, discarded);
     }
   return stat;
 }
=20
+void
+fhandler_console::discard_key_events (size_t n)
+{
+  DWORD discarded =3D 0;
+  INPUT_RECORD input_rec[INREC_SIZE];
+  DWORD n1 =3D min (INREC_SIZE, n);
+  while (n)
+    {
+      ReadConsoleInputW (get_handle (), input_rec, n1, &n1);
+      n -=3D n1;
+      discarded +=3D n1;
+      n1 =3D min (INREC_SIZE, n);
+    }
+  con.num_processed -=3D min (con.num_processed, discarded);
+}
+
 bool
 dev_console::fillin (HANDLE h)
 {
diff --git a/winsup/cygwin/fhandler/termios.cc b/winsup/cygwin/fhandler/ter=
mios.cc
index e2822c3ee..650807850 100644
--- a/winsup/cygwin/fhandler/termios.cc
+++ b/winsup/cygwin/fhandler/termios.cc
@@ -666,9 +666,13 @@ fhandler_termios::sigflush ()
      be NULL while this is alive.  However, we can conceivably close a
      ctty while exiting and that will zero this. */
   if ((!have_execed || have_execed_cygwin) && tc ()
-      && (tc ()->getpgid () =3D=3D myself->pgid)
-      && !(tc ()->ti.c_lflag & NOFLSH))
-    tcflush (TCIFLUSH);
+      && (tc ()->getpgid () =3D=3D myself->pgid))
+    {
+      if (!(tc ()->ti.c_lflag & NOFLSH))
+	tcflush (TCIFLUSH);
+      else
+	discard_key_events (1);
+    }
 }
=20
 pid_t
diff --git a/winsup/cygwin/local_includes/fhandler.h b/winsup/cygwin/local_=
includes/fhandler.h
index 3a4bfac17..1abc2ece8 100644
--- a/winsup/cygwin/local_includes/fhandler.h
+++ b/winsup/cygwin/local_includes/fhandler.h
@@ -1982,6 +1982,7 @@ class fhandler_termios: public fhandler_base
   virtual off_t lseek (off_t, int);
   pid_t tcgetsid ();
   virtual int fstat (struct stat *buf);
+  virtual void discard_key_events (size_t n) {}
=20
   fhandler_termios (void *) {}
=20
@@ -2360,6 +2361,7 @@ private:
   void wpbuf_put (char c);
   void wpbuf_send ();
   int fstat (struct stat *buf);
+  void discard_key_events (size_t n);
=20
   class console_unit
   {
diff --git a/winsup/cygwin/release/3.6.10 b/winsup/cygwin/release/3.6.10
index 597cf7bdb..c583e7746 100644
--- a/winsup/cygwin/release/3.6.10
+++ b/winsup/cygwin/release/3.6.10
@@ -20,3 +20,5 @@ Fixes:
 - Fix CR/NL conversion in accept_input() for pty.
=20
 - Ensure the cons_master_thread runs only when it is really supposed to.
+
+- Fix NOFLSH behaviour in console a bit.