[newlib-cygwin] Cygwin: pty: Fix error handling of master write().

Corinna Vinschen corinna@sourceware.org
Tue Sep 7 18:22:07 GMT 2021


https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=b52f10c4ca02216005f2eba3b968b4504098959b

commit b52f10c4ca02216005f2eba3b968b4504098959b
Author: Takashi Yano <takashi.yano@nifty.ne.jp>
Date:   Tue Sep 7 19:27:45 2021 +0900

    Cygwin: pty: Fix error handling of master write().
    
    - Currently, error handling of write() in pty master side is broken.
      This patch fixes that.

Diff:
---
 winsup/cygwin/fhandler_termios.cc | 24 +++++++++++-------------
 winsup/cygwin/fhandler_tty.cc     | 11 +++++++----
 2 files changed, 18 insertions(+), 17 deletions(-)

diff --git a/winsup/cygwin/fhandler_termios.cc b/winsup/cygwin/fhandler_termios.cc
index b487acab3..012ecb356 100644
--- a/winsup/cygwin/fhandler_termios.cc
+++ b/winsup/cygwin/fhandler_termios.cc
@@ -308,12 +308,12 @@ fhandler_termios::line_edit (const char *rptr, size_t nread, termios& ti,
   int input_done = 0;
   bool sawsig = false;
   int iscanon = ti.c_lflag & ICANON;
+  size_t read_cnt = 0;
 
-  if (bytes_read)
-    *bytes_read = nread;
-  while (nread-- > 0)
+  while (read_cnt < nread)
     {
       c = *rptr++;
+      read_cnt++;
 
       paranoid_printf ("char %0o", c);
 
@@ -453,7 +453,6 @@ fhandler_termios::line_edit (const char *rptr, size_t nread, termios& ti,
 	  if (status != 1)
 	    {
 	      ret = status ? line_edit_error : line_edit_pipe_full;
-	      nread += ralen ();
 	      break;
 	    }
 	  ret = line_edit_input_done;
@@ -462,22 +461,21 @@ fhandler_termios::line_edit (const char *rptr, size_t nread, termios& ti,
     }
 
   /* If we didn't write all bytes in non-canonical mode, write them now. */
-  if (!iscanon && ralen () > 0
-      && (ret == line_edit_ok || ret == line_edit_input_done))
+  if ((input_done || !iscanon) && ralen () > 0 && ret != line_edit_error)
     {
-      int status = accept_input ();
+      int status;
+      int retry_count = 3;
+      while ((status = accept_input ()) != 1 &&
+	     ralen () > 0 && --retry_count > 0)
+	cygwait ((DWORD) 10);
       if (status != 1)
-	{
-	  ret = status ? line_edit_error : line_edit_pipe_full;
-	  nread += ralen ();
-	}
+	ret = status ? line_edit_error : line_edit_pipe_full;
       else
 	ret = line_edit_input_done;
     }
 
-  /* Adding one compensates for the postdecrement in the above loop. */
   if (bytes_read)
-    *bytes_read -= (nread + 1);
+    *bytes_read = read_cnt;
 
   if (sawsig)
     ret = line_edit_signalled;
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index f2ac26892..1ea9a47ac 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -561,18 +561,21 @@ fhandler_pty_master::accept_input ()
 	{
 	  n = p1 - p0 + 1;
 	  rc = WriteFile (write_to, p0, n, &n, NULL);
-	  written += n;
+	  if (rc)
+	    written += n;
 	  p0 = p1 + 1;
 	}
-      if ((n = bytes_left - (p0 - p)))
+      if (rc && (n = bytes_left - (p0 - p)))
 	{
 	  rc = WriteFile (write_to, p0, n, &n, NULL);
-	  written += n;
+	  if (rc)
+	    written += n;
 	}
-      if (!rc)
+      if (!rc && written == 0)
 	{
 	  debug_printf ("error writing to pipe %p %E", write_to);
 	  get_ttyp ()->read_retval = -1;
+	  puts_readahead (p, bytes_left);
 	  ret = -1;
 	}
       else


More information about the Cygwin-cvs mailing list