public inbox for cygwin-patches@cygwin.com
 help / color / mirror / Atom feed
From: Takashi Yano <takashi.yano@nifty.ne.jp>
To: cygwin-patches@cygwin.com
Subject: [PATCH] Cygwin: console: Fix issue of pasting very long text input again.
Date: Tue,  5 Jul 2022 12:10:44 +0900	[thread overview]
Message-ID: <20220705031044.1374-1-takashi.yano@nifty.ne.jp> (raw)

- The recent commit "Cygwin: console: Allow pasting very long text
  input." did not fix the issue enough. This patch adds fixes for
  that.
---
 winsup/cygwin/fhandler_console.cc | 87 +++++++++++++++++++++++--------
 1 file changed, 65 insertions(+), 22 deletions(-)

diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc
index 52031fe31..47d30bc88 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -342,9 +342,9 @@ fhandler_console::cons_master_thread (handle_set_t *p, tty *ttyp)
 	{
 	  DWORD new_inrec_size = total_read + additional_space;
 	  INPUT_RECORD *new_input_rec = (INPUT_RECORD *)
-	    realloc (input_rec, new_inrec_size * sizeof (INPUT_RECORD));
+	    realloc (input_rec, m::bytes (new_inrec_size));
 	  INPUT_RECORD *new_input_tmp = (INPUT_RECORD *)
-	    realloc (input_tmp, new_inrec_size * sizeof (INPUT_RECORD));
+	    realloc (input_tmp, m::bytes (new_inrec_size));
 	  if (new_input_rec && new_input_tmp)
 	    {
 	      inrec_size = new_inrec_size;
@@ -360,6 +360,7 @@ fhandler_console::cons_master_thread (handle_set_t *p, tty *ttyp)
       switch (cygwait (p->input_handle, (DWORD) 0))
 	{
 	case WAIT_OBJECT_0:
+	  acquire_attach_mutex (mutex_timeout);
 	  total_read = 0;
 	  while (cygwait (p->input_handle, (DWORD) 0) == WAIT_OBJECT_0
 		 && total_read < inrec_size)
@@ -467,7 +468,30 @@ remove_record:
 				      min (total_read - n, inrec_size1), &len);
 		  n += len;
 		}
+	      release_attach_mutex ();
+
+	      acquire_attach_mutex (mutex_timeout);
+	      GetNumberOfConsoleInputEvents (p->input_handle, &n);
+	      release_attach_mutex ();
+	      if (n + additional_space > inrec_size)
+		{
+		  DWORD new_inrec_size = n + additional_space;
+		  INPUT_RECORD *new_input_rec = (INPUT_RECORD *)
+		    realloc (input_rec, m::bytes (new_inrec_size));
+		  INPUT_RECORD *new_input_tmp = (INPUT_RECORD *)
+		    realloc (input_tmp, m::bytes (new_inrec_size));
+		  if (new_input_rec && new_input_tmp)
+		    {
+		      inrec_size = new_inrec_size;
+		      input_rec = new_input_rec;
+		      input_tmp = new_input_tmp;
+		      if (!wincap.cons_need_small_input_record_buf ())
+			inrec_size1 = inrec_size;
+		    }
+		}
+
 	      /* Check if writeback was successfull. */
+	      acquire_attach_mutex (mutex_timeout);
 	      PeekConsoleInputW (p->input_handle, input_tmp, inrec_size1, &n);
 	      release_attach_mutex ();
 	      if (n < min (total_read, inrec_size1))
@@ -488,28 +512,47 @@ remove_record:
 		  n += len;
 		}
 	      release_attach_mutex ();
-	      for (DWORD i = 0, j = 0; j < n; j++)
-		if (i == total_read
-		    || !inrec_eq (input_rec + i, input_tmp + j, 1))
-		  {
-		    if (total_read + j - i >= n)
-		      { /* Something is wrong. Giving up. */
-			acquire_attach_mutex (mutex_timeout);
-			DWORD l = 0;
-			while (l < n)
-			  {
-			    DWORD len;
-			    WriteConsoleInputW (p->input_handle, input_tmp + l,
-					      min (n - l, inrec_size1), &len);
-			    l += len;
+	      bool fixed = false;
+	      for (DWORD ofs = n - total_read; ofs > 0; ofs--)
+		{
+		  if (inrec_eq (input_rec, input_tmp + ofs, total_read))
+		    {
+		      memcpy (input_rec + total_read, input_tmp,
+			      m::bytes (ofs));
+		      memcpy (input_rec + total_read + ofs,
+			      input_tmp + total_read + ofs,
+			      m::bytes (n - ofs - total_read));
+		      fixed = true;
+		      break;
+		    }
+		}
+	      if (!fixed)
+		{
+		  for (DWORD i = 0, j = 0; j < n; j++)
+		    if (i == total_read
+			|| !inrec_eq (input_rec + i, input_tmp + j, 1))
+		      {
+			if (total_read + j - i >= n)
+			  { /* Something is wrong. Giving up. */
+			    acquire_attach_mutex (mutex_timeout);
+			    DWORD l = 0;
+			    while (l < n)
+			      {
+				DWORD len;
+				WriteConsoleInputW (p->input_handle,
+						    input_tmp + l,
+						    min (n - l, inrec_size1),
+						    &len);
+				l += len;
+			      }
+			    release_attach_mutex ();
+			    goto skip_writeback;
 			  }
-			release_attach_mutex ();
-			goto skip_writeback;
+			input_rec[total_read + j - i] = input_tmp[j];
 		      }
-		    input_rec[total_read + j - i] = input_tmp[j];
-		  }
-		else
-		  i++;
+		    else
+		      i++;
+		}
 	      total_read = n;
 	    }
 	  while (true);
-- 
2.36.1


                 reply	other threads:[~2022-07-05  3:11 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220705031044.1374-1-takashi.yano@nifty.ne.jp \
    --to=takashi.yano@nifty.ne.jp \
    --cc=cygwin-patches@cygwin.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).