Re: [PATCH 0/1] Fix PTY state management in pseudo console support.

2019-08-31 Thread Takashi Yano
This patch has a small bug.
Please use v2 instead.

On Sat, 31 Aug 2019 23:53:17 +0900
Takashi Yano  wrote:

> Pseudo console support in test release TEST: Cygwin 3.1.0-0.3,
> introduced by commit 169d65a5774acc76ce3f3feeedcbae7405aa9b57,
> has some bugs which cause mismatch between state variables and
> real pseudo console state regarding console attaching and r/w
> pipe switching. This patch fixes this issue by redesigning the
> state management.
> 
> Takashi Yano (1):
>   Cygwin: pty: Fix state management for pseudo console support.
> 
>  winsup/cygwin/dtable.cc   |  15 +-
>  winsup/cygwin/fhandler.h  |   6 +-
>  winsup/cygwin/fhandler_console.cc |   6 +-
>  winsup/cygwin/fhandler_tty.cc | 401 --
>  winsup/cygwin/fork.cc |  24 +-
>  winsup/cygwin/spawn.cc|  65 ++---
>  6 files changed, 280 insertions(+), 237 deletions(-)
> 
> -- 
> 2.21.0
> 


-- 
Takashi Yano 


[PATCH v2 1/1] Cygwin: pty: Fix state management for pseudo console support.

2019-08-31 Thread Takashi Yano
- Pseudo console support introduced by commit
  169d65a5774acc76ce3f3feeedcbae7405aa9b57 has some bugs which
  cause mismatch between state variables and real pseudo console
  state regarding console attaching and r/w pipe switching. This
  patch fixes this issue by redesigning the state management.
---
 winsup/cygwin/dtable.cc   |  15 +-
 winsup/cygwin/fhandler.h  |   6 +-
 winsup/cygwin/fhandler_console.cc |   6 +-
 winsup/cygwin/fhandler_tty.cc | 404 --
 winsup/cygwin/fork.cc |  24 +-
 winsup/cygwin/spawn.cc|  65 ++---
 6 files changed, 283 insertions(+), 237 deletions(-)

diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc
index ba5d16206..6266f1bc2 100644
--- a/winsup/cygwin/dtable.cc
+++ b/winsup/cygwin/dtable.cc
@@ -150,8 +150,11 @@ dtable::stdio_init ()
   bool need_fixup_handle = false;
   fhandler_pty_slave *ptys = NULL;
   bool is_pty[3] = {false, false, false};
-  for (int fd = 0; fd < 3; fd ++)
+  bool already_attached = false;
+  int chk_order[] = {1, 0, 2};
+  for (int i = 0; i < 3; i ++)
 {
+  int fd = chk_order[i];
   fhandler_base *fh = cygheap->fdtab[fd];
   if (fh && fh->get_major () == DEV_PTYS_MAJOR)
{
@@ -161,14 +164,18 @@ dtable::stdio_init ()
  is_pty[fd] = true;
  bool attached = !!fhandler_console::get_console_process_id
(ptys->getHelperProcessId (), true);
- if (!attached)
+ already_attached = already_attached || attached;
+ if (!already_attached)
{
  /* Not attached to pseudo console in fork() or spawn()
 by some reason. This happens if the executable is
 a windows GUI binary, such as mintty. */
  FreeConsole ();
- AttachConsole (ptys->getHelperProcessId ());
- need_fixup_handle = true;
+ if (AttachConsole (ptys->getHelperProcessId ()))
+   {
+ need_fixup_handle = true;
+ already_attached = true;
+   }
}
  ptys->reset_switch_to_pcon ();
}
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index c75e40c0a..af2b948cb 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -2106,19 +2106,22 @@ class fhandler_pty_common: public fhandler_termios
  protected:
   BOOL process_opost_output (HANDLE h,
 const void *ptr, ssize_t& len, bool is_echo);
-  bool check_switch_to_pcon (void);
 };
 
 class fhandler_pty_slave: public fhandler_pty_common
 {
   HANDLE inuse;// used to indicate that a tty is in use
   HANDLE output_handle_cyg, io_handle_cyg;
+  DWORD pidRestore;
 
   /* Helper functions for fchmod and fchown. */
   bool fch_open_handles (bool chown);
   int fch_set_sd (security_descriptor , bool chown);
   void fch_close_handles ();
 
+  bool try_reattach_pcon ();
+  void restore_reattach_pcon ();
+
  public:
   /* Constructor */
   fhandler_pty_slave (int);
@@ -2172,7 +2175,6 @@ class fhandler_pty_slave: public fhandler_pty_common
   void set_switch_to_pcon (void);
   void reset_switch_to_pcon (void);
   void push_to_pcon_screenbuffer (const char *ptr, size_t len);
-  bool has_master_opened (void);
   void mask_switch_to_pcon (bool mask)
   {
 get_ttyp ()->mask_switch_to_pcon = mask;
diff --git a/winsup/cygwin/fhandler_console.cc 
b/winsup/cygwin/fhandler_console.cc
index 997c50d23..ae7f66b80 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -3138,14 +3138,14 @@ fhandler_console::get_console_process_id (DWORD pid, 
bool match)
   DWORD tmp;
   int num = GetConsoleProcessList (, 1);
   DWORD *list = (DWORD *)
- HeapAlloc (GetProcessHeap (), 0, num * sizeof (DWORD));
-  num = GetConsoleProcessList (list, num);
+ HeapAlloc (GetProcessHeap (), 0, (num + 16) * sizeof (DWORD));
+  num = GetConsoleProcessList (list, num + 16);
   tmp = 0;
   for (int i=0; iset_switch_to_pcon ();
-   return;
   }
 }
 
@@ -381,25 +380,6 @@ fhandler_pty_common::__release_output_mutex (const char 
*fn, int ln)
 #endif
 }
 
