public inbox for cygwin-patches@cygwin.com
 help / color / mirror / Atom feed
* [PATCH 0/8] Several modifications for pty and console code.
@ 2022-02-13 14:39 Takashi Yano
  2022-02-13 14:39 ` [PATCH 1/8] Cygwin: pty, console: Fix Ctrl-C handling for non-cygwin apps Takashi Yano
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Takashi Yano @ 2022-02-13 14:39 UTC (permalink / raw)
  To: cygwin-patches

Takashi Yano (8):
  Cygwin: pty, console: Fix Ctrl-C handling for non-cygwin apps.
  Cygwin: pty: Pass Ctrl-Z (EOF) to non-cygwin apps with disable_pcon.
  Cygwin: pty: Prevent deadlock on echo output.
  Cygwin: pty: Revise the code to wait for completion of forwarding.
  Cygwin: pty: Discard input in from_master_nat pipe on signal as well.
  Cygwin: pty: Fix a bug in tty_min::segpgid().
  Cygwin: console: Fix console mode for non-cygwin inferior of GDB.
  Cygwin: console: Set console mode even if stdin/stdout is redirected.

 winsup/cygwin/fhandler.h          |   2 +
 winsup/cygwin/fhandler_console.cc |  67 +++++++++++++++
 winsup/cygwin/fhandler_termios.cc |  47 +++++++++-
 winsup/cygwin/fhandler_tty.cc     | 138 ++++++++++++++++--------------
 winsup/cygwin/spawn.cc            |  19 ++--
 winsup/cygwin/tty.cc              |  14 +--
 winsup/cygwin/tty.h               |   3 +-
 7 files changed, 204 insertions(+), 86 deletions(-)

-- 
2.35.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/8] Cygwin: pty, console: Fix Ctrl-C handling for non-cygwin apps.
  2022-02-13 14:39 [PATCH 0/8] Several modifications for pty and console code Takashi Yano
@ 2022-02-13 14:39 ` Takashi Yano
  2022-02-13 14:39 ` [PATCH 2/8] Cygwin: pty: Pass Ctrl-Z (EOF) to non-cygwin apps with disable_pcon Takashi Yano
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Takashi Yano @ 2022-02-13 14:39 UTC (permalink / raw)
  To: cygwin-patches

- Currently, if cat is started from cmd.exe which is started in cygwin
  console, Ctrl-C terminates not only cat but also cmd.exe. This also
  happens in pty in which pseudo console is disabled. This patch fixes
  the issue.
---
 winsup/cygwin/fhandler_console.cc | 28 +++++++++++++++++++++++
 winsup/cygwin/fhandler_termios.cc | 38 +++++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+)

diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc
index b28dd66f5..da65c465e 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -238,6 +238,33 @@ fhandler_console::cons_master_thread (handle_set_t *p, tty *ttyp)
 	  char c = (char) wc;
 	  bool processed = false;
 	  termios &ti = ttyp->ti;
+	  pinfo pi (ttyp->getpgid ());
+	  if (pi && pi->ctty == ttyp->ntty
+	      && (pi->process_state & PID_NOTCYGWIN)
+	      && input_rec[i].EventType == KEY_EVENT && c == '\003')
+	    {
+	      bool not_a_sig = false;
+	      if (!CCEQ (ti.c_cc[VINTR], c)
+		  && !CCEQ (ti.c_cc[VQUIT], c)
+		  && !CCEQ (ti.c_cc[VSUSP], c))
+		not_a_sig = true;
+	      if (input_rec[i].Event.KeyEvent.bKeyDown)
+		{
+		  /* CTRL_C_EVENT does not work for the process started with
+		     CREATE_NEW_PROCESS_GROUP flag, so send CTRL_BREAK_EVENT
+		     instead. */
+		  if (pi->process_state & PID_NEW_PG)
+		    GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT,
+					      pi->dwProcessId);
+		  else
+		    GenerateConsoleCtrlEvent (CTRL_C_EVENT, 0);
+		  if (not_a_sig)
+		    goto skip_writeback;
+		}
+	      processed = true;
+	      if (not_a_sig)
+		goto remove_record;
+	    }
 	  switch (input_rec[i].EventType)
 	    {
 	    case KEY_EVENT:
@@ -310,6 +337,7 @@ fhandler_console::cons_master_thread (handle_set_t *p, tty *ttyp)
 	      processed = true;
 	      break;
 	    }
+remove_record:
 	  if (processed)
 	    { /* Remove corresponding record. */
 	      memmove (input_rec + i, input_rec + i + 1,
diff --git a/winsup/cygwin/fhandler_termios.cc b/winsup/cygwin/fhandler_termios.cc
index 3461d1785..fe1021520 100644
--- a/winsup/cygwin/fhandler_termios.cc
+++ b/winsup/cygwin/fhandler_termios.cc
@@ -147,6 +147,8 @@ tty_min::kill_pgrp (int sig)
       _pinfo *p = pids[i];
       if (!p || !p->exists () || p->ctty != ntty || p->pgid != pgid)
 	continue;
+      if (p->process_state & PID_NOTCYGWIN)
+	continue;
       if (p == myself)
 	killself = sig != __SIGSETPGRP && !exit_state;
       else
@@ -326,6 +328,42 @@ fhandler_termios::line_edit (const char *rptr, size_t nread, termios& ti,
 
       if (ti.c_iflag & ISTRIP)
 	c &= 0x7f;
+      winpids pids ((DWORD) 0);
+      if (get_ttyp ()->pcon_input_state_eq (tty::to_nat))
+	{
+	  bool need_discard_input = false;
+	  for (unsigned i = 0; i < pids.npids; i++)
+	    {
+	      _pinfo *p = pids[i];
+	      if (c == '\003' && p && p->ctty == tc ()->ntty
+		  && p->pgid == tc ()->getpgid ()
+		  && (p->process_state & PID_NOTCYGWIN))
+		{
+		  /* CTRL_C_EVENT does not work for the process started with
+		     CREATE_NEW_PROCESS_GROUP flag, so send CTRL_BREAK_EVENT
+		     instead. */
+		  if (p->process_state & PID_NEW_PG)
+		    GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT,
+					      p->dwProcessId);
+		  else
+		    GenerateConsoleCtrlEvent (CTRL_C_EVENT, 0);
+		  need_discard_input = true;
+		}
+	    }
+	  if (need_discard_input
+	      && !CCEQ (ti.c_cc[VINTR], c)
+	      && !CCEQ (ti.c_cc[VQUIT], c)
+	      && !CCEQ (ti.c_cc[VSUSP], c))
+	    {
+	      if (!(ti.c_lflag & NOFLSH))
+		{
+		  eat_readahead (-1);
+		  discard_input ();
+		}
+	      ti.c_lflag &= ~FLUSHO;
+	      continue;
+	    }
+	}
       if (ti.c_lflag & ISIG)
 	{
 	  int sig;
-- 
2.35.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 2/8] Cygwin: pty: Pass Ctrl-Z (EOF) to non-cygwin apps with disable_pcon.
  2022-02-13 14:39 [PATCH 0/8] Several modifications for pty and console code Takashi Yano
  2022-02-13 14:39 ` [PATCH 1/8] Cygwin: pty, console: Fix Ctrl-C handling for non-cygwin apps Takashi Yano
