[PATCH] Cygwin: console: Add missing guard regarding attach_mutex.

Takashi Yano takashi.yano@nifty.ne.jp
Mon Jan 25 09:18:11 GMT 2021


- The commit a5333345 did not fix the problem enough. This patch
  provides additional guard for the issue.
---
 winsup/cygwin/fhandler_console.cc | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc
index 49963e719..02d0ac052 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -439,14 +439,18 @@ fhandler_console::set_raw_win32_keyboard_mode (bool new_mode)
 void
 fhandler_console::set_cursor_maybe ()
 {
+  acquire_attach_mutex (INFINITE);
   con.fillin (get_output_handle ());
+  release_attach_mutex ();
   /* Nothing to do for xterm compatible mode. */
   if (wincap.has_con_24bit_colors () && !con_is_legacy)
     return;
   if (con.dwLastCursorPosition.X != con.b.dwCursorPosition.X ||
       con.dwLastCursorPosition.Y != con.b.dwCursorPosition.Y)
     {
+      acquire_attach_mutex (INFINITE);
       SetConsoleCursorPosition (get_output_handle (), con.b.dwCursorPosition);
+      release_attach_mutex ();
       con.dwLastCursorPosition = con.b.dwCursorPosition;
     }
 }
@@ -536,6 +540,7 @@ fhandler_console::read (void *pv, size_t& buflen)
 	}
 
       set_cursor_maybe (); /* to make cursor appear on the screen immediately */
+wait_retry:
       switch (cygwait (get_handle (), timeout))
 	{
 	case WAIT_OBJECT_0:
@@ -551,6 +556,15 @@ fhandler_console::read (void *pv, size_t& buflen)
 	  buflen = (size_t) -1;
 	  return;
 	default:
+	  if (GetLastError () == ERROR_INVALID_HANDLE)
+	    { /* Confirm the handle is still valid */
+	      DWORD mode;
+	      acquire_attach_mutex (INFINITE);
+	      BOOL res = GetConsoleMode (get_handle (), &mode);
+	      release_attach_mutex ();
+	      if (res)
+		goto wait_retry;
+	    }
 	  goto err;
 	}
 
@@ -1243,7 +1257,9 @@ fhandler_console::ioctl (unsigned int cmd, void *arg)
       case TIOCGWINSZ:
 	int st;
 
+	acquire_attach_mutex (INFINITE);
 	st = con.fillin (get_output_handle ());
+	release_attach_mutex ();
 	if (st)
 	  {
 	    /* *not* the buffer size, the actual screen size... */
@@ -1301,12 +1317,15 @@ fhandler_console::ioctl (unsigned int cmd, void *arg)
 	  DWORD n;
 	  int ret = 0;
 	  INPUT_RECORD inp[INREC_SIZE];
+	  acquire_attach_mutex (INFINITE);
 	  if (!PeekConsoleInputW (get_handle (), inp, INREC_SIZE, &n))
 	    {
 	      set_errno (EINVAL);
+	      release_attach_mutex ();
 	      release_output_mutex ();
 	      return -1;
 	    }
+	  release_attach_mutex ();
 	  bool saw_eol = false;
 	  for (DWORD i=0; i<n; i++)
 	    if (inp[i].EventType == KEY_EVENT &&
@@ -1357,11 +1376,13 @@ fhandler_console::tcflush (int queue)
   if (queue == TCIFLUSH
       || queue == TCIOFLUSH)
     {
+      acquire_attach_mutex (INFINITE);
       if (!FlushConsoleInputBuffer (get_handle ()))
 	{
 	  __seterrno ();
 	  res = -1;
 	}
+      release_attach_mutex ();
     }
   return res;
 }
@@ -1375,12 +1396,14 @@ fhandler_console::output_tcsetattr (int, struct termios const *t)
   DWORD flags = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT;
 
   DWORD oflags;
+  acquire_attach_mutex (INFINITE);
   GetConsoleMode (get_output_handle (), &oflags);
   if (wincap.has_con_24bit_colors () && !con_is_legacy
       && (oflags & ENABLE_VIRTUAL_TERMINAL_PROCESSING))
     flags |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
 
   int res = SetConsoleMode (get_output_handle (), flags) ? 0 : -1;
+  release_attach_mutex ();
   if (res)
     __seterrno_from_win_error (GetLastError ());
   release_output_mutex ();
@@ -1398,6 +1421,7 @@ fhandler_console::input_tcsetattr (int, struct termios const *t)
 
   DWORD oflags;
 
+  acquire_attach_mutex (INFINITE);
   if (!GetConsoleMode (get_handle (), &oflags))
     oflags = 0;
   DWORD flags = 0;
@@ -1456,6 +1480,7 @@ fhandler_console::input_tcsetattr (int, struct termios const *t)
       syscall_printf ("%d = tcsetattr(,%p) enable flags %y, c_lflag %y iflag %y",
 		      res, t, flags, t->c_lflag, t->c_iflag);
     }
+  release_attach_mutex ();
 
   get_ttyp ()->rstcons (false);
   release_input_mutex ();
@@ -1481,6 +1506,7 @@ fhandler_console::tcgetattr (struct termios *t)
 
   DWORD flags;
 
+  acquire_attach_mutex (INFINITE);
   if (!GetConsoleMode (get_handle (), &flags))
     {
       __seterrno ();
@@ -1505,6 +1531,7 @@ fhandler_console::tcgetattr (struct termios *t)
       /* All the output bits we can ignore */
       res = 0;
     }
+  release_attach_mutex ();
   syscall_printf ("%d = tcgetattr(%p) enable flags %y, t->lflag %y, t->iflag %y",
 		 res, t, flags, t->c_lflag, t->c_iflag);
   return res;
-- 
2.30.0



More information about the Cygwin-patches mailing list