-static bool switch_to_pcon_prev;
-
-bool
-fhandler_pty_common::check_switch_to_pcon (void)
-{
-  bool switch_to_pcon_now = get_ttyp ()->switch_to_pcon;
-  if (!isHybrid && !switch_to_pcon_prev && switch_to_pcon_now)
-{
-  Sleep (40);
-  /* Check again */
-  switch_to_pcon_now = get_ttyp ()->switch_to_pcon;
-  if (switch_to_pcon_now)
-   switch_to_pcon_prev = true;
-}
-  else
-switch_to_pcon_prev = switch_to_pcon_now;
-  return switch_to_pcon_prev;
-}
-
 /* Process pty input. */
 
 void
@@ -595,7 +575,7 @@ out:
 
 fhandler_pty_slave::fhandler_pty_slave (int unit)
   : fhandler_pty_common (), inuse (NULL), output_handle_cyg (NULL),
-  io_handle_cyg (NULL)
+  io_handle_cyg (NULL), 

[PATCH v2 0/1] Fix PTY state management in pseudo console support.

2019-08-31 Thread Takashi Yano
Pseudo console support in test release TEST: Cygwin 3.1.0-0.3,
introduced by commit 169d65a5774acc76ce3f3feeedcbae7405aa9b57,
has some bugs which cause mismatch between state variables and
real pseudo console state regarding console attaching and r/w
pipe switching. This patch fixes this issue by redesigning the
state management.

v2:
Small bug fixed from v1.

Takashi Yano (1):
  Cygwin: pty: Fix state management for pseudo console support.

 winsup/cygwin/dtable.cc   |  15 +-
 winsup/cygwin/fhandler.h  |   6 +-
 winsup/cygwin/fhandler_console.cc |   6 +-
 winsup/cygwin/fhandler_tty.cc | 404 --
 winsup/cygwin/fork.cc |  24 +-
 winsup/cygwin/spawn.cc|  65 ++---
 6 files changed, 283 insertions(+), 237 deletions(-)

-- 
2.21.0



[PATCH 0/1] Fix PTY state management in pseudo console support.

2019-08-31 Thread Takashi Yano
Pseudo console support in test release TEST: Cygwin 3.1.0-0.3,
introduced by commit 169d65a5774acc76ce3f3feeedcbae7405aa9b57,
has some bugs which cause mismatch between state variables and
real pseudo console state regarding console attaching and r/w
pipe switching. This patch fixes this issue by redesigning the
state management.

Takashi Yano (1):
  Cygwin: pty: Fix state management for pseudo console support.

 winsup/cygwin/dtable.cc   |  15 +-
 winsup/cygwin/fhandler.h  |   6 +-
 winsup/cygwin/fhandler_console.cc |   6 +-
 winsup/cygwin/fhandler_tty.cc | 401 --
 winsup/cygwin/fork.cc |  24 +-
 winsup/cygwin/spawn.cc|  65 ++---
 6 files changed, 280 insertions(+), 237 deletions(-)

-- 
2.21.0



[PATCH 1/1] Cygwin: pty: Fix state management for pseudo console support.

2019-08-31 Thread Takashi Yano
- Pseudo console support introduced by commit
  169d65a5774acc76ce3f3feeedcbae7405aa9b57 has some bugs which
  cause mismatch between state variables and real pseudo console
  state regarding console attaching and r/w pipe switching. This
  patch fixes this issue by redesigning the state management.
---
 winsup/cygwin/dtable.cc   |  15 +-
 winsup/cygwin/fhandler.h  |   6 +-
 winsup/cygwin/fhandler_console.cc |   6 +-
 winsup/cygwin/fhandler_tty.cc | 401 --
 winsup/cygwin/fork.cc |  24 +-
 winsup/cygwin/spawn.cc|  65 ++---
 6 files changed, 280 insertions(+), 237 deletions(-)

diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc
index ba5d16206..6266f1bc2 100644
--- a/winsup/cygwin/dtable.cc
+++ b/winsup/cygwin/dtable.cc
@@ -150,8 +150,11 @@ dtable::stdio_init ()
   bool need_fixup_handle = false;
   fhandler_pty_slave *ptys = NULL;
   bool is_pty[3] = {false, false, false};
-  for (int fd = 0; fd < 3; fd ++)
+  bool already_attached = false;
+  int chk_order[] = {1, 0, 2};
+  for (int i = 0; i < 3; i ++)
 {
+  int fd = chk_order[i];
   fhandler_base *fh = cygheap->fdtab[fd];
   if (fh && fh->get_major () == DEV_PTYS_MAJOR)
{
@@ -161,14 +164,18 @@ dtable::stdio_init ()
  is_pty[fd] = true;
  bool attached = !!fhandler_console::get_console_process_id
(ptys->getHelperProcessId (), true);
- if (!attached)
+ already_attached = already_attached || attached;
+ if (!already_attached)
{
  /* Not attached to pseudo console in fork() or spawn()
 by some reason. This happens if the executable is
 a windows GUI binary, such as mintty. */
  FreeConsole ();
- AttachConsole (ptys->getHelperProcessId ());
- need_fixup_handle = true;
+ if (AttachConsole (ptys->getHelperProcessId ()))
+   {
+ need_fixup_handle = true;
+ already_attached = true;
+   }
}
  ptys->reset_switch_to_pcon ();
}
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index c75e40c0a..af2b948cb 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -2106,19 +2106,22 @@ class fhandler_pty_common: public fhandler_termios
  protected:
   BOOL process_opost_output (HANDLE h,
 const void *ptr, ssize_t& len, bool is_echo);
-  bool check_switch_to_pcon (void);
 };
 
 class fhandler_pty_slave: public fhandler_pty_common
 {
   HANDLE inuse;// used to indicate that a tty is in use
   HANDLE output_handle_cyg, io_handle_cyg;
+  DWORD pidRestore;
 
   /* Helper functions for fchmod and fchown. */
   bool fch_open_handles (bool chown);
   int fch_set_sd (security_descriptor , bool chown);
   void fch_close_handles ();
 
+  bool try_reattach_pcon ();
+  void restore_reattach_pcon ();
+
  public:
   /* Constructor */
   fhandler_pty_slave (int);
@@ -2172,7 +2175,6 @@ class fhandler_pty_slave: public fhandler_pty_common
   void set_switch_to_pcon (void);
   void reset_switch_to_pcon (void);
   void push_to_pcon_screenbuffer (const char *ptr, size_t len);
-  bool has_master_opened (void);
   void mask_switch_to_pcon (bool mask)
   {
 get_ttyp ()->mask_switch_to_pcon = mask;
diff --git a/winsup/cygwin/fhandler_console.cc 
b/winsup/cygwin/fhandler_console.cc
index 997c50d23..ae7f66b80 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -3138,14 +3138,14 @@ fhandler_console::get_console_process_id (DWORD pid, 
bool match)
   DWORD tmp;
   int num = GetConsoleProcessList (, 1);
   DWORD *list = (DWORD *)
- HeapAlloc (GetProcessHeap (), 0, num * sizeof (DWORD));
-  num = GetConsoleProcessList (list, num);
+ HeapAlloc (GetProcessHeap (), 0, (num + 16) * sizeof (DWORD));
+  num = GetConsoleProcessList (list, num + 16);
   tmp = 0;
   for (int i=0; iset_switch_to_pcon ();
-   return;
   }
 }
 
@@ -381,25 +380,6 @@ fhandler_pty_common::__release_output_mutex (const char 
*fn, int ln)
 #endif
 }
 
-static bool switch_to_pcon_prev;
-
-bool
-fhandler_pty_common::check_switch_to_pcon (void)
-{
-  bool switch_to_pcon_now = get_ttyp ()->switch_to_pcon;
-  if (!isHybrid && !switch_to_pcon_prev && switch_to_pcon_now)
-{
-  Sleep (40);
-  /* Check again */
-  switch_to_pcon_now = get_ttyp ()->switch_to_pcon;
-  if (switch_to_pcon_now)
-   switch_to_pcon_prev = true;
-}
-  else
-switch_to_pcon_prev = switch_to_pcon_now;
-  return switch_to_pcon_prev;
-}
-
 /* Process pty input. */
 
 void
@@ -595,7 +575,7 @@ out:
 
 fhandler_pty_slave::fhandler_pty_slave (int unit)
   : fhandler_pty_common (), inuse (NULL), output_handle_cyg (NULL),
-  io_handle_cyg (NULL)
+  io_handle_cyg (NULL),