@ 2022-02-13 14:39 ` Takashi Yano
  2022-02-13 14:39 ` [PATCH 3/8] Cygwin: pty: Prevent deadlock on echo output Takashi Yano
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Takashi Yano @ 2022-02-13 14:39 UTC (permalink / raw)
  To: cygwin-patches

- Previously, non-cygwin app running in pty started without pseudo
  console support was suspended by Ctrl-Z rather than sending EOF.
  Even worse, suspended app could not be resumed by fg command. With
  this patch, Ctrl-Z (EOF for non-cygwin apps) is passed to non-cygwin
  app instead of suspending that app. This patch also handles Ctrl-\
  (QUIT) and Ctrl-D (EOF) as well.
---
 winsup/cygwin/fhandler_termios.cc | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/winsup/cygwin/fhandler_termios.cc b/winsup/cygwin/fhandler_termios.cc
index fe1021520..b935a70bc 100644
--- a/winsup/cygwin/fhandler_termios.cc
+++ b/winsup/cygwin/fhandler_termios.cc
@@ -329,6 +329,7 @@ fhandler_termios::line_edit (const char *rptr, size_t nread, termios& ti,
       if (ti.c_iflag & ISTRIP)
 	c &= 0x7f;
       winpids pids ((DWORD) 0);
+      bool need_check_sigs = get_ttyp ()->pcon_input_state_eq (tty::to_cyg);
       if (get_ttyp ()->pcon_input_state_eq (tty::to_nat))
 	{
 	  bool need_discard_input = false;
@@ -349,11 +350,15 @@ fhandler_termios::line_edit (const char *rptr, size_t nread, termios& ti,
 		    GenerateConsoleCtrlEvent (CTRL_C_EVENT, 0);
 		  need_discard_input = true;
 		}
+	      if (p->ctty == get_ttyp ()->ntty
+		  && p->pgid == get_ttyp ()->getpgid () && !p->cygstarted)
+		need_check_sigs = true;
 	    }
-	  if (need_discard_input
-	      && !CCEQ (ti.c_cc[VINTR], c)
+	  if (!CCEQ (ti.c_cc[VINTR], c)
 	      && !CCEQ (ti.c_cc[VQUIT], c)
 	      && !CCEQ (ti.c_cc[VSUSP], c))
+	    need_check_sigs = false;
+	  if (need_discard_input && !need_check_sigs)
 	    {
 	      if (!(ti.c_lflag & NOFLSH))
 		{
@@ -364,7 +369,7 @@ fhandler_termios::line_edit (const char *rptr, size_t nread, termios& ti,
 	      continue;
 	    }
 	}
-      if (ti.c_lflag & ISIG)
+      if ((ti.c_lflag & ISIG) && need_check_sigs)
 	{
 	  int sig;
 	  if (CCEQ (ti.c_cc[VINTR], c))
@@ -469,7 +474,7 @@ fhandler_termios::line_edit (const char *rptr, size_t nread, termios& ti,
 	    }
 	  continue;
 	}
-      else if (CCEQ (ti.c_cc[VEOF], c))
+      else if (CCEQ (ti.c_cc[VEOF], c) && need_check_sigs)
 	{
 	  termios_printf ("EOF");
 	  accept_input ();
-- 
2.35.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 3/8] Cygwin: pty: Prevent deadlock on echo output.
  2022-02-13 14:39 [PATCH 0/8] Several modifications for pty and console code Takashi Yano
  2022-02-13 14:39 ` [PATCH 1/8] Cygwin: pty, console: Fix Ctrl-C handling for non-cygwin apps Takashi Yano
  2022-02-13 14:39 ` [PATCH 2/8] Cygwin: pty: Pass Ctrl-Z (EOF) to non-cygwin apps with disable_pcon Takashi Yano
@ 2022-02-13 14:39 ` Takashi Yano
  2022-02-13 14:39 ` [PATCH 4/8] Cygwin: pty: Revise the code to wait for completion of forwarding Takashi Yano
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Takashi Yano @ 2022-02-13 14:39 UTC (permalink / raw)
  To: cygwin-patches

- If the slave process writes a lot of text output, doecho() can
  cause deadlock. This is because output_mutex is held in slave::
  write() and if WriteFile() is blocked due to pipe full, doecho()
  tries to acquire output_mutex and gets into deadlock. With this
  patch, the deadlock is prevented on the sacrifice of atomicity
  of doecho().
---
 winsup/cygwin/fhandler_tty.cc | 2 --
 1 file changed, 2 deletions(-)

diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 7bef6958c..7e065c46a 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -496,11 +496,9 @@ void
 fhandler_pty_master::doecho (const void *str, DWORD len)
 {
   ssize_t towrite = len;
-  acquire_output_mutex (mutex_timeout);
   if (!process_opost_output (echo_w, str, towrite, true,
 			     get_ttyp (), is_nonblocking ()))
     termios_printf ("Write to echo pipe failed, %E");
-  release_output_mutex ();
 }
 
 int
-- 
2.35.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 4/8] Cygwin: pty: Revise the code to wait for completion of forwarding.
  2022-02-13 14:39 [PATCH 0/8] Several modifications for pty and console code Takashi Yano
                   ` (2 preceding siblings ...)
  2022-02-13 14:39 ` [PATCH 3/8] Cygwin: pty: Prevent deadlock on echo output Takashi Yano
@ 2022-02-13 14:39 ` Takashi Yano
  2022-02-13 14:39 ` [PATCH 5/8] Cygwin: pty: Discard input in from_master_nat pipe on signal as well Takashi Yano
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Takashi Yano @ 2022-02-13 14:39 UTC (permalink / raw)
  To: cygwin-patches

- With this patch, the code to wait for completion of forwarding of
  output from non-cygwin app is revised so that it can more reliably
  detect the completion.
---
 winsup/cygwin/fhandler_tty.cc |  5 ++++-
 winsup/cygwin/tty.cc          | 11 ++++++-----
 winsup/cygwin/tty.h           |  3 ++-
 3 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 7e065c46a..7e733e49a 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -1118,7 +1118,7 @@ fhandler_pty_slave::reset_switch_to_pcon (void)
       if (WaitForSingleObject (h_gdb_process, 0) == WAIT_TIMEOUT)
 	{
 	  if (isHybrid)
-	    get_ttyp ()->wait_pcon_fwd (false);
+	    get_ttyp ()->wait_pcon_fwd ();
 	}
       else
 	{
@@ -2705,6 +2705,9 @@ fhandler_pty_master::pty_master_fwd_thread (const master_fwd_thread_param_t *p)
   for (;;)
     {
       p->ttyp->pcon_last_time = GetTickCount ();
+      DWORD n;
+      p->ttyp->pcon_fwd_not_empty =
+	::bytes_available (n, p->from_slave_nat) && n;
       if (!ReadFile (p->from_slave_nat, outbuf, NT_MAX_PATH, &rlen, NULL))
 	{
 	  termios_printf ("ReadFile for forwarding failed, %E");
diff --git a/winsup/cygwin/tty.cc b/winsup/cygwin/tty.cc
index 789528856..da75b8dd2 100644
--- a/winsup/cygwin/tty.cc
+++ b/winsup/cygwin/tty.cc
@@ -240,6 +240,7 @@ tty::init ()
   pcon_pid = 0;
   term_code_page = 0;
   pcon_last_time = 0;
+  pcon_fwd_not_empty = false;
   pcon_start = false;
   pcon_start_pid = 0;
   pcon_cap_checked = false;
@@ -367,7 +368,7 @@ tty_min::setpgid (int pid)
 }
 
 void
-tty::wait_pcon_fwd (bool init)
+tty::wait_pcon_fwd ()
 {
   /* The forwarding in pseudo console sometimes stops for
      16-32 msec even if it already has data to transfer.
@@ -377,11 +378,11 @@ tty::wait_pcon_fwd (bool init)
      thread when the last data is transfered. */
   const int sleep_in_pcon = 16;
   const int time_to_wait = sleep_in_pcon * 2 + 1/* margine */;
-  if (init)
-    pcon_last_time = GetTickCount ();
-  while (GetTickCount () - pcon_last_time < time_to_wait)
+  int elapsed;
+  while (pcon_fwd_not_empty
+	 || (elapsed = GetTickCount () - pcon_last_time) < time_to_wait)
     {
-      int tw = time_to_wait - (GetTickCount () - pcon_last_time);
+      int tw = pcon_fwd_not_empty ? 10 : (time_to_wait - elapsed);
       cygwait (tw);
     }
 }
diff --git a/winsup/cygwin/tty.h b/winsup/cygwin/tty.h
index 519d7c0d5..2cd12a665 100644
--- a/winsup/cygwin/tty.h
+++ b/winsup/cygwin/tty.h
@@ -116,6 +116,7 @@ private:
   DWORD pcon_pid;
   UINT term_code_page;
   DWORD pcon_last_time;
+  bool pcon_fwd_not_empty;
   HANDLE h_pcon_write_pipe;
   HANDLE h_pcon_condrv_reference;
   HANDLE h_pcon_conhost_process;
@@ -166,7 +167,7 @@ public:
   void set_master_ctl_closed () {master_pid = -1;}
   static void __stdcall create_master (int);
   static void __stdcall init_session ();
-  void wait_pcon_fwd (bool init = true);
+  void wait_pcon_fwd ();
   bool pcon_input_state_eq (xfer_dir x) { return pcon_input_state == x; }
   bool pcon_fg (pid_t pgid);
   friend class fhandler_pty_common;
-- 
2.35.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 5/8] Cygwin: pty: Discard input in from_master_nat pipe on signal as well.
  2022-02-13 14:39 [PATCH 0/8] Several modifications for pty and console code Takashi Yano
                   ` (3 preceding siblings ...)
  2022-02-13 14:39 ` [PATCH 4/8] Cygwin: pty: Revise the code to wait for completion of forwarding Takashi Yano
@ 2022-02-13 14:39 ` Takashi Yano
  2022-02-13 14:39 ` [PATCH 6/8] Cygwin: pty: Fix a bug in tty_min::segpgid() Takashi Yano
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Takashi Yano @ 2022-02-13 14:39 UTC (permalink / raw)
  To: cygwin-patches

- Currently, pty discards input only in from_master pipe on signal.
  Due to this, if pty is started without pseudo console support and
  start a non-cygwin process from cmd.exe, type adhead input is not
  discarded on signals such as Ctrl-C. This patch fixes the issue.
---
 winsup/cygwin/fhandler_tty.cc | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 7e733e49a..8c9a10c23 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -438,6 +438,9 @@ fhandler_pty_master::discard_input ()
   while (::bytes_available (bytes_in_pipe, from_master) && bytes_in_pipe)
     ReadFile (from_master, buf, sizeof(buf), &n, NULL);
   ResetEvent (input_available_event);
+  if (!get_ttyp ()->pcon_activated)
+    while (::bytes_available (bytes_in_pipe, from_master_nat) && bytes_in_pipe)
+      ReadFile (from_master_nat, buf, sizeof(buf), &n, NULL);
   get_ttyp ()->discard_input = true;
   ReleaseMutex (input_mutex);
 }
-- 
2.35.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 6/8] Cygwin: pty: Fix a bug in tty_min::segpgid().
  2022-02-13 14:39 [PATCH 0/8] Several modifications for pty and console code Takashi Yano
                   ` (4 preceding siblings ...)
  2022-02-13 14:39 ` [PATCH 5/8] Cygwin: pty: Discard input in from_master_nat pipe on signal as well Takashi Yano
@ 2022-02-13 14:39 ` Takashi Yano
  2022-02-13 14:39 ` [PATCH 7/8] Cygwin: console: Fix console mode for non-cygwin inferior of GDB Takashi Yano
  2022-02-13 14:39 ` [PATCH 8/8] Cygwin: console: Set console mode even if stdin/stdout is redirected Takashi Yano
  7 siblings, 0 replies; 9+ messages in thread
From: Takashi Yano @ 2022-02-13 14:39 UTC (permalink / raw)
  To: cygwin-patches

- In tty_min::setpgid(), a pointer to fhandler instance is casted to
  fhandler_pty_slave and accessed even if terminal is not a pty slave.
  This patch fixes the issue.
---
 winsup/cygwin/tty.cc | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/winsup/cygwin/tty.cc b/winsup/cygwin/tty.cc
index da75b8dd2..c0015aceb 100644
--- a/winsup/cygwin/tty.cc
+++ b/winsup/cygwin/tty.cc
@@ -309,7 +309,8 @@ tty_min::setpgid (int pid)
   fhandler_pty_slave *ptys = NULL;
   cygheap_fdenum cfd (false);
   while (cfd.next () >= 0 && ptys == NULL)
-    if (cfd->get_device () == getntty ())
+    if (cfd->get_device () == getntty ()
+	&& cfd->get_major () == DEV_PTYS_MAJOR)
       ptys = (fhandler_pty_slave *) (fhandler_base *) cfd;
 
   if (ptys)
-- 
2.35.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 7/8] Cygwin: console: Fix console mode for non-cygwin inferior of GDB.
  2022-02-13 14:39 [PATCH 0/8] Several modifications for pty and console code Takashi Yano
                   ` (5 preceding siblings ...)
  2022-02-13 14:39 ` [PATCH 6/8] Cygwin: pty: Fix a bug in tty_min::segpgid() Takashi Yano
@ 2022-02-13 14:39 ` Takashi Yano
  2022-02-13 14:39 ` [PATCH 8/8] Cygwin: console: Set console mode even if stdin/stdout is redirected Takashi Yano
  7 siblings, 0 replies; 9+ messages in thread
From: Takashi Yano @ 2022-02-13 14:39 UTC (permalink / raw)
  To: cygwin-patches

- Currently, there is no chance to change console mode for non-cygwin
  inferior of GDB. With this patch, the console mode is changed to
  tty::native in CreateProcess() and ContinueDebugEvent() hooked in
  fhandler_console.
---
 winsup/cygwin/fhandler.h          |   2 +
 winsup/cygwin/fhandler_console.cc |  39 +++++++++
 winsup/cygwin/fhandler_tty.cc     | 128 +++++++++++++++---------------
 3 files changed, 107 insertions(+), 62 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index fb4747608..4e86ab58a 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -1941,6 +1941,8 @@ class fhandler_termios: public fhandler_base
     fh->copy_from (this);
     return fh;
   }
+  static bool path_iscygexec_a (LPCSTR n, LPSTR c);
+  static bool path_iscygexec_w (LPCWSTR n, LPWSTR c);
 };
 
 enum ansi_intensity
diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc
index da65c465e..50f350c49 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -32,6 +32,7 @@ details. */
 #include "sync.h"
 #include "child_info.h"
 #include "cygwait.h"
+#include "winf.h"
 
 /* Don't make this bigger than NT_MAX_PATH as long as the temporary buffer
    is allocated using tmp_pathbuf!!! */
@@ -3595,10 +3596,32 @@ set_console_title (char *title)
   debug_printf ("title '%W'", buf);
 }
 
+static bool NO_COPY gdb_inferior_noncygwin = false;
+static void
+set_console_mode_to_native ()
+{
+  cygheap_fdenum cfd (false);
+  while (cfd.next () >= 0)
+    if (cfd->get_major () == DEV_CONS_MAJOR)
+      {
+	fhandler_console *cons = (fhandler_console *) (fhandler_base *) cfd;
+	if (cons->get_device () == cons->tc ()->getntty ())
+	  {
+	    termios *cons_ti = &((tty *) cons->tc ())->ti;
+	    fhandler_console::set_input_mode (tty::native, cons_ti,
+					      cons->get_handle_set ());
+	    fhandler_console::set_output_mode (tty::native, cons_ti,
+					       cons->get_handle_set ());
+	    break;
+	  }
+      }
+}
+
 #define DEF_HOOK(name) static __typeof__ (name) *name##_Orig
 /* CreateProcess() is hooked for GDB etc. */
 DEF_HOOK (CreateProcessA);
 DEF_HOOK (CreateProcessW);
+DEF_HOOK (ContinueDebugEvent);
 
 static BOOL WINAPI
 CreateProcessA_Hooked
@@ -3608,6 +3631,9 @@ CreateProcessA_Hooked
 {
   if (f & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS))
     mutex_timeout = 0; /* to avoid deadlock in GDB */
+  gdb_inferior_noncygwin = !fhandler_termios::path_iscygexec_a (n, c);
+  if (gdb_inferior_noncygwin)
+    set_console_mode_to_native ();
   return CreateProcessA_Orig (n, c, pa, ta, inh, f, e, d, si, pi);
 }
 
@@ -3619,9 +3645,21 @@ CreateProcessW_Hooked
 {
   if (f & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS))
     mutex_timeout = 0; /* to avoid deadlock in GDB */
+  gdb_inferior_noncygwin = !fhandler_termios::path_iscygexec_w (n, c);
+  if (gdb_inferior_noncygwin)
+    set_console_mode_to_native ();
   return CreateProcessW_Orig (n, c, pa, ta, inh, f, e, d, si, pi);
 }
 
+static BOOL WINAPI
+ContinueDebugEvent_Hooked
+     (DWORD p, DWORD t, DWORD s)
+{
+  if (gdb_inferior_noncygwin)
+    set_console_mode_to_native ();
+  return ContinueDebugEvent_Orig (p, t, s);
+}
+
 void
 fhandler_console::fixup_after_fork_exec (bool execing)
 {
@@ -3641,6 +3679,7 @@ fhandler_console::fixup_after_fork_exec (bool execing)
   /* CreateProcess() is hooked for GDB etc. */
   DO_HOOK (NULL, CreateProcessA);
   DO_HOOK (NULL, CreateProcessW);
+  DO_HOOK (NULL, ContinueDebugEvent);
 }
 
 /* Ugly workaround to create invisible console required since Windows 7.
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 8c9a10c23..5ba50cc73 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -157,6 +157,66 @@ set_switch_to_pcon (HANDLE *in, HANDLE *out, HANDLE *err, bool iscygwin)
     *err = replace_err->get_output_handle_nat ();
 }
 
+static bool
+path_iscygexec_a_w (LPCSTR na, LPSTR ca, LPCWSTR nw, LPWSTR cw)
+{
+  path_conv path;
+  tmp_pathbuf tp;
+  char *prog =tp.c_get ();
+  if (na)
+    {
+      __small_sprintf (prog, "%s", na);
+      find_exec (prog, path);
+    }
+  else if (nw)
+    {
+      __small_sprintf (prog, "%W", nw);
+      find_exec (prog, path);
+    }
+  else
+    {
+      if (ca)
+	__small_sprintf (prog, "%s", ca);
+      else if (cw)
+	__small_sprintf (prog, "%W", cw);
+      else
+	return true;
+      char *p = prog;
+      char *p1;
+      do
+	if ((p1 = strchr (p, ' ')) || (p1 = p + strlen (p)))
+	  {
+	    p = p1;
+	    if (*p == ' ')
+	      {
+		*p = '\0';
+		find_exec (prog, path);
+		*p = ' ';
+		p ++;
+	      }
+	    else if (*p == '\0')
+	      find_exec (prog, path);
+	  }
+      while (!path.exists() && *p);
+    }
+  const char *argv[] = {"", NULL}; /* Dummy */
+  av av1;
+  av1.setup ("", path, "", 1, argv, false);
+  return path.iscygexec ();
+}
+
+bool
+fhandler_termios::path_iscygexec_a (LPCSTR n, LPSTR c)
+{
+  return path_iscygexec_a_w (n, c, NULL, NULL);
+}
+
+bool
+fhandler_termios::path_iscygexec_w (LPCWSTR n, LPWSTR c)
+{
+  return path_iscygexec_a_w (NULL, NULL, n, c);
+}
+
 static bool atexit_func_registered = false;
 static bool debug_process = false;
 
@@ -220,37 +280,9 @@ CreateProcessA_Hooked
       siov->hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);
       siov->hStdError = GetStdHandle (STD_ERROR_HANDLE);
     }
-  path_conv path;
-  tmp_pathbuf tp;
-  char *prog =tp.c_get ();
-  if (n)
-    __small_sprintf (prog, "%s", n);
-  else
-    {
-      __small_sprintf (prog, "%s", c);
-      char *p = prog;
-      char *p1;
-      do
-	if ((p1 = strchr (p, ' ')) || (p1 = p + strlen (p)))
-	  {
-	    p = p1;
-	    if (*p == ' ')
-	      {
-		*p = '\0';
-		find_exec (prog, path);
-		*p = ' ';
-		p ++;
-	      }
-	    else if (*p == '\0')
-	      find_exec (prog, path);
-	  }
-      while (!path.exists() && *p);
-    }
-  const char *argv[] = {"", NULL}; /* Dummy */
-  av av1;
-  av1.setup ("", path, "", 1, argv, false);
+  bool path_iscygexec = fhandler_termios::path_iscygexec_a (n, c);
   set_switch_to_pcon (&siov->hStdInput, &siov->hStdOutput, &siov->hStdError,
-		      path.iscygexec ());
+		      path_iscygexec);
   BOOL ret = CreateProcessA_Orig (n, c, pa, ta, inh, f, e, d, siov, pi);
   h_gdb_process = pi->hProcess;
   DuplicateHandle (GetCurrentProcess (), h_gdb_process,
@@ -259,7 +291,7 @@ CreateProcessA_Hooked
   debug_process = !!(f & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS));
   if (debug_process)
     mutex_timeout = 0; /* to avoid deadlock in GDB */
-  if (!atexit_func_registered && !path.iscygexec ())
+  if (!atexit_func_registered && !path_iscygexec)
     {
       atexit (atexit_func);
       atexit_func_registered = true;
@@ -286,37 +318,9 @@ CreateProcessW_Hooked
       siov->hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);
       siov->hStdError = GetStdHandle (STD_ERROR_HANDLE);
     }
-  path_conv path;
-  tmp_pathbuf tp;
-  char *prog =tp.c_get ();
-  if (n)
-    __small_sprintf (prog, "%W", n);
-  else
-    {
-      __small_sprintf (prog, "%W", c);
-      char *p = prog;
-      char *p1;
-      do
-	if ((p1 = strchr (p, ' ')) || (p1 = p + strlen (p)))
-	  {
-	    p = p1;
-	    if (*p == ' ')
-	      {
-		*p = '\0';
-		find_exec (prog, path);
-		*p = ' ';
-		p ++;
-	      }
-	    else if (*p == '\0')
-	      find_exec (prog, path);
-	  }
-      while (!path.exists() && *p);
-    }
-  const char *argv[] = {"", NULL}; /* Dummy */
-  av av1;
-  av1.setup ("", path, "", 1, argv, false);
+  bool path_iscygexec = fhandler_termios::path_iscygexec_w (n, c);
   set_switch_to_pcon (&siov->hStdInput, &siov->hStdOutput, &siov->hStdError,
-		      path.iscygexec ());
+		      path_iscygexec);
   BOOL ret = CreateProcessW_Orig (n, c, pa, ta, inh, f, e, d, siov, pi);
   h_gdb_process = pi->hProcess;
   DuplicateHandle (GetCurrentProcess (), h_gdb_process,
@@ -325,7 +329,7 @@ CreateProcessW_Hooked
   debug_process = !!(f & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS));
   if (debug_process)
     mutex_timeout = 0; /* to avoid deadlock in GDB */
-  if (!atexit_func_registered && !path.iscygexec ())
+  if (!atexit_func_registered && !path_iscygexec)
     {
       atexit (atexit_func);
       atexit_func_registered = true;
-- 
2.35.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 8/8] Cygwin: console: Set console mode even if stdin/stdout is redirected.
  2022-02-13 14:39 [PATCH 0/8] Several modifications for pty and console code Takashi Yano
                   ` (6 preceding siblings ...)
  2022-02-13 14:39 ` [PATCH 7/8] Cygwin: console: Fix console mode for non-cygwin inferior of GDB Takashi Yano
@ 2022-02-13 14:39 ` Takashi Yano
  7 siblings, 0 replies; 9+ messages in thread
From: Takashi Yano @ 2022-02-13 14:39 UTC (permalink / raw)
  To: cygwin-patches

- When non-cygwin app is started in console, console mode is set to
  tty::native. However, if stdin is redirected, current code does not
  set the input mode of the console. In this case, if the app opens
  "CONIN$", the console mode will not be appropriate for non-cygwin
  app. This patch fixes the issue.

Addresses:
https://github.com/GitCredentialManager/git-credential-manager/issues/576
---
 winsup/cygwin/spawn.cc | 19 +++++++------------
 1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc
index 81dba5a94..a7e25cc20 100644
--- a/winsup/cygwin/spawn.cc
+++ b/winsup/cygwin/spawn.cc
@@ -627,23 +627,18 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
 	    }
 	  else if (fh && fh->get_major () == DEV_CONS_MAJOR)
 	    {
-	      fhandler_console *cons = (fhandler_console *) fh;
-	      if (!iscygwin ())
+	      if (!iscygwin () && cons_native == NULL)
 		{
-		  if (cons_native == NULL)
-		    {
-		      cons_native = cons;
-		      cons_ti = &((tty *)cons->tc ())->ti;
-		      cons_owner = cons->get_owner ();
-		    }
+		  fhandler_console *cons = (fhandler_console *) fh;
+		  cons_native = cons;
+		  cons_ti = &((tty *)cons->tc ())->ti;
+		  cons_owner = cons->get_owner ();
 		  tty::cons_mode conmode =
 		    (ctty_pgid && ctty_pgid == myself->pgid) ?
 		    tty::native : tty::restore;
-		  if (fd == 0)
-		    fhandler_console::set_input_mode (conmode,
+		  fhandler_console::set_input_mode (conmode,
 					   cons_ti, cons->get_handle_set ());
-		  else if (fd == 1 || fd == 2)
-		    fhandler_console::set_output_mode (conmode,
+		  fhandler_console::set_output_mode (conmode,
 					   cons_ti, cons->get_handle_set ());
 		}
 	    }
-- 
2.35.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2022-02-13 14:40 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-13 14:39 [PATCH 0/8] Several modifications for pty and console code Takashi Yano
2022-02-13 14:39 ` [PATCH 1/8] Cygwin: pty, console: Fix Ctrl-C handling for non-cygwin apps Takashi Yano
2022-02-13 14:39 ` [PATCH 2/8] Cygwin: pty: Pass Ctrl-Z (EOF) to non-cygwin apps with disable_pcon Takashi Yano
2022-02-13 14:39 ` [PATCH 3/8] Cygwin: pty: Prevent deadlock on echo output Takashi Yano
2022-02-13 14:39 ` [PATCH 4/8] Cygwin: pty: Revise the code to wait for completion of forwarding Takashi Yano
2022-02-13 14:39 ` [PATCH 5/8] Cygwin: pty: Discard input in from_master_nat pipe on signal as well Takashi Yano
2022-02-13 14:39 ` [PATCH 6/8] Cygwin: pty: Fix a bug in tty_min::segpgid() Takashi Yano
2022-02-13 14:39 ` [PATCH 7/8] Cygwin: console: Fix console mode for non-cygwin inferior of GDB Takashi Yano
2022-02-13 14:39 ` [PATCH 8/8] Cygwin: console: Set console mode even if stdin/stdout is redirected Takashi Yano

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).