Re: [PATCH 0/2] Return appropriate handle by _get_osfhandle() and GetStdHandle().

2021-03-23 Thread Takashi Yano via Cygwin-patches
On Tue, 23 Mar 2021 21:42:06 +0900
Takashi Yano wrote:
> On Tue, 23 Mar 2021 21:32:12 +0900
> Takashi Yano wrote:
> > I try to check run.exe behaviour and noticed that
> > run cmd.exe
> > and
> > run cat.exe
> > does not work with cygwin 3.0.7 and 3.2.0 (TEST) while these
> > work in 3.1.7.
> 
> In obove cases, cmd.exe and cat.exe is running in *hidden* console,
> therefore nothing is shown. Right?

In what situation are
  psi->cb = sizeof (STARTUPINFO);
  psi->hStdInput  = GetStdHandle (STD_INPUT_HANDLE);
  psi->hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);
  psi->hStdError  = GetStdHandle (STD_ERROR_HANDLE);
these handles used?

-- 
Takashi Yano 


Re: [PATCH 0/2] Return appropriate handle by _get_osfhandle() and GetStdHandle().

2021-03-23 Thread Takashi Yano via Cygwin-patches
On Tue, 23 Mar 2021 21:32:12 +0900
Takashi Yano wrote:
> I try to check run.exe behaviour and noticed that
> run cmd.exe
> and
> run cat.exe
> does not work with cygwin 3.0.7 and 3.2.0 (TEST) while these
> work in 3.1.7.

In obove cases, cmd.exe and cat.exe is running in *hidden* console,
therefore nothing is shown. Right?

-- 
Takashi Yano 


Re: [PATCH 0/2] Return appropriate handle by _get_osfhandle() and GetStdHandle().

2021-03-23 Thread Takashi Yano via Cygwin-patches
On Tue, 23 Mar 2021 13:17:16 +0100
Corinna Vinschen wrote:
> On Mar 23 20:57, Takashi Yano via Cygwin-patches wrote:
> > Corinna Vinschen wrote:
> > > > > On Mar 22 08:07, Takashi Yano via Cygwin-patches wrote:
> > > > > > > And also, following cygwin apps/dlls call GetStdHandle():
> > > > > > > ccmake.exe
> > > > > > > cmake.exe
> > > > > > > cpack.exe
> > > > > > > ctest.exe
> > > > > > > run.exe
> > > 
> > > run creates its own conin/conout handles to create a hidden console.
> > > The code calling GetStdHandle() is only for debug purposes and never
> > > built into the executable.
> 
> Sorry, but this was utterly wrong.  run calls GetStdHandle, then
> overwrites the handles, but only if it doesn't already is attached to a
> console.
> 
> > > Looks right to me.  If we patch cmake to do the right thing, do we still
> > > need this patch, Takashi?
> > 
> > I don't think so. If all is well with current code, nothing to be fixed.
> 
> How do you evaluate this in light of the run behaviour above?

I try to check run.exe behaviour and noticed that
run cmd.exe
and
run cat.exe
does not work with cygwin 3.0.7 and 3.2.0 (TEST) while these
work in 3.1.7.

Is this expected behaviour?

-- 
Takashi Yano 


Re: [PATCH 0/2] Return appropriate handle by _get_osfhandle() and GetStdHandle().

2021-03-23 Thread Takashi Yano via Cygwin-patches
On Tue, 23 Mar 2021 11:10:04 +0100
Corinna Vinschen wrote:
> [CC Marco, CC Jan]
> 
> On Mar 22 13:02, Ken Brown via Cygwin-patches wrote:
> > [Still CC Marco]
> > 
> > On 3/22/2021 7:43 AM, Corinna Vinschen via Cygwin-patches wrote:
> > > [CC Marco]
> > > 
> > > On Mar 22 08:07, Takashi Yano via Cygwin-patches wrote:
> > > > On Sun, 21 Mar 2021 17:44:27 +0900
> > > > Takashi Yano wrote:
> > > > > [...]
> > > > > However, following cygwin apps/dlls call _get_osfhandle():
> > > > > ccmake.exe
> > > > > cmake.exe
> > > > > cpack.exe
> > > > > ctest.exe
> > > > > ddrescue.exe
> 
> I'm pretty sure ddrescue needs the osfhandle just to access raw block
> devices.
> 
> > > > > And also, following cygwin apps/dlls call GetStdHandle():
> > > > > ccmake.exe
> > > > > cmake.exe
> > > > > cpack.exe
> > > > > ctest.exe
> > > > > run.exe
> 
> run creates its own conin/conout handles to create a hidden console.
> The code calling GetStdHandle() is only for debug purposes and never
> built into the executable.
> 
> > > > > cygusb0.dll
> 
> This lib tries to access USB devices only.
> 
> > > > > tk86.dll
> 
> Not sure about this one.  In theory this shouldn't happen, given our
> tk is built against X11, not against the Windows GUI.
> 
> Jan, can you please check where and why tk86.dll calls GetStdHandle.
> I found a few places in the source where GetStdHandle is called, but
> it's not clear to me which one is called.

Thanks for checking obove.

> > Out of curiosity, I took a quick glance at the cmake code.  It appears that
> > this code is designed to support running cmake in a Console.  I don't think
> > that should be needed any more, if it ever was.
> > [...]
> > I think the following might suffice (untested):
> > 
> > --- a/Source/kwsys/Terminal.c
> > +++ b/Source/kwsys/Terminal.c
> > @@ -10,7 +10,7 @@
> >  #endif
> > 
> >  /* Configure support for this platform.  */
> > -#if defined(_WIN32) || defined(__CYGWIN__)
> > +#if defined(_WIN32)
> >  #  define KWSYS_TERMINAL_SUPPORT_CONSOLE
> >  #endif
> >  #if !defined(_WIN32)
> 
> Looks right to me.  If we patch cmake to do the right thing, do we still
> need this patch, Takashi?

I don't think so. If all is well with current code, nothing to be fixed.

-- 
Takashi Yano 


[PATCH] Cygwin: pty: Rename input/output named pipes.

2021-03-23 Thread Takashi Yano via Cygwin-patches
- Currently, names of output pipes are "pty%d-to-master" and "pty%d-
  to-master-cyg" and names of input pipes are "pty%d-to-slave" and
  "pty%d-from-master". With this patch, these pipes are renamed to
  "pty%d-to-master-nat", "pty%d-to-master", "pty%d-from-master-nat"
  and "pty%d-from-master" respectively.
---
 winsup/cygwin/fhandler_tty.cc | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 643a357ad..d755f7d87 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -2768,26 +2768,26 @@ fhandler_pty_master::setup ()
 termios_printf ("can't set output_handle(%p) to non-blocking mode",
get_output_handle ());
 
-  char pipename[sizeof ("pty-to-master-cyg")];
-  __small_sprintf (pipename, "pty%d-to-master", unit);
+  char pipename[sizeof ("pty-from-master-nat")];
+  __small_sprintf (pipename, "pty%d-to-master-nat", unit);
   res = fhandler_pipe::create (&sec_none, &from_slave, &to_master,
   fhandler_pty_common::pipesize, pipename, 0);
   if (res)
 {
-  errstr = "output pipe";
+  errstr = "output pipe for non-cygwin apps";
   goto err;
 }
 
-  __small_sprintf (pipename, "pty%d-to-master-cyg", unit);
+  __small_sprintf (pipename, "pty%d-to-master", unit);
   res = fhandler_pipe::create (&sec_none, &get_handle (), &to_master_cyg,
   fhandler_pty_common::pipesize, pipename, 0);
   if (res)
 {
-  errstr = "output pipe for cygwin";
+  errstr = "output pipe";
   goto err;
 }
 
-  __small_sprintf (pipename, "pty%d-to-slave", unit);
+  __small_sprintf (pipename, "pty%d-from-master-nat", unit);
   /* FILE_FLAG_OVERLAPPED is specified here in order to prevent
  PeekNamedPipe() from blocking in transfer_input().
  Accordig to the official document, in order to access the handle
-- 
2.31.0



Re: [PATCH] Cygwin: pty: Rename input named pipes.

2021-03-23 Thread Takashi Yano via Cygwin-patches
On Tue, 23 Mar 2021 10:32:34 +0100
Corinna Vinschen wrote:
> On Mar 23 09:38, Takashi Yano via Cygwin-patches wrote:
> > On Mon, 22 Mar 2021 12:49:20 +0100
> > Corinna Vinschen wrote:
> > > Hi Takashi,
> > > 
> > > On Mar 21 12:59, Takashi Yano via Cygwin-patches wrote:
> > > > - Currently, the name of input pipe is "pty-from-master" for
> > > >   cygwin process, and "pty-to-slave" for non-cygwin process.
> > > >   These are not only inconsistent with output pipes but also very
> > > >   confusing.
> > > >   With this patch, these are renamed to "pty-from-master-cyg"
> > > >   and "pty-from-master" respectively.
> > > > ---
> > > >  winsup/cygwin/fhandler_tty.cc | 2 +-
> > > >  winsup/cygwin/tty.cc  | 4 ++--
> > > >  2 files changed, 3 insertions(+), 3 deletions(-)
> > > 
> > > Actually... wouldn't it make more sense to call the Cygwin pipe
> > > 
> > >   pty%d-from-master / pty%d-to-slave
> > > 
> > > and the non-Cygwin one something like
> > > 
> > >   pty%d-from-master-nat / pty%d-to-slave-nat
> > > 
> > > ?
> > > 
> > > After all, Cygwin is the norm, and non-Cygwin is the exception.
> > > 
> > > On second thought, this would also make sense for thr fhandler methods,
> > > i. e.
> > > 
> > >   get_output_handle / get_output_handle_cyg
> > > 
> > > vs.
> > > 
> > >   get_output_handle_nat / get_output_handle
> > > 
> > > Probably the fhandler stuff is too much renaming for this release,
> > > but we should do this for the next one, I think.
> > 
> > I basically agree. However, renaming them consistently is
> > too much for 3.2.0 release as you mentioned. So, IMHO, it
> > is better to apply this patch once for 3.2.0 release and
> > then fully rename them for the next one.
> > 
> > What do you think?
> 
> I thought of renaming the pipes in this release, since you're already
> renaimg it anyway.  Renaming the fhandler members and methods could
> take place in the next release.

OK. I will submit the rename patch.

-- 
Takashi Yano 


Re: [PATCH] Cygwin: pty: Rename input named pipes.

2021-03-22 Thread Takashi Yano via Cygwin-patches
On Mon, 22 Mar 2021 12:49:20 +0100
Corinna Vinschen wrote:
> Hi Takashi,
> 
> On Mar 21 12:59, Takashi Yano via Cygwin-patches wrote:
> > - Currently, the name of input pipe is "pty-from-master" for
> >   cygwin process, and "pty-to-slave" for non-cygwin process.
> >   These are not only inconsistent with output pipes but also very
> >   confusing.
> >   With this patch, these are renamed to "pty-from-master-cyg"
> >   and "pty-from-master" respectively.
> > ---
> >  winsup/cygwin/fhandler_tty.cc | 2 +-
> >  winsup/cygwin/tty.cc  | 4 ++--
> >  2 files changed, 3 insertions(+), 3 deletions(-)
> 
> Actually... wouldn't it make more sense to call the Cygwin pipe
> 
>   pty%d-from-master / pty%d-to-slave
> 
> and the non-Cygwin one something like
> 
>   pty%d-from-master-nat / pty%d-to-slave-nat
> 
> ?
> 
> After all, Cygwin is the norm, and non-Cygwin is the exception.
> 
> On second thought, this would also make sense for thr fhandler methods,
> i. e.
> 
>   get_output_handle / get_output_handle_cyg
> 
> vs.
> 
>   get_output_handle_nat / get_output_handle
> 
> Probably the fhandler stuff is too much renaming for this release,
> but we should do this for the next one, I think.

I basically agree. However, renaming them consistently is
too much for 3.2.0 release as you mentioned. So, IMHO, it
is better to apply this patch once for 3.2.0 release and
then fully rename them for the next one.

What do you think?

-- 
Takashi Yano 


[PATCH v2 3/3] Cygwin: pty: Clear input_available_event if pipe is empty on close.

2021-03-21 Thread Takashi Yano via Cygwin-patches
- If apps read input from get_handle_cyg() directly by ReadFile(),
  input_available_event may remains signalled. This patch clears
  input_available_event if the pipe is empty on closing pty slave.
---
 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 682264130..43e83b807 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -982,6 +982,9 @@ fhandler_pty_slave::close ()
   termios_printf ("closing last open %s handle", ttyname ());
   if (inuse && !CloseHandle (inuse))
 termios_printf ("CloseHandle (inuse), %E");
+  DWORD n;
+  if (bytes_available (n) && !n)
+ResetEvent (input_available_event);
   if (!ForceCloseHandle (input_available_event))
 termios_printf ("CloseHandle (input_available_event<%p>), %E", 
input_available_event);
   if (!ForceCloseHandle (get_output_handle_cyg ()))
-- 
2.30.2



[PATCH v2 2/3] Cygwin: pty: Add hook for GetStdHandle() to return appropriate handle.

2021-03-21 Thread Takashi Yano via Cygwin-patches
- Currently, GetStdHandle(STD_INPUT_HANDLE) returns input handle for
  non-cygwin process. If cygwin process read from non-cygwin pipe,
  this causes hang up because master writes input to cygwin pipe.
  Also, setup_locale() is called to make charset conversion for output
  handle work properly.
---
 winsup/cygwin/fhandler_tty.cc | 28 +---
 1 file changed, 21 insertions(+), 7 deletions(-)

diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 02e94efcc..682264130 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -118,7 +118,7 @@ set_switch_to_pcon (HANDLE *in, HANDLE *out, HANDLE *err, 
bool iscygwin)
   fhandler_pty_slave *ptys_pcon = NULL;
   while ((fd = cfd.next ()) >= 0)
 {
-  if (*in == cfd->get_handle () ||
+  if (*in == cfd->get_handle () || *in == cfd->get_handle_cyg () ||
  (fd == 0 && *in == GetStdHandle (STD_INPUT_HANDLE)))
replace_in = (fhandler_base *) cfd;
   if (*out == cfd->get_output_handle () ||
@@ -140,12 +140,7 @@ set_switch_to_pcon (HANDLE *in, HANDLE *out, HANDLE *err, 
bool iscygwin)
   if (!iscygwin && ptys_pcon)
 ptys_pcon->set_switch_to_pcon ();
   if (replace_in)
-{
-  if (iscygwin && ptys_pcon->pcon_activated ())
-   *in = replace_in->get_handle_cyg ();
-  else
-   *in = replace_in->get_handle ();
-}
+*in = replace_in->get_handle ();
   if (replace_out)
 *out = replace_out->get_output_handle ();
   if (replace_err)
@@ -157,6 +152,7 @@ set_switch_to_pcon (HANDLE *in, HANDLE *out, HANDLE *err, 
bool iscygwin)
 DEF_HOOK (CreateProcessA);
 DEF_HOOK (CreateProcessW);
 DEF_HOOK (exit);
+DEF_HOOK (GetStdHandle);
 
 static BOOL WINAPI
 CreateProcessA_Hooked
@@ -300,6 +296,23 @@ exit_Hooked (int e)
   exit_Orig (e);
 }
 
+static HANDLE WINAPI
+GetStdHandle_Hooked (DWORD h)
+{
+  HANDLE r = GetStdHandle_Orig (h);
+  cygheap_fdenum cfd (false);
+  while (cfd.next () >= 0)
+if (cfd->get_major () == DEV_PTYS_MAJOR)
+  {
+   fhandler_pty_slave *ptys =
+ (fhandler_pty_slave *) (fhandler_base *) cfd;
+   ptys->setup_locale ();
+   if (r == cfd->get_handle ())
+ return cfd->get_handle_cyg ();
+  }
+  return r;
+}
+
 static void
 convert_mb_str (UINT cp_to, char *ptr_to, size_t *len_to,
UINT cp_from, const char *ptr_from, size_t len_from,
@@ -2349,6 +2362,7 @@ fhandler_pty_slave::fixup_after_exec ()
   DO_HOOK (NULL, CreateProcessW);
   if (CreateProcessA_Orig || CreateProcessW_Orig)
 DO_HOOK (NULL, exit);
+  DO_HOOK (NULL, GetStdHandle);
 }
 
 /* This thread function handles the master control pipe.  It waits for a
-- 
2.30.2



[PATCH v2 1/3] Cygwin: syscalls.cc: Make _get_osfhandle() return appropriate handle.

2021-03-21 Thread Takashi Yano via Cygwin-patches
- Currently, _get_osfhandle() returns input handle for pty even for
  stdout and stdout. This patch fixes the issue. Also, setup_locale()
  is called to make sure the charset conversion works for output.
---
 winsup/cygwin/syscalls.cc | 13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index 6ba4f10f7..205d15951 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -3223,7 +3223,18 @@ _get_osfhandle (int fd)
 
   cygheap_fdget cfd (fd);
   if (cfd >= 0)
-res = (long) cfd->get_handle ();
+{
+  if (cfd->get_major () == DEV_PTYS_MAJOR)
+   {
+ fhandler_pty_slave *ptys =
+   (fhandler_pty_slave *) (fhandler_base *) cfd;
+ ptys->setup_locale ();
+   }
+  if (fd == 1 || fd == 2)
+   res = (long) cfd->get_output_handle ();
+  else
+   res = (long) cfd->get_handle_cyg ();
+}
   else
 res = -1;
 
-- 
2.30.2



[PATCH v2 0/3] Return appropriate handle by _get_osfhandle() and GetStdHandle().

2021-03-21 Thread Takashi Yano via Cygwin-patches
Takashi Yano (3):
  Cygwin: syscalls.cc: Make _get_osfhandle() return appropriate handle.
  Cygwin: pty: Add hook for GetStdHandle() to return appropriate handle.
  Cygwin: pty: Clear input_available_event if pipe is empty on close.

 winsup/cygwin/fhandler_tty.cc | 31 ---
 winsup/cygwin/syscalls.cc | 13 -
 2 files changed, 36 insertions(+), 8 deletions(-)

-- 
2.30.2



Re: [PATCH 0/2] Return appropriate handle by _get_osfhandle() and GetStdHandle().

2021-03-21 Thread Takashi Yano via Cygwin-patches
On Sun, 21 Mar 2021 17:44:27 +0900
Takashi Yano wrote:
> On Sun, 21 Mar 2021 13:01:24 +0900
> Takashi Yano wrote:
> > Takashi Yano (2):
> >   Cygwin: syscalls.cc: Make _get_osfhandle() return appropriate handle.
> >   Cygwin: pty: Add hook for GetStdHandle() to return appropriate handle.
> > 
> >  winsup/cygwin/fhandler_tty.cc | 19 +++
> >  winsup/cygwin/syscalls.cc | 13 -
> >  2 files changed, 31 insertions(+), 1 deletion(-)
> 
> I submitted these patches, however, I still wonder if we really
> need these patches. I cannot imagine the situation where handle
> itself is needed rather than file descriptor.
> 
> However, following cygwin apps/dlls call _get_osfhandle():
> ccmake.exe
> cmake.exe
> cpack.exe
> ctest.exe
> ddrescue.exe
> 
> And also, following cygwin apps/dlls call GetStdHandle():
> ccmake.exe
> cmake.exe
> cpack.exe
> ctest.exe
> run.exe
> cygusb0.dll
> tk86.dll
> 
> in my installation.
> 
> Therefore, some of these apps/dlls may need these patches...

I looked into cmake source and found the patch exactly for
this issue. Therefore, it seems better to fix this. 

/* Get the Windows handle for a FILE stream.  */
static HANDLE kwsysTerminalGetStreamHandle(FILE* stream)
{
  /* Get the C-library file descriptor from the stream.  */
  int fd = fileno(stream);

#  if defined(__CYGWIN__)
  /* Cygwin seems to have an extra pipe level.  If the file descriptor
 corresponds to stdout or stderr then obtain the matching windows
 handle directly.  */
  if (fd == fileno(stdout)) {
return GetStdHandle(STD_OUTPUT_HANDLE);
  } else if (fd == fileno(stderr)) {
return GetStdHandle(STD_ERROR_HANDLE);
  }
#  endif

  /* Get the underlying Windows handle for the descriptor.  */
  return (HANDLE)_get_osfhandle(fd);
}


-- 
Takashi Yano 


Re: [PATCH 0/2] Return appropriate handle by _get_osfhandle() and GetStdHandle().

2021-03-21 Thread Takashi Yano via Cygwin-patches
On Sun, 21 Mar 2021 13:01:24 +0900
Takashi Yano wrote:
> Takashi Yano (2):
>   Cygwin: syscalls.cc: Make _get_osfhandle() return appropriate handle.
>   Cygwin: pty: Add hook for GetStdHandle() to return appropriate handle.
> 
>  winsup/cygwin/fhandler_tty.cc | 19 +++
>  winsup/cygwin/syscalls.cc | 13 -
>  2 files changed, 31 insertions(+), 1 deletion(-)

I submitted these patches, however, I still wonder if we really
need these patches. I cannot imagine the situation where handle
itself is needed rather than file descriptor.

However, following cygwin apps/dlls call _get_osfhandle():
ccmake.exe
cmake.exe
cpack.exe
ctest.exe
ddrescue.exe

And also, following cygwin apps/dlls call GetStdHandle():
ccmake.exe
cmake.exe
cpack.exe
ctest.exe
run.exe
cygusb0.dll
tk86.dll

in my installation.

Therefore, some of these apps/dlls may need these patches...

-- 
Takashi Yano 


[PATCH 2/2] Cygwin: pty: Add hook for GetStdHandle() to return appropriate handle.

2021-03-20 Thread Takashi Yano via Cygwin-patches
- Currently, GetStdHandle(STD_INPUT_HANDLE) returns input handle for
  non-cygwin process. If cygwin process read from non-cygwin pipe,
  this causes hang up because master writes input to cygwin pipe.
  Also, setup_locale() is called to make charset conversion for output
  handle work properly.
---
 winsup/cygwin/fhandler_tty.cc | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 02e94efcc..c1f11f399 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -157,6 +157,7 @@ set_switch_to_pcon (HANDLE *in, HANDLE *out, HANDLE *err, 
bool iscygwin)
 DEF_HOOK (CreateProcessA);
 DEF_HOOK (CreateProcessW);
 DEF_HOOK (exit);
+DEF_HOOK (GetStdHandle);
 
 static BOOL WINAPI
 CreateProcessA_Hooked
@@ -300,6 +301,23 @@ exit_Hooked (int e)
   exit_Orig (e);
 }
 
+static HANDLE WINAPI
+GetStdHandle_Hooked (DWORD h)
+{
+  HANDLE r = GetStdHandle_Orig (h);
+  cygheap_fdenum cfd (false);
+  while (cfd.next () >= 0)
+if (cfd->get_major () == DEV_PTYS_MAJOR)
+  {
+   fhandler_pty_slave *ptys =
+ (fhandler_pty_slave *) (fhandler_base *) cfd;
+   ptys->setup_locale ();
+   if (r == cfd->get_handle ())
+ return cfd->get_handle_cyg ();
+  }
+  return r;
+}
+
 static void
 convert_mb_str (UINT cp_to, char *ptr_to, size_t *len_to,
UINT cp_from, const char *ptr_from, size_t len_from,
@@ -2349,6 +2367,7 @@ fhandler_pty_slave::fixup_after_exec ()
   DO_HOOK (NULL, CreateProcessW);
   if (CreateProcessA_Orig || CreateProcessW_Orig)
 DO_HOOK (NULL, exit);
+  DO_HOOK (NULL, GetStdHandle);
 }
 
 /* This thread function handles the master control pipe.  It waits for a
-- 
2.30.1



[PATCH 1/2] Cygwin: syscalls.cc: Make _get_osfhandle() return appropriate handle.

2021-03-20 Thread Takashi Yano via Cygwin-patches
- Currently, _get_osfhandle() returns input handle for pty even for
  stdout and stdout. This patch fixes the issue. Also, setup_locale()
  is called to make sure the charset conversion works for output.
---
 winsup/cygwin/syscalls.cc | 13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index 6ba4f10f7..205d15951 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -3223,7 +3223,18 @@ _get_osfhandle (int fd)
 
   cygheap_fdget cfd (fd);
   if (cfd >= 0)
-res = (long) cfd->get_handle ();
+{
+  if (cfd->get_major () == DEV_PTYS_MAJOR)
+   {
+ fhandler_pty_slave *ptys =
+   (fhandler_pty_slave *) (fhandler_base *) cfd;
+ ptys->setup_locale ();
+   }
+  if (fd == 1 || fd == 2)
+   res = (long) cfd->get_output_handle ();
+  else
+   res = (long) cfd->get_handle_cyg ();
+}
   else
 res = -1;
 
-- 
2.30.1



[PATCH 0/2] Return appropriate handle by _get_osfhandle() and GetStdHandle().

2021-03-20 Thread Takashi Yano via Cygwin-patches
Takashi Yano (2):
  Cygwin: syscalls.cc: Make _get_osfhandle() return appropriate handle.
  Cygwin: pty: Add hook for GetStdHandle() to return appropriate handle.

 winsup/cygwin/fhandler_tty.cc | 19 +++
 winsup/cygwin/syscalls.cc | 13 -
 2 files changed, 31 insertions(+), 1 deletion(-)

-- 
2.30.1



[PATCH] Cygwin: pty: Rename input named pipes.

2021-03-20 Thread Takashi Yano via Cygwin-patches
- Currently, the name of input pipe is "pty-from-master" for
  cygwin process, and "pty-to-slave" for non-cygwin process.
  These are not only inconsistent with output pipes but also very
  confusing.
  With this patch, these are renamed to "pty-from-master-cyg"
  and "pty-from-master" respectively.
---
 winsup/cygwin/fhandler_tty.cc | 2 +-
 winsup/cygwin/tty.cc  | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 643a357ad..02e94efcc 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -2787,7 +2787,7 @@ fhandler_pty_master::setup ()
   goto err;
 }
 
-  __small_sprintf (pipename, "pty%d-to-slave", unit);
+  __small_sprintf (pipename, "pty%d-from-master", unit);
   /* FILE_FLAG_OVERLAPPED is specified here in order to prevent
  PeekNamedPipe() from blocking in transfer_input().
  Accordig to the official document, in order to access the handle
diff --git a/winsup/cygwin/tty.cc b/winsup/cygwin/tty.cc
index 3c016315c..269b87735 100644
--- a/winsup/cygwin/tty.cc
+++ b/winsup/cygwin/tty.cc
@@ -159,8 +159,8 @@ tty::not_allocated (HANDLE& r, HANDLE& w)
 {
   /* Attempt to open the from-master side of the tty.  If it is accessible
  then it exists although we may not have privileges to actually use it. */
-  char pipename[sizeof("pty-from-master")];
-  __small_sprintf (pipename, "pty%d-from-master", get_minor ());
+  char pipename[sizeof("pty-from-master-cyg")];
+  __small_sprintf (pipename, "pty%d-from-master-cyg", get_minor ());
   /* fhandler_pipe::create returns 0 when creation succeeds */
   return fhandler_pipe::create (&sec_none, &r, &w,
fhandler_pty_common::pipesize, pipename,
-- 
2.30.1



[PATCH] Cygwin: pty: Transfer input only if the stdin is a pty.

2021-03-08 Thread Takashi Yano via Cygwin-patches
- The commit 12325677f73a did not fix enough. With this patch, more
  transfer_input() calls are skipped if stdin is redirected or piped.
---
 winsup/cygwin/fhandler_tty.cc | 10 --
 winsup/cygwin/spawn.cc|  9 +++--
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 47d59e8c5..643a357ad 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -131,7 +131,9 @@ set_switch_to_pcon (HANDLE *in, HANDLE *out, HANDLE *err, 
bool iscygwin)
{
  fhandler_base *fh = cfd;
  fhandler_pty_slave *ptys = (fhandler_pty_slave *) fh;
- if (*in == ptys->get_handle ())
+ if (*in == ptys->get_handle ()
+ || *out == ptys->get_output_handle ()
+ || *err == ptys->get_output_handle ())
ptys_pcon = ptys;
}
 }
@@ -284,6 +286,7 @@ exit_Hooked (int e)
HANDLE from = ptys->get_handle ();
HANDLE input_available_event = ptys->get_input_available_event ();
if (ttyp->getpgid () == myself->pgid
+   && GetStdHandle (STD_INPUT_HANDLE) == ptys->get_handle ()
&& ttyp->pcon_input_state_eq (tty::to_nat))
  {
WaitForSingleObject (ptys->input_mutex, INFINITE);
@@ -1035,6 +1038,7 @@ fhandler_pty_slave::set_switch_to_pcon (void)
   bool pcon_enabled = setup_pseudoconsole (nopcon);
   ReleaseMutex (pcon_mutex);
   if (!pcon_enabled && get_ttyp ()->getpgid () == myself->pgid
+ && GetStdHandle (STD_INPUT_HANDLE) == get_handle ()
  && get_ttyp ()->pcon_input_state_eq (tty::to_cyg))
{
  WaitForSingleObject (input_mutex, INFINITE);
@@ -1062,6 +1066,7 @@ fhandler_pty_slave::reset_switch_to_pcon (void)
  if (isHybrid)
{
  if (get_ttyp ()->getpgid () == myself->pgid
+ && GetStdHandle (STD_INPUT_HANDLE) == get_handle ()
  && get_ttyp ()->pcon_input_state_eq (tty::to_nat))
{
  WaitForSingleObject (input_mutex, INFINITE);
@@ -1204,7 +1209,8 @@ fhandler_pty_slave::mask_switch_to_pcon_in (bool mask, 
bool xfer)
   /* In GDB, transfer input based on setpgid() does not work because
  GDB may not set terminal process group properly. Therefore,
  transfer input here if isHybrid is set. */
-  if (isHybrid && !!masked != mask && xfer)
+  if (isHybrid && !!masked != mask && xfer
+  && GetStdHandle (STD_INPUT_HANDLE) == get_handle ())
 {
   if (mask && get_ttyp ()->pcon_input_state_eq (tty::to_nat))
{
diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc
index 9d70cb2b7..7a585392a 100644
--- a/winsup/cygwin/spawn.cc
+++ b/winsup/cygwin/spawn.cc
@@ -665,6 +665,7 @@ child_info_spawn::worker (const char *prog_arg, const char 
*const *argv,
   HANDLE ptys_pcon_mutex = NULL;
   HANDLE ptys_input_mutex = NULL;
   tty *ptys_ttyp = NULL;
+  bool stdin_is_ptys = false;
   if (!iscygwin () && ptys_primary && is_console_app (runpath))
{
  bool nopcon = mode != _P_OVERLAY && mode != _P_WAIT;
@@ -675,6 +676,9 @@ child_info_spawn::worker (const char *prog_arg, const char 
*const *argv,
  if (ptys_primary->setup_pseudoconsole (nopcon))
enable_pcon = true;
  ReleaseMutex (ptys_primary->pcon_mutex);
+ HANDLE h_stdin = handle ((in__stdin < 0 ? 0 : in__stdin), false);
+ if (h_stdin == ptys_primary->get_handle ())
+   stdin_is_ptys = true;
  ptys_from_master = ptys_primary->get_handle ();
  DuplicateHandle (GetCurrentProcess (), ptys_from_master,
   GetCurrentProcess (), &ptys_from_master,
@@ -691,6 +695,7 @@ child_info_spawn::worker (const char *prog_arg, const char 
*const *argv,
   GetCurrentProcess (), &ptys_input_mutex,
   0, 0, DUPLICATE_SAME_ACCESS);
  if (!enable_pcon && ptys_ttyp->getpgid () == myself->pgid
+ && stdin_is_ptys
  && ptys_ttyp->pcon_input_state_eq (tty::to_cyg))
{
  WaitForSingleObject (ptys_input_mutex, INFINITE);
@@ -983,7 +988,7 @@ child_info_spawn::worker (const char *prog_arg, const char 
*const *argv,
  if (ptys_ttyp)
{
  ptys_ttyp->wait_pcon_fwd ();
- if (ptys_ttyp->getpgid () == myself->pgid
+ if (ptys_ttyp->getpgid () == myself->pgid && stdin_is_ptys
  && ptys_ttyp->pcon_input_state_eq (tty::to_nat))
{
  WaitForSingleObject (ptys_input_mutex, INFINITE);
@@ -1020,7 +1025,7 @@ child_info_spawn::worker (const char *prog_arg, const 
char *const *argv,
  if (ptys_ttyp)
{
  ptys_ttyp->wait_pcon_fwd ();
- if (ptys_ttyp->getpgid () == myself->pgid
+ if (ptys_ttyp->getpgid () == myself->pgid && stdin_is_ptys
  

Re: [PATCH] Cygwin: pty: Transfer input for native app only if the stdin is pcon.

2021-03-08 Thread Takashi Yano via Cygwin-patches
On Mon, 8 Mar 2021 21:52:37 +0100
Corinna Vinschen wrote:
> On Mar  9 00:48, Takashi Yano via Cygwin-patches wrote:
> > On Mon, 8 Mar 2021 16:32:16 +0100
> > Corinna Vinschen wrote:
> > > Hi Takashi,
> > > 
> > > On Mar  8 23:55, Takashi Yano via Cygwin-patches wrote:
> > > > - Currently, transfer input is triggered even if the stdin of native
> > > >   app is not a pseudo console. With this patch it is triggered only
> > > >   if the stdin is a pseudo console.
> > > 
> > > do you have more patches in the loop?  I wonder if I should really start
> > > the test release cycle for 3.2.0 or if I should wait a bit...?
> > 
> > I'm sorry to submit patches one after another. However,
> > I think this should be the last one. Please go ahead.
> 
> Great, thanks!

I am very sorry but I would like to submit just one more patch.
I apologize to overturn the previous statement...

-- 
Takashi Yano 


Re: [PATCH] Cygwin: pty: Transfer input for native app only if the stdin is pcon.

2021-03-08 Thread Takashi Yano via Cygwin-patches
On Mon, 8 Mar 2021 16:32:16 +0100
Corinna Vinschen wrote:
> Hi Takashi,
> 
> On Mar  8 23:55, Takashi Yano via Cygwin-patches wrote:
> > - Currently, transfer input is triggered even if the stdin of native
> >   app is not a pseudo console. With this patch it is triggered only
> >   if the stdin is a pseudo console.
> 
> do you have more patches in the loop?  I wonder if I should really start
> the test release cycle for 3.2.0 or if I should wait a bit...?

I'm sorry to submit patches one after another. However,
I think this should be the last one. Please go ahead.

-- 
Takashi Yano 


[PATCH] Cygwin: pty: Transfer input for native app only if the stdin is pcon.

2021-03-08 Thread Takashi Yano via Cygwin-patches
- Currently, transfer input is triggered even if the stdin of native
  app is not a pseudo console. With this patch it is triggered only
  if the stdin is a pseudo console.
---
 winsup/cygwin/fhandler_tty.cc | 18 ++
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 3bfc8c0c8..47d59e8c5 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -3084,14 +3084,16 @@ fhandler_pty_slave::setup_pseudoconsole (bool nopcon)
   if (get_ttyp ()->pcon_pid && get_ttyp ()->pcon_pid != myself->pid
   && !!pinfo (get_ttyp ()->pcon_pid) && get_ttyp ()->pcon_activated)
 {
-  /* Send CSI6n just for requesting transfer input. */
-  DWORD n;
-  WaitForSingleObject (input_mutex, INFINITE);
-  get_ttyp ()->req_xfer_input = true;
-  get_ttyp ()->pcon_start = true;
-  get_ttyp ()->pcon_start_pid = myself->pid;
-  WriteFile (get_output_handle_cyg (), "\033[6n", 4, &n, NULL);
-  ReleaseMutex (input_mutex);
+  if (GetStdHandle (STD_INPUT_HANDLE) == get_handle ())
+   { /* Send CSI6n just for requesting transfer input. */
+ DWORD n;
+ WaitForSingleObject (input_mutex, INFINITE);
+ get_ttyp ()->req_xfer_input = true;
+ get_ttyp ()->pcon_start = true;
+ get_ttyp ()->pcon_start_pid = myself->pid;
+ WriteFile (get_output_handle_cyg (), "\033[6n", 4, &n, NULL);
+ ReleaseMutex (input_mutex);
+   }
   /* Attach to the pseudo console which already exits. */
   pinfo p (get_ttyp ()->pcon_pid);
   HANDLE pcon_owner =
-- 
2.30.1



[PATCH] Cygwin: pty: Attach to stub process when non-cygwin app inherits pcon.

2021-03-08 Thread Takashi Yano via Cygwin-patches
- If two non-cygwin apps are started simultaneously, attaching to
  pseudo console sometimes fails. This is because the second app
  trys to attach to the process not started yet. This patch avoids
  the issue by attaching to the stub process rather than the other
  non-cygwin app.
---
 winsup/cygwin/fhandler_tty.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 4358bceec..3bfc8c0c8 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -3104,7 +3104,7 @@ fhandler_pty_slave::setup_pseudoconsole (bool nopcon)
   0, TRUE, DUPLICATE_SAME_ACCESS);
   CloseHandle (pcon_owner);
   FreeConsole ();
-  AttachConsole (p->dwProcessId);
+  AttachConsole (p->exec_dwProcessId);
   goto skip_create;
 }
 
-- 
2.30.1



[PATCH] Cygwin: console, pty: Stop ignoring Ctrl-C by IGNBRK.

2021-03-06 Thread Takashi Yano via Cygwin-patches
- Perhaps current code misunderstand meaning of the IGNBRK. As far
  as I investigated, IGNBRK is concerned with break signal in serial
  port but there is no evidence that it has effect to ignore Ctrl-C.
  This patch stops ignoring Ctrl-C by IGNBRK for non-cygwin apps.
---
 winsup/cygwin/fhandler_console.cc | 2 +-
 winsup/cygwin/fhandler_tty.cc | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/winsup/cygwin/fhandler_console.cc 
b/winsup/cygwin/fhandler_console.cc
index 96a8729e8..0b33a1370 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -484,7 +484,7 @@ fhandler_console::set_input_mode (tty::cons_mode m, const 
termios *t,
/* This is illegal, so turn off the echo here, and fake it
   when we read the characters */
flags &= ~ENABLE_ECHO_INPUT;
-  if ((t->c_lflag & ISIG) && !(t->c_iflag & IGNBRK))
+  if (t->c_lflag & ISIG)
flags |= ENABLE_PROCESSED_INPUT;
   break;
 }
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 244147a80..4358bceec 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -2165,8 +2165,8 @@ fhandler_pty_master::write (const void *ptr, size_t len)
}
 
   WaitForSingleObject (input_mutex, INFINITE);
-  if ((ti.c_lflag & ISIG) && !(ti.c_iflag & IGNBRK)
- && !(ti.c_lflag & NOFLSH) && memchr (buf, '\003', nlen))
+  if ((ti.c_lflag & ISIG) && !(ti.c_lflag & NOFLSH)
+ && memchr (buf, '\003', nlen))
get_ttyp ()->discard_input = true;
   DWORD n;
   WriteFile (to_slave, buf, nlen, &n, NULL);
@@ -3307,7 +3307,7 @@ skip_create:
/* This is illegal, so turn off the echo here, and fake it
   when we read the characters */
mode &= ~ENABLE_ECHO_INPUT;
-  if ((t.c_lflag & ISIG) && !(t.c_iflag & IGNBRK))
+  if (t.c_lflag & ISIG)
mode |= ENABLE_PROCESSED_INPUT;
   SetConsoleMode (hpConIn, mode);
   /* Set output mode */
-- 
2.30.1



[PATCH] Cygwin: pty: Discard input already accepted on interrupt.

2021-03-05 Thread Takashi Yano via Cygwin-patches
- Currently, input already accepted is not discarded on interrupt
  by VINTR, VQUIT and VSUSP keys. This patch fixes the issue.
---
 winsup/cygwin/fhandler.h  |  2 ++
 winsup/cygwin/fhandler_termios.cc |  5 -
 winsup/cygwin/fhandler_tty.cc | 23 +++
 winsup/cygwin/tty.cc  |  1 +
 winsup/cygwin/tty.h   |  1 +
 5 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 9b85d1ee9..4da35b7f5 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -1921,6 +1921,7 @@ class fhandler_termios: public fhandler_base
   int eat_readahead (int n);
   virtual void acquire_input_mutex_if_necessary (DWORD ms) {};
   virtual void release_input_mutex_if_necessary (void) {};
+  virtual void discard_input () {};
 
  public:
   tty_min*& tc () {return _tc;}
@@ -2451,6 +2452,7 @@ public:
   void fixup_after_exec ();
   int tcgetpgrp ();
   void flush_to_slave ();
+  void discard_input ();
 
   fhandler_pty_master (void *) {}
 
diff --git a/winsup/cygwin/fhandler_termios.cc 
b/winsup/cygwin/fhandler_termios.cc
index ae35fe894..b487acab3 100644
--- a/winsup/cygwin/fhandler_termios.cc
+++ b/winsup/cygwin/fhandler_termios.cc
@@ -333,7 +333,10 @@ fhandler_termios::line_edit (const char *rptr, size_t 
nread, termios& ti,
 
  termios_printf ("got interrupt %d, sending signal %d", c, sig);
  if (!(ti.c_lflag & NOFLSH))
-   eat_readahead (-1);
+   {
+ eat_readahead (-1);
+ discard_input ();
+   }
  release_input_mutex_if_necessary ();
  tc ()->kill_pgrp (sig);
  acquire_input_mutex_if_necessary (INFINITE);
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 930501d01..244147a80 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -391,6 +391,21 @@ fhandler_pty_master::flush_to_slave ()
 accept_input ();
 }
 
+void
+fhandler_pty_master::discard_input ()
+{
+  DWORD bytes_in_pipe;
+  char buf[1024];
+  DWORD n;
+
+  WaitForSingleObject (input_mutex, INFINITE);
+  while (::bytes_available (bytes_in_pipe, from_master_cyg) && bytes_in_pipe)
+ReadFile (from_master_cyg, buf, sizeof(buf), &n, NULL);
+  ResetEvent (input_available_event);
+  get_ttyp ()->discard_input = true;
+  ReleaseMutex (input_mutex);
+}
+
 DWORD
 fhandler_pty_common::__acquire_output_mutex (const char *fn, int ln,
 DWORD ms)
@@ -2150,6 +2165,9 @@ fhandler_pty_master::write (const void *ptr, size_t len)
}
 
   WaitForSingleObject (input_mutex, INFINITE);
+  if ((ti.c_lflag & ISIG) && !(ti.c_iflag & IGNBRK)
+ && !(ti.c_lflag & NOFLSH) && memchr (buf, '\003', nlen))
+   get_ttyp ()->discard_input = true;
   DWORD n;
   WriteFile (to_slave, buf, nlen, &n, NULL);
   ReleaseMutex (input_mutex);
@@ -3709,6 +3727,8 @@ fhandler_pty_slave::transfer_input (tty::xfer_dir dir, 
HANDLE from, tty *ttyp,
   while (PeekConsoleInputA (from, r, INREC_SIZE, &n) && n)
{
  ReadConsoleInputA (from, r, n, &n);
+ if (ttyp->discard_input)
+   continue;
  int len = 0;
  char *ptr = buf;
  for (DWORD i = 0; i < n; i++)
@@ -3773,6 +3793,8 @@ fhandler_pty_slave::transfer_input (tty::xfer_dir dir, 
HANDLE from, tty *ttyp,
{
  DWORD n = MIN (bytes_in_pipe, NT_MAX_PATH);
  ReadFile (from, buf, n, &n, NULL);
+ if (ttyp->discard_input)
+   continue;
  char *ptr = buf;
  if (dir == tty::to_nat)
{
@@ -3803,4 +3825,5 @@ fhandler_pty_slave::transfer_input (tty::xfer_dir dir, 
HANDLE from, tty *ttyp,
   else if (transfered)
 SetEvent (input_available_event);
   ttyp->pcon_input_state = dir;
+  ttyp->discard_input = false;
 }
diff --git a/winsup/cygwin/tty.cc b/winsup/cygwin/tty.cc
index eaab573e0..3c016315c 100644
--- a/winsup/cygwin/tty.cc
+++ b/winsup/cygwin/tty.cc
@@ -253,6 +253,7 @@ tty::init ()
   pcon_input_state = to_cyg;
   last_sig = 0;
   mask_flusho = false;
+  discard_input = false;
 }
 
 HANDLE
diff --git a/winsup/cygwin/tty.h b/winsup/cygwin/tty.h
index b74120416..f041250a3 100644
--- a/winsup/cygwin/tty.h
+++ b/winsup/cygwin/tty.h
@@ -131,6 +131,7 @@ private:
   bool req_xfer_input;
   xfer_dir pcon_input_state;
   bool mask_flusho;
+  bool discard_input;
 
 public:
   HANDLE from_master () const { return _from_master; }
-- 
2.30.1



[PATCH v2] Cygwin: console: Fix restoring console mode failure.

2021-03-04 Thread Takashi Yano via Cygwin-patches
- Restoring console mode fails in the following scenario.
   1) Start cygwin shell in command prompt.
   2) Run 'exec chcp.com'.
  This patch fixes the issue.
---
 winsup/cygwin/fhandler.h |  1 +
 winsup/cygwin/spawn.cc   | 14 ++
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index ad90cf33d..9b85d1ee9 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -2251,6 +2251,7 @@ private:
   const handle_set_t *p);
 
   static void cons_master_thread (handle_set_t *p, tty *ttyp);
+  pid_t get_owner (void) { return shared_console_info->con.owner; }
 
   friend tty_min * tty_list::get_cttyp ();
 };
diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc
index 323630fcb..490675859 100644
--- a/winsup/cygwin/spawn.cc
+++ b/winsup/cygwin/spawn.cc
@@ -608,6 +608,7 @@ child_info_spawn::worker (const char *prog_arg, const char 
*const *argv,
   fhandler_pty_slave *ptys_primary = NULL;
   fhandler_console *cons_native = NULL;
   termios *cons_ti = NULL;
+  pid_t cons_owner = 0;
   for (int i = 0; i < 3; i ++)
{
  const int chk_order[] = {1, 0, 2};
@@ -628,6 +629,7 @@ child_info_spawn::worker (const char *prog_arg, const char 
*const *argv,
{
  cons_native = cons;
  cons_ti = &((tty *)cons->tc ())->ti;
+ cons_owner = cons->get_owner ();
}
  if (fd == 0)
fhandler_console::set_input_mode (tty::native,
@@ -1000,9 +1002,11 @@ child_info_spawn::worker (const char *prog_arg, const 
char *const *argv,
}
  if (cons_native)
{
- fhandler_console::set_output_mode (tty::cygwin, cons_ti,
+ tty::cons_mode conmode =
+   cons_owner == myself->pid ? tty::restore : tty::cygwin;
+ fhandler_console::set_output_mode (conmode, cons_ti,
 &cons_handle_set);
- fhandler_console::set_input_mode (tty::cygwin, cons_ti,
+ fhandler_console::set_input_mode (conmode, cons_ti,
&cons_handle_set);
  fhandler_console::close_handle_set (&cons_handle_set);
}
@@ -1035,9 +1039,11 @@ child_info_spawn::worker (const char *prog_arg, const 
char *const *argv,
}
  if (cons_native)
{
- fhandler_console::set_output_mode (tty::cygwin, cons_ti,
+ tty::cons_mode conmode =
+   cons_owner == myself->pid ? tty::restore : tty::cygwin;
+ fhandler_console::set_output_mode (conmode, cons_ti,
 &cons_handle_set);
- fhandler_console::set_input_mode (tty::cygwin, cons_ti,
+ fhandler_console::set_input_mode (conmode, cons_ti,
&cons_handle_set);
  fhandler_console::close_handle_set (&cons_handle_set);
}
-- 
2.30.1



Re: [PATCH] Cygwin: console: Fix restoring console mode failure.

2021-03-04 Thread Takashi Yano via Cygwin-patches
On Thu,  4 Mar 2021 17:57:34 +0900
Takashi Yano wrote:
> - Restoring console mode fails in the following scenario.
>1) Start cygwin shell in command prompt.
>2) Run 'exec chcp.com'.
>   This patch fixes the issue.
> ---
>  winsup/cygwin/fhandler.h |  1 +
>  winsup/cygwin/spawn.cc   | 14 ++
>  2 files changed, 11 insertions(+), 4 deletions(-)
> 
> diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
> index ad90cf33d..9b85d1ee9 100644
> --- a/winsup/cygwin/fhandler.h
> +++ b/winsup/cygwin/fhandler.h
> @@ -2251,6 +2251,7 @@ private:
>  const handle_set_t *p);
>  
>static void cons_master_thread (handle_set_t *p, tty *ttyp);
> +  pid_t get_owner (void) { return shared_console_info->con.owner; }
>  
>friend tty_min * tty_list::get_cttyp ();
>  };
> diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc
> index 323630fcb..490675859 100644
> --- a/winsup/cygwin/spawn.cc
> +++ b/winsup/cygwin/spawn.cc
> @@ -608,6 +608,7 @@ child_info_spawn::worker (const char *prog_arg, const 
> char *const *argv,
>fhandler_pty_slave *ptys_primary = NULL;
>fhandler_console *cons_native = NULL;
>termios *cons_ti = NULL;
> +  pid_t cons_owner = 0;
>for (int i = 0; i < 3; i ++)
>   {
> const int chk_order[] = {1, 0, 2};
> @@ -628,6 +629,7 @@ child_info_spawn::worker (const char *prog_arg, const 
> char *const *argv,
>   {
> cons_native = cons;
> cons_ti = &((tty *)cons->tc ())->ti;
> +   cons_owner = cons->get_owner ();
>   }
> if (fd == 0)
>   fhandler_console::set_input_mode (tty::native,
> @@ -1000,9 +1002,11 @@ child_info_spawn::worker (const char *prog_arg, const 
> char *const *argv,
>   }
> if (cons_native)
>   {
> -   fhandler_console::set_output_mode (tty::cygwin, cons_ti,
> +   tty::cons_mode mode =
> + cons_owner == myself->pid ? tty::restore : tty::cygwin;
> +   fhandler_console::set_output_mode (mode, cons_ti,
>&cons_handle_set);
> -   fhandler_console::set_input_mode (tty::cygwin, cons_ti,
> +   fhandler_console::set_input_mode (mode, cons_ti,
>   &cons_handle_set);
> fhandler_console::close_handle_set (&cons_handle_set);
>   }
> @@ -1035,9 +1039,11 @@ child_info_spawn::worker (const char *prog_arg, const 
> char *const *argv,
>   }
> if (cons_native)
>   {
> -   fhandler_console::set_output_mode (tty::cygwin, cons_ti,
> +   tty::cons_mode mode =
> + cons_owner == myself->pid ? tty::restore : tty::cygwin;
> +   fhandler_console::set_output_mode (mode, cons_ti,
>&cons_handle_set);
> -   fhandler_console::set_input_mode (tty::cygwin, cons_ti,
> +   fhandler_console::set_input_mode (mode, cons_ti,
>   &cons_handle_set);
> fhandler_console::close_handle_set (&cons_handle_set);
>   }

The variable name 'mode' is already used therefore this code
overrides it. I will submit v2 patch since it is not so good.

-- 
Takashi Yano 


[PATCH] Cygwin: console: Fix restoring console mode failure.

2021-03-04 Thread Takashi Yano via Cygwin-patches
- Restoring console mode fails in the following scenario.
   1) Start cygwin shell in command prompt.
   2) Run 'exec chcp.com'.
  This patch fixes the issue.
---
 winsup/cygwin/fhandler.h |  1 +
 winsup/cygwin/spawn.cc   | 14 ++
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index ad90cf33d..9b85d1ee9 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -2251,6 +2251,7 @@ private:
   const handle_set_t *p);
 
   static void cons_master_thread (handle_set_t *p, tty *ttyp);
+  pid_t get_owner (void) { return shared_console_info->con.owner; }
 
   friend tty_min * tty_list::get_cttyp ();
 };
diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc
index 323630fcb..490675859 100644
--- a/winsup/cygwin/spawn.cc
+++ b/winsup/cygwin/spawn.cc
@@ -608,6 +608,7 @@ child_info_spawn::worker (const char *prog_arg, const char 
*const *argv,
   fhandler_pty_slave *ptys_primary = NULL;
   fhandler_console *cons_native = NULL;
   termios *cons_ti = NULL;
+  pid_t cons_owner = 0;
   for (int i = 0; i < 3; i ++)
{
  const int chk_order[] = {1, 0, 2};
@@ -628,6 +629,7 @@ child_info_spawn::worker (const char *prog_arg, const char 
*const *argv,
{
  cons_native = cons;
  cons_ti = &((tty *)cons->tc ())->ti;
+ cons_owner = cons->get_owner ();
}
  if (fd == 0)
fhandler_console::set_input_mode (tty::native,
@@ -1000,9 +1002,11 @@ child_info_spawn::worker (const char *prog_arg, const 
char *const *argv,
}
  if (cons_native)
{
- fhandler_console::set_output_mode (tty::cygwin, cons_ti,
+ tty::cons_mode mode =
+   cons_owner == myself->pid ? tty::restore : tty::cygwin;
+ fhandler_console::set_output_mode (mode, cons_ti,
 &cons_handle_set);
- fhandler_console::set_input_mode (tty::cygwin, cons_ti,
+ fhandler_console::set_input_mode (mode, cons_ti,
&cons_handle_set);
  fhandler_console::close_handle_set (&cons_handle_set);
}
@@ -1035,9 +1039,11 @@ child_info_spawn::worker (const char *prog_arg, const 
char *const *argv,
}
  if (cons_native)
{
- fhandler_console::set_output_mode (tty::cygwin, cons_ti,
+ tty::cons_mode mode =
+   cons_owner == myself->pid ? tty::restore : tty::cygwin;
+ fhandler_console::set_output_mode (mode, cons_ti,
 &cons_handle_set);
- fhandler_console::set_input_mode (tty::cygwin, cons_ti,
+ fhandler_console::set_input_mode (mode, cons_ti,
&cons_handle_set);
  fhandler_console::close_handle_set (&cons_handle_set);
}
-- 
2.30.1



[PATCH] Cygwin: pty: Fix a race issue in startup of pseudo console.

2021-03-04 Thread Takashi Yano via Cygwin-patches
- If two non-cygwin apps are started simultaneously and this is the
  first execution of non-cygwin apps in the pty, these occasionally
  hang up. The cause is the race issue between term_has_pcon_cap(),
  reset_switch_to_pcon() and setup_pseudoconsole(). This patch fixes
  the issue.
---
 winsup/cygwin/fhandler_tty.cc | 16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 3fcaa8277..930501d01 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -1118,15 +1118,20 @@ fhandler_pty_slave::reset_switch_to_pcon (void)
}
}
 }
-  if (get_ttyp ()->pcon_pid && get_ttyp ()->pcon_pid != myself->pid
-  && !!pinfo (get_ttyp ()->pcon_pid))
-/* There is a process which is grabbing pseudo console. */
-return;
   if (isHybrid)
 return;
+  WaitForSingleObject (pcon_mutex, INFINITE);
+  if (get_ttyp ()->pcon_pid && get_ttyp ()->pcon_pid != myself->pid
+  && !!pinfo (get_ttyp ()->pcon_pid))
+{
+  /* There is a process which is grabbing pseudo console. */
+  ReleaseMutex (pcon_mutex);
+  return;
+}
   get_ttyp ()->pcon_pid = 0;
   get_ttyp ()->switch_to_pcon_in = false;
   get_ttyp ()->pcon_activated = false;
+  ReleaseMutex (pcon_mutex);
 }
 
 ssize_t __stdcall
@@ -3538,6 +3543,7 @@ fhandler_pty_slave::term_has_pcon_cap (const WCHAR *env)
 goto maybe_dumb;
 
   /* Check if terminal has CSI6n */
+  WaitForSingleObject (pcon_mutex, INFINITE);
   WaitForSingleObject (input_mutex, INFINITE);
   /* Set pcon_activated and pcon_start so that the response
  will sent to io_handle rather than io_handle_cyg. */
@@ -3573,6 +3579,7 @@ fhandler_pty_slave::term_has_pcon_cap (const WCHAR *env)
   while (len);
   get_ttyp ()->pcon_activated = false;
   get_ttyp ()->pcon_pid = 0;
+  ReleaseMutex (pcon_mutex);
   if (len == 0)
 goto not_has_csi6n;
 
@@ -3588,6 +3595,7 @@ not_has_csi6n:
   get_ttyp ()->pcon_start = false;
   get_ttyp ()->pcon_activated = false;
   ReleaseMutex (input_mutex);
+  ReleaseMutex (pcon_mutex);
 maybe_dumb:
   get_ttyp ()->pcon_cap_checked = true;
   return false;
-- 
2.30.1



Re: [PATCH] Cygwin: pty: Fix segfault caused when tcflush() is called.

2021-02-23 Thread Takashi Yano via Cygwin-patches
On Tue, 23 Feb 2021 22:13:52 +0900
Takashi Yano wrote:
> Hi Thomas,
> 
> On Tue, 23 Feb 2021 12:24:09 +0100
> Thomas Wolff wrote:
> > I've downloaded yesterday's snapshot (2021-02-22) for some testing.
> > If I compile mintty (which passes without problem) and try to run it, it 
> > just exits silently (no window popped up).
> > After reverting to 3.1.7, it runs just fine (even the one compiled with 
> > the snapshot).
> 
> Thanks for testing. However, I cannot reproduce your problem.
> I downloaded mintty-3.4.6-1-src.tar.xz and extract it.
> Then run
> cygport mintty-3.4.6-1.cygport prep
> cygport mintty-3.4.6-1.cygport compile
> 
> The binary in build/bin directory works with cygwin snapshot
> 2021-02-22. I have tried both 32bit and 64bit build, and both
> work without problem.
> 
> Could you please provide some more information?

Difference of compiler version?
I am using gcc-g++ 10.2.0-1.

-- 
Takashi Yano 


Re: [PATCH] Cygwin: pty: Fix segfault caused when tcflush() is called.

2021-02-23 Thread Takashi Yano via Cygwin-patches
Hi Thomas,

On Tue, 23 Feb 2021 12:24:09 +0100
Thomas Wolff wrote:
> I've downloaded yesterday's snapshot (2021-02-22) for some testing.
> If I compile mintty (which passes without problem) and try to run it, it 
> just exits silently (no window popped up).
> After reverting to 3.1.7, it runs just fine (even the one compiled with 
> the snapshot).

Thanks for testing. However, I cannot reproduce your problem.
I downloaded mintty-3.4.6-1-src.tar.xz and extract it.
Then run
cygport mintty-3.4.6-1.cygport prep
cygport mintty-3.4.6-1.cygport compile

The binary in build/bin directory works with cygwin snapshot
2021-02-22. I have tried both 32bit and 64bit build, and both
work without problem.

Could you please provide some more information?

-- 
Takashi Yano 


[PATCH] Cygwin: console: Prevent NULL pointer access in close().

2021-02-22 Thread Takashi Yano via Cygwin-patches
- There seems to be a case that shared_console_info is not set yet
  when close() is called. This patch adds guard for such case.
---
 winsup/cygwin/fhandler_console.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/winsup/cygwin/fhandler_console.cc 
b/winsup/cygwin/fhandler_console.cc
index 6ded9eabf..96a8729e8 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -1393,7 +1393,7 @@ fhandler_console::close ()
 
   release_output_mutex ();
 
-  if (con.owner == myself->pid)
+  if (shared_console_info && con.owner == myself->pid)
 {
   char name[MAX_PATH];
   shared_name (name, CONS_THREAD_SYNC, get_minor ());
-- 
2.30.0



Re: [PATCH] Cygwin: pty: Fix segfault caused when tcflush() is called.

2021-02-22 Thread Takashi Yano via Cygwin-patches
On Mon, 22 Feb 2021 20:41:00 +0900
Takashi Yano wrote:
> On Mon, 22 Feb 2021 10:51:19 +0100
> Corinna Vinschen wrote:
> > So, what do you think is the state of the console code, Takashi?
> > Shall we start a release cycle next week?
> 
> I think all the fixes and improvements that come to mind at this
> point have been completed. As for releasing, I believe I've done
> enough testing, but honestly I'm not without anxiety because total
> amount of changes for pty and console code is relatively large
> since the beginning of this year.

Sure enough, I found a problem in the console code...

I will submit a patch for that.

-- 
Takashi Yano 


Re: [PATCH] Cygwin: pty: Fix segfault caused when tcflush() is called.

2021-02-22 Thread Takashi Yano via Cygwin-patches
On Mon, 22 Feb 2021 10:51:19 +0100
Corinna Vinschen wrote:
> So, what do you think is the state of the console code, Takashi?
> Shall we start a release cycle next week?

I think all the fixes and improvements that come to mind at this
point have been completed. As for releasing, I believe I've done
enough testing, but honestly I'm not without anxiety because total
amount of changes for pty and console code is relatively large
since the beginning of this year.

On the other hand, I also want people to use new features as soon
as possible.

I would like to leave the final decision to you.

-- 
Takashi Yano 


[PATCH] Cygwin: pty: Fix segfault caused when tcflush() is called.

2021-02-20 Thread Takashi Yano via Cygwin-patches
- After commit 253352e796ff9ec9a447e5375f5bc3e2b92b5293, mc (midnight
  commander) crashes with segfault if the shell is bash. This is due
  to NULL pointer access in read(). This patch fixes the issue.
  Addresses::
https://cygwin.com/pipermail/cygwin/2021-February/247870.html
---
 winsup/cygwin/fhandler_tty.cc | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index d30041af1..3fcaa8277 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -1474,8 +1474,11 @@ wait_retry:
 out:
   termios_printf ("%d = read(%p, %lu)", totalread, ptr, len);
   len = (size_t) totalread;
-  bool saw_eol = totalread > 0 && strchr ("\r\n", ptr0[totalread -1]);
-  mask_switch_to_pcon_in (false, saw_eol);
+  if (ptr0)
+{ /* Not tcflush() */
+  bool saw_eol = totalread > 0 && strchr ("\r\n", ptr0[totalread -1]);
+  mask_switch_to_pcon_in (false, saw_eol);
+}
 }
 
 int
-- 
2.30.0



[PATCH 1/2] Cygwin: pty: Make FLUSHO and Ctrl-O work.

2021-02-19 Thread Takashi Yano via Cygwin-patches
- Previously, FLUSHO feature was implemented incompletely. With
  this patch, FLUSHO and Ctrl-O (VDISCARD) get working.
---
 winsup/cygwin/fhandler.h  |  1 +
 winsup/cygwin/fhandler_tty.cc | 17 +++--
 winsup/cygwin/select.cc   |  5 +
 winsup/cygwin/tty.cc  |  1 +
 winsup/cygwin/tty.h   |  1 +
 5 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index faa910692..5d095d384 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -2467,6 +2467,7 @@ public:
   bool to_be_read_from_pcon (void);
   void get_master_thread_param (master_thread_param_t *p);
   void get_master_fwd_thread_param (master_fwd_thread_param_t *p);
+  void set_mask_flusho (bool m) { get_ttyp ()->mask_flusho = m; }
 };
 
 class fhandler_dev_null: public fhandler_base
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index e4c35ea41..d30041af1 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -612,8 +612,8 @@ fhandler_pty_master::process_slave_output (char *buf, 
size_t len, int pktmode_on
  rc = -1;
  goto out;
}
- /* DISCARD (FLUSHO) and tcflush can finish here. */
- if ((get_ttyp ()->ti.c_lflag & FLUSHO || !buf))
+ /* tclush can finish here. */
+ if (!buf)
goto out;
 
  if (is_nonblocking ())
@@ -671,8 +671,9 @@ fhandler_pty_master::process_slave_output (char *buf, 
size_t len, int pktmode_on
 
   termios_printf ("bytes read %u", n);
 
-  if (get_ttyp ()->ti.c_lflag & FLUSHO || !buf)
-   continue;
+  if (!buf || ((get_ttyp ()->ti.c_lflag & FLUSHO)
+  && !get_ttyp ()->mask_flusho))
+   continue; /* Discard read data */
 
   memcpy (optr, outbuf, n);
   optr += n;
@@ -691,6 +692,8 @@ fhandler_pty_master::process_slave_output (char *buf, 
size_t len, int pktmode_on
 }
 
 out:
+  if (buf)
+set_mask_flusho (false);
   termios_printf ("returning %d", rc);
   return rc;
 }
@@ -2036,7 +2039,7 @@ fhandler_pty_master::write (const void *ptr, size_t len)
 {
   ssize_t ret;
   char *p = (char *) ptr;
-  termios ti = tc ()->ti;
+  termios &ti = tc ()->ti;
 
   bg_check_types bg = bg_check (SIGTTOU);
   if (bg <= bg_eof)
@@ -2193,7 +2196,7 @@ fhandler_pty_master::tcflush (int queue)
 
   if (queue == TCIFLUSH || queue == TCIOFLUSH)
 ret = process_slave_output (NULL, OUT_BUFFER_SIZE, 0);
-  else if (queue == TCIFLUSH || queue == TCIOFLUSH)
+  if (queue == TCOFLUSH || queue == TCIOFLUSH)
 {
   /* do nothing for now. */
 }
@@ -2929,6 +2932,8 @@ fhandler_pty_common::process_opost_output (HANDLE h, 
const void *ptr,
 {
   ssize_t towrite = len;
   BOOL res = TRUE;
+  if (ttyp->ti.c_lflag & FLUSHO)
+return res; /* Discard write data */
   while (towrite)
 {
   if (!is_echo)
diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc
index 085de6deb..c8f288c27 100644
--- a/winsup/cygwin/select.cc
+++ b/winsup/cygwin/select.cc
@@ -710,6 +710,11 @@ peek_pipe (select_record *s, bool from_select)
 }
 
 out:
+  if (fh->get_major () == DEV_PTYM_MAJOR)
+{
+  fhandler_pty_master *fhm = (fhandler_pty_master *) fh;
+  fhm->set_mask_flusho (s->read_ready);
+}
   h = fh->get_output_handle_cyg ();
   if (s->write_selected && dev != FH_PIPER)
 {
diff --git a/winsup/cygwin/tty.cc b/winsup/cygwin/tty.cc
index 7627cd6c7..eaab573e0 100644
--- a/winsup/cygwin/tty.cc
+++ b/winsup/cygwin/tty.cc
@@ -252,6 +252,7 @@ tty::init ()
   req_xfer_input = false;
   pcon_input_state = to_cyg;
   last_sig = 0;
+  mask_flusho = false;
 }
 
 HANDLE
diff --git a/winsup/cygwin/tty.h b/winsup/cygwin/tty.h
index 4ef1e04c9..b74120416 100644
--- a/winsup/cygwin/tty.h
+++ b/winsup/cygwin/tty.h
@@ -130,6 +130,7 @@ private:
   bool master_is_running_as_service;
   bool req_xfer_input;
   xfer_dir pcon_input_state;
+  bool mask_flusho;
 
 public:
   HANDLE from_master () const { return _from_master; }
-- 
2.30.0



[PATCH 2/2] Cygwin: console: Add support for FLUSHO and Ctrl-O.

2021-02-19 Thread Takashi Yano via Cygwin-patches
- With this patch, FLUSHO and Ctrl-O (VDISCARD) get working.
---
 winsup/cygwin/fhandler_console.cc | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/winsup/cygwin/fhandler_console.cc 
b/winsup/cygwin/fhandler_console.cc
index ca8eb6400..6ded9eabf 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -259,6 +259,7 @@ fhandler_console::cons_master_thread (handle_set_t *p, tty 
*ttyp)
{
  ttyp->kill_pgrp (sig);
  ttyp->output_stopped = false;
+ ti.c_lflag &= ~FLUSHO;
  /* Discard type ahead input */
  goto skip_writeback;
}
@@ -286,6 +287,13 @@ fhandler_console::cons_master_thread (handle_set_t *p, tty 
*ttyp)
   && c && i >= output_stopped_at)
goto restart_output;
}
+ if ((ti.c_lflag & ICANON) && (ti.c_lflag & IEXTEN)
+ && CCEQ (ti.c_cc[VDISCARD], c))
+   {
+ if (input_rec[i].Event.KeyEvent.bKeyDown)
+   ti.c_lflag ^= FLUSHO;
+ processed = true;
+   }
  break;
case WINDOW_BUFFER_SIZE_EVENT:
  SHORT y = con.dwWinSize.Y;
@@ -3052,6 +3060,9 @@ fhandler_console::write (const void *vsrc, size_t len)
   if (bg <= bg_eof)
 return (ssize_t) bg;
 
+  if (get_ttyp ()->ti.c_lflag & FLUSHO)
+return len; /* Discard write data */
+
   if (get_ttyp ()->output_stopped && is_nonblocking ())
 {
   set_errno (EAGAIN);
-- 
2.30.0



[PATCH 0/2] Cygwin: pty, console: Make FLUSHO and Ctrl-O work.

2021-02-19 Thread Takashi Yano via Cygwin-patches
- With these patches, FLUSHO and Ctrl-O (VDISCARD) get working.

Takashi Yano (2):
  Cygwin: pty: Make FLUSHO and Ctrl-O work.
  Cygwin: console: Add support for FLUSHO and Ctrl-O.

 winsup/cygwin/fhandler.h  |  1 +
 winsup/cygwin/fhandler_console.cc | 11 +++
 winsup/cygwin/fhandler_tty.cc | 17 +++--
 winsup/cygwin/select.cc   |  5 +
 winsup/cygwin/tty.cc  |  1 +
 winsup/cygwin/tty.h   |  1 +
 6 files changed, 30 insertions(+), 6 deletions(-)

-- 
2.30.0



[PATCH] Cygwin: pty: Make tty setting NOFLSH work.

2021-02-18 Thread Takashi Yano via Cygwin-patches
- With this patch, "stty noflsh" gets working in pty.
---
 winsup/cygwin/fhandler_termios.cc | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/winsup/cygwin/fhandler_termios.cc 
b/winsup/cygwin/fhandler_termios.cc
index e8daf946b..ae35fe894 100644
--- a/winsup/cygwin/fhandler_termios.cc
+++ b/winsup/cygwin/fhandler_termios.cc
@@ -332,7 +332,8 @@ fhandler_termios::line_edit (const char *rptr, size_t 
nread, termios& ti,
goto not_a_sig;
 
  termios_printf ("got interrupt %d, sending signal %d", c, sig);
- eat_readahead (-1);
+ if (!(ti.c_lflag & NOFLSH))
+   eat_readahead (-1);
  release_input_mutex_if_necessary ();
  tc ()->kill_pgrp (sig);
  acquire_input_mutex_if_necessary (INFINITE);
-- 
2.30.0



[PATCH] Cygwin: pty: Reflect tty settings to pseudo console mode.

2021-02-18 Thread Takashi Yano via Cygwin-patches
- With this patch, tty setting such as echo, icanon, isig and onlcr
  are reflected to pseudo console mode.
---
 winsup/cygwin/fhandler_tty.cc | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 5afede859..e4c35ea41 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -3261,6 +3261,33 @@ skip_create:
   if (get_ttyp ()->previous_output_code_page)
 SetConsoleOutputCP (get_ttyp ()->previous_output_code_page);
 
+  do
+{
+  termios &t = get_ttyp ()->ti;
+  DWORD mode;
+  /* Set input mode */
+  GetConsoleMode (hpConIn, &mode);
+  mode &= ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | 
ENABLE_PROCESSED_INPUT);
+  if (t.c_lflag & ECHO)
+   mode |= ENABLE_ECHO_INPUT;
+  if (t.c_lflag & ICANON)
+   mode |= ENABLE_LINE_INPUT;
+  if (mode & ENABLE_ECHO_INPUT && !(mode & ENABLE_LINE_INPUT))
+   /* This is illegal, so turn off the echo here, and fake it
+  when we read the characters */
+   mode &= ~ENABLE_ECHO_INPUT;
+  if ((t.c_lflag & ISIG) && !(t.c_iflag & IGNBRK))
+   mode |= ENABLE_PROCESSED_INPUT;
+  SetConsoleMode (hpConIn, mode);
+  /* Set output mode */
+  GetConsoleMode (hpConOut, &mode);
+  mode &= ~DISABLE_NEWLINE_AUTO_RETURN;
+  if (!(t.c_oflag & OPOST) || !(t.c_oflag & ONLCR))
+   mode |= DISABLE_NEWLINE_AUTO_RETURN;
+  SetConsoleMode (hpConOut, mode);
+}
+  while (false);
+
   return true;
 
 cleanup_pcon_in:
-- 
2.30.0



[PATCH] Cygwin: Add console fix regarding Ctrl-Z etc. to release notes.

2021-02-18 Thread Takashi Yano via Cygwin-patches
---
 winsup/cygwin/release/3.2.0 | 5 +
 1 file changed, 5 insertions(+)

diff --git a/winsup/cygwin/release/3.2.0 b/winsup/cygwin/release/3.2.0
index d02d16863..d69ed446c 100644
--- a/winsup/cygwin/release/3.2.0
+++ b/winsup/cygwin/release/3.2.0
@@ -9,6 +9,11 @@ What's new:
   thrd_detach, thrd_equal, thrd_exit, thrd_join, thrd_sleep, thrd_yield,
   tss_create, tss_delete, tss_get, tss_set.
 
+- In cygwin console, new thread which handles special keys/signals such
+  as Ctrl-Z (VSUSP), Ctrl-\ (VQUIT), Ctrl-S (VSTOP), Ctrl-Q (VSTART) and
+  SIGWINCH has been intrudocued. There have been a long standing issue
+  that these keys/signals are handled only when app calls read() or
+  select(). Now, these work even if app does not call read() or select().
 
 What changed:
 -
-- 
2.30.0



[PATCH 2/2] Cygwin: console: Fix handling of Ctrl-S in Win7.

2021-02-18 Thread Takashi Yano via Cygwin-patches
- If ENABLE_LINE_INPUT is set, Ctrl-S is handled by Windows if the
  OS is Windows 7. This conflicts with Ctrl-S handling in cygwin
  console code. This patch unsets ENABLE_LINE_INPUT flag in cygwin
  and set it when native app is executed.
---
 winsup/cygwin/fhandler.h  |   9 +-
 winsup/cygwin/fhandler_console.cc | 291 +++---
 winsup/cygwin/select.cc   |   4 +-
 winsup/cygwin/spawn.cc|  32 ++--
 winsup/cygwin/tty.h   |   8 +-
 5 files changed, 98 insertions(+), 246 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index e457e2785..faa910692 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -2135,11 +2135,9 @@ private:
   const unsigned char *write_normal (unsigned const char*, unsigned const char 
*);
   void char_command (char);
   bool set_raw_win32_keyboard_mode (bool);
-  int output_tcsetattr (int a, const struct termios *t);
 
 /* Input calls */
   int igncr_enabled ();
-  int input_tcsetattr (int a, const struct termios *t);
   void set_cursor_maybe ();
   static bool create_invisible_console (HWINSTA);
   static bool create_invisible_console_workaround (bool force);
@@ -2196,7 +2194,6 @@ private:
   void fixup_after_exec () {fixup_after_fork_exec (true);}
   void fixup_after_fork (HANDLE) {fixup_after_fork_exec (false);}
   void set_close_on_exec (bool val);
-  void set_input_state ();
   bool send_winch_maybe ();
   void setup ();
   bool set_unit ();
@@ -2245,8 +2242,10 @@ private:
   void get_duplicated_handle_set (handle_set_t *p);
   static void close_handle_set (handle_set_t *p);
 
-  static void request_xterm_mode_input (bool, const handle_set_t *p);
-  static void request_xterm_mode_output (bool, const handle_set_t *p);
+  static void set_input_mode (tty::cons_mode m, const termios *t,
+ const handle_set_t *p);
+  static void set_output_mode (tty::cons_mode m, const termios *t,
+  const handle_set_t *p);
 
   static void cons_master_thread (handle_set_t *p, tty *ttyp);
 
diff --git a/winsup/cygwin/fhandler_console.cc 
b/winsup/cygwin/fhandler_console.cc
index 4dee506dd..ca8eb6400 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -299,8 +299,8 @@ fhandler_console::cons_master_thread (handle_set_t *p, tty 
*ttyp)
{ /* Fix tab position */
  /* Re-setting ENABLE_VIRTUAL_TERMINAL_PROCESSING
 fixes the tab position. */
- request_xterm_mode_output (false, p);
- request_xterm_mode_output (true, p);
+ set_output_mode (tty::restore, &ti, p);
+ set_input_mode (tty::cygwin, &ti, p);
}
  ttyp->kill_pgrp (SIGWINCH);
}
@@ -446,64 +446,72 @@ fhandler_console::rabuflen ()
   return con_ra.rabuflen;
 }
 
-/* The function request_xterm_mode_{in,out}put() should be static so that
-   they can be called even after the fhandler_console instance is deleted. */
+/* The function set_{in,out}put_mode() should be static so that they
+   can be called even after the fhandler_console instance is deleted. */
 void
-fhandler_console::request_xterm_mode_input (bool req, const handle_set_t *p)
+fhandler_console::set_input_mode (tty::cons_mode m, const termios *t,
+ const handle_set_t *p)
 {
-  if (con_is_legacy)
-return;
+  DWORD flags = 0, oflags;
   WaitForSingleObject (p->input_mutex, INFINITE);
-  DWORD dwMode;
-  GetConsoleMode (p->input_handle, &dwMode);
-  if (req)
+  GetConsoleMode (p->input_handle, &oflags);
+  switch (m)
 {
-  if (!(dwMode & ENABLE_VIRTUAL_TERMINAL_INPUT))
-   {
- dwMode |= ENABLE_VIRTUAL_TERMINAL_INPUT;
- SetConsoleMode (p->input_handle, dwMode);
- if (con.cursor_key_app_mode) /* Restore DECCKM */
-   {
- request_xterm_mode_output (true, p);
- WriteConsoleW (p->output_handle, L"\033[?1h", 5, NULL, 0);
-   }
-   }
+case tty::restore:
+  flags = ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT;
+  break;
+case tty::cygwin:
+  flags = ENABLE_WINDOW_INPUT;
+  if (wincap.has_con_24bit_colors () && !con_is_legacy)
+   flags |= ENABLE_VIRTUAL_TERMINAL_INPUT;
+  else
+   flags |= ENABLE_MOUSE_INPUT;
+  break;
+case tty::native:
+  if (t->c_lflag & ECHO)
+   flags |= ENABLE_ECHO_INPUT;
+  if (t->c_lflag & ICANON)
+   flags |= ENABLE_LINE_INPUT;
+  if (flags & ENABLE_ECHO_INPUT && !(flags & ENABLE_LINE_INPUT))
+   /* This is illegal, so turn off the echo here, and fake it
+  when we read the characters */
+   flags &= ~ENABLE_ECHO_INPUT;
+  if ((t->c_lflag & ISIG) && !(t->c_iflag & IGNBRK))
+   flags |= ENABLE_PROCESSED_INPUT;
+  break;
 }
-  else
-{
-  if (dwMode & ENABLE_VIR

[PATCH 0/2] Console fixes for Win7.

2021-02-18 Thread Takashi Yano via Cygwin-patches
Takashi Yano (2):
  Cygwin: console: Fix SIGWINCH handling in Win7.
  Cygwin: console: Fix handling of Ctrl-S in Win7.

 winsup/cygwin/fhandler.h  |   9 +-
 winsup/cygwin/fhandler_console.cc | 306 --
 winsup/cygwin/select.cc   |   4 +-
 winsup/cygwin/spawn.cc|  32 ++--
 winsup/cygwin/tty.h   |   8 +-
 5 files changed, 113 insertions(+), 246 deletions(-)

-- 
2.30.0



[PATCH 1/2] Cygwin: console: Fix SIGWINCH handling in Win7.

2021-02-18 Thread Takashi Yano via Cygwin-patches
- If ENABLE_VIRTUAL_TERMINAL_INPUT is not set, changing window height
  does not generate WINDOW_BUFFER_SIZE_EVENT. This happens if console
  is in the legacy mode. Therefore, with this patch, the windows size
  is checked every time in cons_master_thread() if the cosole is in
  the legacy mode.
---
 winsup/cygwin/fhandler_console.cc | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/winsup/cygwin/fhandler_console.cc 
b/winsup/cygwin/fhandler_console.cc
index 5053cb053..4dee506dd 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -223,6 +223,21 @@ fhandler_console::cons_master_thread (handle_set_t *p, tty 
*ttyp)
  ReleaseMutex (p->input_mutex);
  return;
}
+  /* If ENABLE_VIRTUAL_TERMINAL_INPUT is not set, changing
+window height does not generate WINDOW_BUFFER_SIZE_EVENT.
+Therefore, check windows size every time here. */
+  if (!wincap.has_con_24bit_colors () || con_is_legacy)
+   {
+ SHORT y = con.dwWinSize.Y;
+ SHORT x = con.dwWinSize.X;
+ con.fillin (p->output_handle);
+ if (y != con.dwWinSize.Y || x != con.dwWinSize.X)
+   {
+ con.scroll_region.Top = 0;
+ con.scroll_region.Bottom = -1;
+ ttyp->kill_pgrp (SIGWINCH);
+   }
+   }
   for (i = 0; i < total_read; i++)
{
  const char c = input_rec[i].Event.KeyEvent.uChar.AsciiChar;
-- 
2.30.0



[PATCH v2] Cygwin: console: Introduce new thread which handles input signal.

2021-02-16 Thread Takashi Yano via Cygwin-patches
- Currently, Ctrl-Z, Ctrl-\ and SIGWINCH does not work in console
  if the process does not call read() or select(). This is because
  these are processed in process_input_message() which is called
  from read() or select(). This is a long standing issue of console.
  Addresses:
https://cygwin.com/pipermail/cygwin/2020-May/244898.html
https://cygwin.com/pipermail/cygwin/2021-February/247779.html

  With this patch, new thread which handles only input signals is
  introduced so that Crtl-Z, etc. work without calling read() or
  select(). Ctrl-S and Ctrl-Q are also handled in this thread.
---
 winsup/cygwin/exceptions.cc   |   1 +
 winsup/cygwin/fhandler.h  |   5 +-
 winsup/cygwin/fhandler_console.cc | 177 +-
 3 files changed, 181 insertions(+), 2 deletions(-)

diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index 3a6823325..a914110fe 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -1163,6 +1163,7 @@ ctrl_c_handler (DWORD type)
sig = SIGQUIT;
   t->last_ctrl_c = GetTickCount64 ();
   t->kill_pgrp (sig);
+  t->output_stopped = false;
   t->last_ctrl_c = GetTickCount64 ();
   return TRUE;
 }
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 166ade414..e457e2785 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -2105,6 +2105,7 @@ public:
 HANDLE input_mutex;
 HANDLE output_mutex;
   };
+  HANDLE thread_sync_event;
 private:
   static const unsigned MAX_WRITE_CHARS;
   static console_state *shared_console_info;
@@ -2167,7 +2168,7 @@ private:
 
   void __reg3 read (void *ptr, size_t& len);
   ssize_t __stdcall write (const void *ptr, size_t len);
-  void doecho (const void *str, DWORD len) { (void) write (str, len); }
+  void doecho (const void *str, DWORD len);
   int close ();
   static bool exists () {return !!GetConsoleCP ();}
 
@@ -2247,6 +2248,8 @@ private:
   static void request_xterm_mode_input (bool, const handle_set_t *p);
   static void request_xterm_mode_output (bool, const handle_set_t *p);
 
+  static void cons_master_thread (handle_set_t *p, tty *ttyp);
+
   friend tty_min * tty_list::get_cttyp ();
 };
 
diff --git a/winsup/cygwin/fhandler_console.cc 
b/winsup/cygwin/fhandler_console.cc
index 78af6cf2b..5053cb053 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -47,6 +47,8 @@ details. */
  con.b.srWindow.Top + con.scroll_region.Bottom)
 #define con_is_legacy (shared_console_info && con.is_legacy)
 
+#define CONS_THREAD_SYNC "cygcons.thread_sync"
+
 const unsigned fhandler_console::MAX_WRITE_CHARS = 16384;
 
 fhandler_console::console_state NO_COPY *fhandler_console::shared_console_info;
@@ -170,6 +172,143 @@ console_unit::console_unit (HWND me0):
 api_fatal ("console device allocation failure - too many consoles in use, 
max consoles is 32");
 }
 
+static DWORD WINAPI
+cons_master_thread (VOID *arg)
+{
+  fhandler_console *fh = (fhandler_console *) arg;
+  tty *ttyp = (tty *) fh->tc ();
+  fhandler_console::handle_set_t handle_set;
+  fh->get_duplicated_handle_set (&handle_set);
+  HANDLE thread_sync_event;
+  DuplicateHandle (GetCurrentProcess (), fh->thread_sync_event,
+  GetCurrentProcess (), &thread_sync_event,
+  0, FALSE, DUPLICATE_SAME_ACCESS);
+  SetEvent (thread_sync_event);
+  /* Do not touch class members after here because the class instance
+ may have been destroyed. */
+  fhandler_console::cons_master_thread (&handle_set, ttyp);
+  fhandler_console::close_handle_set (&handle_set);
+  SetEvent (thread_sync_event);
+  CloseHandle (thread_sync_event);
+  return 0;
+}
+
+/* This thread processes signals derived from input messages.
+   Without this thread, those signals can be handled only when
+   the process calls read() or select(). This thread reads input
+   records, processes signals and removes corresponding record.
+   The other input records are kept back for read() or select(). */
+void
+fhandler_console::cons_master_thread (handle_set_t *p, tty *ttyp)
+{
+  DWORD output_stopped_at = 0;
+  while (con.owner == myself->pid)
+{
+  DWORD total_read, n, i, j;
+  INPUT_RECORD input_rec[INREC_SIZE];
+
+  WaitForSingleObject (p->input_mutex, INFINITE);
+  total_read = 0;
+  switch (cygwait (p->input_handle, (DWORD) 0))
+   {
+   case WAIT_OBJECT_0:
+ ReadConsoleInputA (p->input_handle,
+input_rec, INREC_SIZE, &total_read);
+ break;
+   case WAIT_TIMEOUT:
+   case WAIT_SIGNALED:
+   case WAIT_CANCELED:
+ break;
+   default: /* Error */
+ ReleaseMutex (p->input_mutex);
+ return;
+   }
+  for (i = 0; i < total_read; i++)
+   {
+ const char c = input_rec[i].Event.KeyEvent.uChar.AsciiChar;
+ bool processed = false;
+ termios &ti = ttyp->ti;
+ switch (input_re

[PATCH] Cygwin: console: Introduce new thread which handles input signal.

2021-02-16 Thread Takashi Yano via Cygwin-patches
- Currently, Ctrl-Z, Ctrl-\ and SIGWINCH does not work in console
  if the process does not call read() or select(). This is because
  these are processed in process_input_message() which is called
  from read() or select(). This is a long standing issue of console.
  Addresses:
https://cygwin.com/pipermail/cygwin/2020-May/244898.html
https://cygwin.com/pipermail/cygwin/2021-February/247779.html

  With this patch, new thread which handles only input signals is
  introduced so that Crtl-Z, etc. work without calling read() or
  select(). Ctrl-S and Ctrl-Q are also handled in this thread.
---
 winsup/cygwin/exceptions.cc   |   1 +
 winsup/cygwin/fhandler.h  |   4 +
 winsup/cygwin/fhandler_console.cc | 168 +-
 3 files changed, 172 insertions(+), 1 deletion(-)

diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index 3a6823325..a914110fe 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -1163,6 +1163,7 @@ ctrl_c_handler (DWORD type)
sig = SIGQUIT;
   t->last_ctrl_c = GetTickCount64 ();
   t->kill_pgrp (sig);
+  t->output_stopped = false;
   t->last_ctrl_c = GetTickCount64 ();
   return TRUE;
 }
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 166ade414..9f60672ae 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -2111,6 +2111,7 @@ private:
   static bool invisible_console;
   HANDLE input_mutex, output_mutex;
   handle_set_t handle_set;
+  HANDLE thread_sync_event;
 
   /* Used when we encounter a truncated multi-byte sequence.  The
  lead bytes are stored here and revisited in the next write call. */
@@ -2247,6 +2248,9 @@ private:
   static void request_xterm_mode_input (bool, const handle_set_t *p);
   static void request_xterm_mode_output (bool, const handle_set_t *p);
 
+  static DWORD WINAPI start_master_thread (void *arg);
+  static void cons_master_thread (handle_set_t *p, tty *ttyp);
+
   friend tty_min * tty_list::get_cttyp ();
 };
 
diff --git a/winsup/cygwin/fhandler_console.cc 
b/winsup/cygwin/fhandler_console.cc
index 78af6cf2b..b5fcd3a0a 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -47,6 +47,8 @@ details. */
  con.b.srWindow.Top + con.scroll_region.Bottom)
 #define con_is_legacy (shared_console_info && con.is_legacy)
 
+#define CONS_THREAD_SYNC "cygcons.thread_sync"
+
 const unsigned fhandler_console::MAX_WRITE_CHARS = 16384;
 
 fhandler_console::console_state NO_COPY *fhandler_console::shared_console_info;
@@ -170,6 +172,143 @@ console_unit::console_unit (HWND me0):
 api_fatal ("console device allocation failure - too many consoles in use, 
max consoles is 32");
 }
 
+DWORD WINAPI
+fhandler_console::start_master_thread (VOID *arg)
+{
+  fhandler_console *fh = (fhandler_console *) arg;
+  tty *ttyp = (tty *) fh->tc ();
+  fhandler_console::handle_set_t handle_set;
+  fh->get_duplicated_handle_set (&handle_set);
+  HANDLE thread_sync_event;
+  DuplicateHandle (GetCurrentProcess (), fh->thread_sync_event,
+  GetCurrentProcess (), &thread_sync_event,
+  0, FALSE, DUPLICATE_SAME_ACCESS);
+  SetEvent (thread_sync_event);
+  /* Do not touch class members after here because the class instance
+ may have been destroyed. */
+  cons_master_thread (&handle_set, ttyp);
+  close_handle_set (&handle_set);
+  SetEvent (thread_sync_event);
+  CloseHandle (thread_sync_event);
+  return 0;
+}
+
+/* This thread processes signals derived from input messages.
+   Without this thread, those signals can be handled only when
+   the process calls read() or select(). This thread reads input
+   records, processes signals and removes corresponding record.
+   The other input records are kept back for read() or select(). */
+void
+fhandler_console::cons_master_thread (handle_set_t *p, tty *ttyp)
+{
+  DWORD output_stopped_at = 0;
+  while (con.owner == myself->pid)
+{
+  DWORD total_read, n, i, j;
+  INPUT_RECORD input_rec[INREC_SIZE];
+
+  WaitForSingleObject (p->input_mutex, INFINITE);
+  total_read = 0;
+  switch (cygwait (p->input_handle, (DWORD) 0))
+   {
+   case WAIT_OBJECT_0:
+ ReadConsoleInputA (p->input_handle,
+input_rec, INREC_SIZE, &total_read);
+ break;
+   case WAIT_TIMEOUT:
+   case WAIT_SIGNALED:
+   case WAIT_CANCELED:
+ break;
+   default: /* Error */
+ ReleaseMutex (p->input_mutex);
+ return;
+   }
+  for (i = 0; i < total_read; i++)
+   {
+ const char c = input_rec[i].Event.KeyEvent.uChar.AsciiChar;
+ bool processed = false;
+ termios &ti = ttyp->ti;
+ switch (input_rec[i].EventType)
+   {
+   case KEY_EVENT:
+ if (ti.c_lflag & ISIG)
+   {
+ int sig = 0;
+ if (CCEQ (ti.c_cc[VINTR], c))
+

Re: [PATCH v2] Cygwin: console: Abort read() on signal if SA_RESTART is not set.

2021-02-15 Thread Takashi Yano via Cygwin-patches
On Mon, 15 Feb 2021 13:04:41 +0100
Corinna Vinschen wrote:
> On Feb 14 18:42, Takashi Yano via Cygwin-patches wrote:
> > - Currently, console read() keeps reading after SIGWINCH is sent
> >   even if SA_RESTART flag is not set. With this patch, read()
> >   returns EINTR on SIGWINCH if SA_RESTART flag is not set.
> >   The same problem for SIGQUIT and SIGTSTP has also been fixed.
> > ---
> >  winsup/cygwin/fhandler_console.cc | 7 +++
> >  winsup/cygwin/fhandler_termios.cc | 1 +
> >  winsup/cygwin/tty.cc  | 1 +
> >  winsup/cygwin/tty.h   | 1 +
> >  4 files changed, 6 insertions(+), 4 deletions(-)
> > 
> > diff --git a/winsup/cygwin/fhandler_console.cc 
> > b/winsup/cygwin/fhandler_console.cc
> > index 3c0783575..78af6cf2b 100644
> > --- a/winsup/cygwin/fhandler_console.cc
> > +++ b/winsup/cygwin/fhandler_console.cc
> > @@ -586,12 +586,11 @@ wait_retry:
> > case input_ok: /* input ready */
> >   break;
> > case input_signalled: /* signalled */
> > - release_input_mutex ();
> > - /* The signal will be handled by cygwait() above. */
> > - continue;
> > case input_winch:
> >   release_input_mutex ();
> > - continue;
> > + if (global_sigs[get_ttyp ()->last_sig].sa_flags & SA_RESTART)
> 
> Shouldn't this check for last_sig != 0 first?

This code is reached only after SIGINT, SIGTSTP, SIGQUIT (case
input_signalled) or SIGWINCH (case input_winch) has been sent.
Therefore, last_sig should be one of them here.

-- 
Takashi Yano 


[PATCH] Cygwin: pty: Fix a bug in input transfer for GDB.

2021-02-14 Thread Takashi Yano via Cygwin-patches
- With this patch, not only NL but also CR is treated as a line end
  in the code checking if input transfer is necessary.
---
 winsup/cygwin/fhandler_tty.cc | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index f6eb3ae4d..5afede859 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -1181,7 +1181,7 @@ fhandler_pty_slave::mask_switch_to_pcon_in (bool mask, 
bool xfer)
   /* In GDB, transfer input based on setpgid() does not work because
  GDB may not set terminal process group properly. Therefore,
  transfer input here if isHybrid is set. */
-  if (get_ttyp ()->switch_to_pcon_in && !!masked != mask && xfer && isHybrid)
+  if (isHybrid && !!masked != mask && xfer)
 {
   if (mask && get_ttyp ()->pcon_input_state_eq (tty::to_nat))
{
@@ -1471,7 +1471,8 @@ wait_retry:
 out:
   termios_printf ("%d = read(%p, %lu)", totalread, ptr, len);
   len = (size_t) totalread;
-  mask_switch_to_pcon_in (false, totalread > 0 && ptr0[totalread - 1] == '\n');
+  bool saw_eol = totalread > 0 && strchr ("\r\n", ptr0[totalread -1]);
+  mask_switch_to_pcon_in (false, saw_eol);
 }
 
 int
-- 
2.30.0



[PATCH v2] Cygwin: console: Abort read() on signal if SA_RESTART is not set.

2021-02-14 Thread Takashi Yano via Cygwin-patches
- Currently, console read() keeps reading after SIGWINCH is sent
  even if SA_RESTART flag is not set. With this patch, read()
  returns EINTR on SIGWINCH if SA_RESTART flag is not set.
  The same problem for SIGQUIT and SIGTSTP has also been fixed.
---
 winsup/cygwin/fhandler_console.cc | 7 +++
 winsup/cygwin/fhandler_termios.cc | 1 +
 winsup/cygwin/tty.cc  | 1 +
 winsup/cygwin/tty.h   | 1 +
 4 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/winsup/cygwin/fhandler_console.cc 
b/winsup/cygwin/fhandler_console.cc
index 3c0783575..78af6cf2b 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -586,12 +586,11 @@ wait_retry:
case input_ok: /* input ready */
  break;
case input_signalled: /* signalled */
- release_input_mutex ();
- /* The signal will be handled by cygwait() above. */
- continue;
case input_winch:
  release_input_mutex ();
- continue;
+ if (global_sigs[get_ttyp ()->last_sig].sa_flags & SA_RESTART)
+   continue;
+ goto sig_exit;
default:
  /* Should not come here */
  release_input_mutex ();
diff --git a/winsup/cygwin/fhandler_termios.cc 
b/winsup/cygwin/fhandler_termios.cc
index 9fbace95c..e8daf946b 100644
--- a/winsup/cygwin/fhandler_termios.cc
+++ b/winsup/cygwin/fhandler_termios.cc
@@ -133,6 +133,7 @@ tty_min::kill_pgrp (int sig)
   siginfo_t si = {0};
   si.si_signo = sig;
   si.si_code = SI_KERNEL;
+  last_sig = sig;
 
   for (unsigned i = 0; i < pids.npids; i++)
 {
diff --git a/winsup/cygwin/tty.cc b/winsup/cygwin/tty.cc
index 41f81f694..7627cd6c7 100644
--- a/winsup/cygwin/tty.cc
+++ b/winsup/cygwin/tty.cc
@@ -251,6 +251,7 @@ tty::init ()
   master_is_running_as_service = false;
   req_xfer_input = false;
   pcon_input_state = to_cyg;
+  last_sig = 0;
 }
 
 HANDLE
diff --git a/winsup/cygwin/tty.h b/winsup/cygwin/tty.h
index e1de7ab46..a8ddd68d6 100644
--- a/winsup/cygwin/tty.h
+++ b/winsup/cygwin/tty.h
@@ -48,6 +48,7 @@ public:
   fh_devices ntty;
   ULONGLONG last_ctrl_c;   /* tick count of last ctrl-c */
   bool is_console;
+  int last_sig;
 
   IMPLEMENT_STATUS_FLAG (bool, initialized)
   IMPLEMENT_STATUS_FLAG (bool, rstcons)
-- 
2.30.0



[PATCH] Cygwin: console: Abort read() on SIGWINCH if SA_RESTART is not set.

2021-02-14 Thread Takashi Yano via Cygwin-patches
- Currently, console read() keeps reading after SIGWINCH is sent
  even if SA_RESTART flag is not set. With this patch, read()
  returns EINTR on SIGWINCH if SA_RESTART flag is not set.
---
 winsup/cygwin/fhandler_console.cc | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/winsup/cygwin/fhandler_console.cc 
b/winsup/cygwin/fhandler_console.cc
index 3c0783575..bdd6e5bb6 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -591,7 +591,9 @@ wait_retry:
  continue;
case input_winch:
  release_input_mutex ();
- continue;
+ if (global_sigs[SIGWINCH].sa_flags & SA_RESTART)
+   continue;
+ goto sig_exit;
default:
  /* Should not come here */
  release_input_mutex ();
-- 
2.30.0



[PATCH v2] Cygwin: pty: Reduce unecessary input transfer.

2021-02-11 Thread Takashi Yano via Cygwin-patches
- Currently, input transfer is performed every time one line is read(),
  if the non-cygwin app is running in the background. With this patch,
  transfer is triggered by setpgid() rather than read() so that the
  unnecessary input transfer can be reduced much in that situation.
---
 winsup/cygwin/fhandler.h  |  15 +-
 winsup/cygwin/fhandler_tty.cc | 377 --
 winsup/cygwin/spawn.cc|  78 ---
 winsup/cygwin/tty.cc  |  89 
 winsup/cygwin/tty.h   |  16 +-
 5 files changed, 376 insertions(+), 199 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 2fad7d33c..95011b6e3 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -2244,13 +2244,13 @@ class fhandler_pty_common: public fhandler_termios
  public:
   fhandler_pty_common ()
 : fhandler_termios (),
-output_mutex (NULL), input_mutex (NULL),
+output_mutex (NULL), input_mutex (NULL), pcon_mutex (NULL),
 input_available_event (NULL)
   {
 pc.file_attributes (FILE_ATTRIBUTE_NORMAL);
   }
   static const unsigned pipesize = 128 * 1024;
-  HANDLE output_mutex, input_mutex;
+  HANDLE output_mutex, input_mutex, pcon_mutex;
   HANDLE input_available_event;
 
   bool use_archetype () const {return true;}
@@ -2306,13 +2306,6 @@ class fhandler_pty_slave: public fhandler_pty_common
   void fch_close_handles ();
 
  public:
-  /* Transfer direction for transfer_input() */
-  enum xfer_dir
-  {
-to_nat,
-to_cyg
-  };
-
   /* Constructor */
   fhandler_pty_slave (int);
 
@@ -2371,8 +2364,8 @@ class fhandler_pty_slave: public fhandler_pty_common
   void setup_locale (void);
   tty *get_ttyp () { return (tty *) tc (); } /* Override as public */
   void create_invisible_console (void);
-  static void transfer_input (xfer_dir dir, HANDLE from, tty *ttyp,
- _minor_t unit, HANDLE input_available_event);
+  static void transfer_input (tty::xfer_dir dir, HANDLE from, tty *ttyp,
+ HANDLE input_available_event);
   HANDLE get_input_available_event (void) { return input_available_event; }
   bool pcon_activated (void) { return get_ttyp ()->pcon_activated; }
 };
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 48b89ae77..f6eb3ae4d 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -127,7 +127,7 @@ set_switch_to_pcon (HANDLE *in, HANDLE *out, HANDLE *err, 
bool iscygwin)
   if (*err == cfd->get_output_handle () ||
  (fd == 2 && *err == GetStdHandle (STD_ERROR_HANDLE)))
replace_err = (fhandler_base *) cfd;
-  if (cfd->get_major () == DEV_PTYS_MAJOR)
+  if (cfd->get_device () == (dev_t) myself->ctty)
{
  fhandler_base *fh = cfd;
  fhandler_pty_slave *ptys = (fhandler_pty_slave *) fh;
@@ -154,6 +154,7 @@ set_switch_to_pcon (HANDLE *in, HANDLE *out, HANDLE *err, 
bool iscygwin)
 /* CreateProcess() is hooked for GDB etc. */
 DEF_HOOK (CreateProcessA);
 DEF_HOOK (CreateProcessW);
+DEF_HOOK (exit);
 
 static BOOL WINAPI
 CreateProcessA_Hooked
@@ -268,6 +269,34 @@ CreateProcessW_Hooked
   return ret;
 }
 
+void
+exit_Hooked (int e)
+{
+  if (isHybrid)
+{
+  cygheap_fdenum cfd (false);
+  while (cfd.next () >= 0)
+   if (cfd->get_device () == (dev_t) myself->ctty)
+ {
+   fhandler_base *fh = cfd;
+   fhandler_pty_slave *ptys = (fhandler_pty_slave *) fh;
+   tty *ttyp = ptys->get_ttyp ();
+   HANDLE from = ptys->get_handle ();
+   HANDLE input_available_event = ptys->get_input_available_event ();
+   if (ttyp->getpgid () == myself->pgid
+   && ttyp->pcon_input_state_eq (tty::to_nat))
+ {
+   WaitForSingleObject (ptys->input_mutex, INFINITE);
+   fhandler_pty_slave::transfer_input (tty::to_cyg, from, ttyp,
+   input_available_event);
+   ReleaseMutex (ptys->input_mutex);
+ }
+   break;
+ }
+}
+  exit_Orig (e);
+}
+
 static void
 convert_mb_str (UINT cp_to, char *ptr_to, size_t *len_to,
UINT cp_from, const char *ptr_from, size_t len_from,
@@ -438,7 +467,8 @@ fhandler_pty_master::accept_input ()
 
   HANDLE write_to = get_output_handle ();
   tmp_pathbuf tp;
-  if (to_be_read_from_pcon ())
+  if (to_be_read_from_pcon ()
+  && get_ttyp ()->pcon_input_state == tty::to_nat)
 {
   write_to = to_slave;
 
@@ -487,11 +517,27 @@ fhandler_pty_master::accept_input ()
 }
   else
 {
-  DWORD rc;
+  BOOL rc = TRUE;
   DWORD written = 0;
 
   paranoid_printf ("about to write %u chars to slave", bytes_left);
-  rc = WriteFile (write_to, p, bytes_left, &written, NULL);
+  /* Write line by line for transfer input. */
+  char *p0 = p;
+  char *p1 = p;
+  DWORD n;
+  while ((p1 = (char *) memchr (p0, '\n', bytes_left - (p0 

Re: [PATCH] Cygwin: pty: Reduce unecessary input transfer.

2021-02-10 Thread Takashi Yano via Cygwin-patches
On Wed, 10 Feb 2021 18:02:59 +0900
Takashi Yano wrote:
> - Currently, input transfer is performed every time one line is read(),
>   if the non-cygwin app is running in the background. With this patch,
>   transfer is triggered by setpgid() rather than read() so that the
>   unnecessary input transfer can be reduced much in that situation.
> ---
>  winsup/cygwin/fhandler.h  |  15 +-
>  winsup/cygwin/fhandler_tty.cc | 371 --
>  winsup/cygwin/spawn.cc|  76 ---
>  winsup/cygwin/tty.cc  |  89 
>  winsup/cygwin/tty.h   |  16 +-
>  5 files changed, 371 insertions(+), 196 deletions(-)

Hmm. This patch seems to have some race issues.
Please wait for v2 patch.

-- 
Takashi Yano 


[PATCH] Cygwin: pty: Reduce unecessary input transfer.

2021-02-10 Thread Takashi Yano via Cygwin-patches
- Currently, input transfer is performed every time one line is read(),
  if the non-cygwin app is running in the background. With this patch,
  transfer is triggered by setpgid() rather than read() so that the
  unnecessary input transfer can be reduced much in that situation.
---
 winsup/cygwin/fhandler.h  |  15 +-
 winsup/cygwin/fhandler_tty.cc | 371 --
 winsup/cygwin/spawn.cc|  76 ---
 winsup/cygwin/tty.cc  |  89 
 winsup/cygwin/tty.h   |  16 +-
 5 files changed, 371 insertions(+), 196 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 2fad7d33c..95011b6e3 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -2244,13 +2244,13 @@ class fhandler_pty_common: public fhandler_termios
  public:
   fhandler_pty_common ()
 : fhandler_termios (),
-output_mutex (NULL), input_mutex (NULL),
+output_mutex (NULL), input_mutex (NULL), pcon_mutex (NULL),
 input_available_event (NULL)
   {
 pc.file_attributes (FILE_ATTRIBUTE_NORMAL);
   }
   static const unsigned pipesize = 128 * 1024;
-  HANDLE output_mutex, input_mutex;
+  HANDLE output_mutex, input_mutex, pcon_mutex;
   HANDLE input_available_event;
 
   bool use_archetype () const {return true;}
@@ -2306,13 +2306,6 @@ class fhandler_pty_slave: public fhandler_pty_common
   void fch_close_handles ();
 
  public:
-  /* Transfer direction for transfer_input() */
-  enum xfer_dir
-  {
-to_nat,
-to_cyg
-  };
-
   /* Constructor */
   fhandler_pty_slave (int);
 
@@ -2371,8 +2364,8 @@ class fhandler_pty_slave: public fhandler_pty_common
   void setup_locale (void);
   tty *get_ttyp () { return (tty *) tc (); } /* Override as public */
   void create_invisible_console (void);
-  static void transfer_input (xfer_dir dir, HANDLE from, tty *ttyp,
- _minor_t unit, HANDLE input_available_event);
+  static void transfer_input (tty::xfer_dir dir, HANDLE from, tty *ttyp,
+ HANDLE input_available_event);
   HANDLE get_input_available_event (void) { return input_available_event; }
   bool pcon_activated (void) { return get_ttyp ()->pcon_activated; }
 };
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 48b89ae77..7d2748b66 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -127,7 +127,7 @@ set_switch_to_pcon (HANDLE *in, HANDLE *out, HANDLE *err, 
bool iscygwin)
   if (*err == cfd->get_output_handle () ||
  (fd == 2 && *err == GetStdHandle (STD_ERROR_HANDLE)))
replace_err = (fhandler_base *) cfd;
-  if (cfd->get_major () == DEV_PTYS_MAJOR)
+  if (cfd->get_device () == (dev_t) myself->ctty)
{
  fhandler_base *fh = cfd;
  fhandler_pty_slave *ptys = (fhandler_pty_slave *) fh;
@@ -154,6 +154,7 @@ set_switch_to_pcon (HANDLE *in, HANDLE *out, HANDLE *err, 
bool iscygwin)
 /* CreateProcess() is hooked for GDB etc. */
 DEF_HOOK (CreateProcessA);
 DEF_HOOK (CreateProcessW);
+DEF_HOOK (exit);
 
 static BOOL WINAPI
 CreateProcessA_Hooked
@@ -268,6 +269,33 @@ CreateProcessW_Hooked
   return ret;
 }
 
+void
+exit_Hooked (int e)
+{
+  if (isHybrid)
+{
+  cygheap_fdenum cfd (false);
+  while (cfd.next () >= 0)
+   if (cfd->get_device () == (dev_t) myself->ctty)
+ {
+   fhandler_base *fh = cfd;
+   fhandler_pty_slave *ptys = (fhandler_pty_slave *) fh;
+   tty *ttyp = ptys->get_ttyp ();
+   HANDLE from = ptys->get_handle ();
+   HANDLE input_available_event = ptys->get_input_available_event ();
+   if (ttyp->pcon_input_state_eq (tty::to_nat))
+ {
+   WaitForSingleObject (ptys->input_mutex, INFINITE);
+   fhandler_pty_slave::transfer_input (tty::to_cyg, from, ttyp,
+   input_available_event);
+   ReleaseMutex (ptys->input_mutex);
+ }
+   break;
+ }
+}
+  exit_Orig (e);
+}
+
 static void
 convert_mb_str (UINT cp_to, char *ptr_to, size_t *len_to,
UINT cp_from, const char *ptr_from, size_t len_from,
@@ -487,11 +515,27 @@ fhandler_pty_master::accept_input ()
 }
   else
 {
-  DWORD rc;
+  BOOL rc = TRUE;
   DWORD written = 0;
 
   paranoid_printf ("about to write %u chars to slave", bytes_left);
-  rc = WriteFile (write_to, p, bytes_left, &written, NULL);
+  /* Write line by line for transfer input. */
+  char *p0 = p;
+  char *p1 = p;
+  DWORD n;
+  while ((p1 = (char *) memchr (p0, '\n', bytes_left - (p0 - p)))
+|| (p1 = (char *) memchr (p0, '\r', bytes_left - (p0 - p
+   {
+ n = p1 - p0 + 1;
+ rc = WriteFile (write_to, p0, n, &n, NULL);
+ written += n;
+ p0 = p1 + 1;
+   }
+  if ((n = bytes_left - (p0 - p)))
+   {
+ rc = WriteFile (write_to, p0, n, &n, NUL

[PATCH] Cygwin: exceptions.cc: Suspend all threads in sig_handle_tty_stop().

2021-01-28 Thread Takashi Yano via Cygwin-patches
- Currently, thread created by pthread_create() is not suspended by
  the signal SIGTSTP. For example, even if a process with a thread
  is suspended by Ctrl-Z, the thread continues running. This patch
  fixes the issue.
---
 winsup/cygwin/exceptions.cc | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index c98b92d30..3a6823325 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -902,7 +902,9 @@ sig_handle_tty_stop (int sig, siginfo_t *, void *)
 thread. */
   /* Use special cygwait parameter to handle SIGCONT.  _main_tls.sig will
 be cleared under lock when SIGCONT is detected.  */
+  pthread::suspend_all_except_self ();
   DWORD res = cygwait (NULL, cw_infinite, cw_sig_cont);
+  pthread::resume_all ();
   switch (res)
{
case WAIT_SIGNALED:
-- 
2.30.0



[PATCH] Cygwin: console: Align the behaviour against signal with pty.

2021-01-28 Thread Takashi Yano via Cygwin-patches
- Currently, read() returns -1 with EINTR if the process is suspended
  by Ctrl-Z and resumed by fg command, while pty continues to read.
  For example, xxd command stops with error "Interrupted system call"
  after Ctrl-Z and fg. This patch aligns the behaviour with pty (and
  Linux).
---
 winsup/cygwin/fhandler_console.cc | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/winsup/cygwin/fhandler_console.cc 
b/winsup/cygwin/fhandler_console.cc
index 0b404411e..3c0783575 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -587,7 +587,8 @@ wait_retry:
  break;
case input_signalled: /* signalled */
  release_input_mutex ();
- goto sig_exit;
+ /* The signal will be handled by cygwait() above. */
+ continue;
case input_winch:
  release_input_mutex ();
  continue;
-- 
2.30.0



[PATCH v3 2/2] Cygwin: pty: Make slave read() thread-safe.

2021-01-28 Thread Takashi Yano via Cygwin-patches
- Currently slave read() is somehow not thread-safe. This patch
  fixes the issue.
---
 winsup/cygwin/fhandler_tty.cc | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 06fc19ac2..48b89ae77 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -1241,6 +1241,7 @@ fhandler_pty_slave::read (void *ptr, size_t& len)
time_to_wait = !vtime ? INFINITE : 100 * vtime;
 }
 
+wait_retry:
   while (len)
 {
   switch (cygwait (input_available_event, time_to_wait))
@@ -1319,6 +1320,11 @@ fhandler_pty_slave::read (void *ptr, size_t& len)
}
  goto out;
}
+  if (!IsEventSignalled (input_available_event))
+   { /* Maybe another thread has processed input. */
+ ReleaseMutex (input_mutex);
+ goto wait_retry;
+   }
 
   if (!bytes_available (bytes_in_pipe))
{
-- 
2.30.0



[PATCH v3 1/2] Cygwin: console: Make read() thread-safe.

2021-01-28 Thread Takashi Yano via Cygwin-patches
- Currently read() is somehow not thread-safe. This patch fixes
  the issue.
---
 winsup/cygwin/fhandler.h  | 10 ++
 winsup/cygwin/fhandler_console.cc | 11 ++-
 winsup/cygwin/fhandler_termios.cc |  2 ++
 3 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index a4c1a3816..2fad7d33c 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -1905,6 +1905,8 @@ class fhandler_termios: public fhandler_base
   tty_min *_tc;
   tty *get_ttyp () {return (tty *) tc ();}
   int eat_readahead (int n);
+  virtual void acquire_input_mutex_if_necessary (DWORD ms) {};
+  virtual void release_input_mutex_if_necessary (void) {};
 
  public:
   tty_min*& tc () {return _tc;}
@@ -2212,6 +2214,14 @@ private:
   void __release_input_mutex (const char *fn, int ln);
   DWORD __acquire_output_mutex (const char *fn, int ln, DWORD ms);
   void __release_output_mutex (const char *fn, int ln);
+  void acquire_input_mutex_if_necessary (DWORD ms)
+  {
+acquire_input_mutex (ms);
+  }
+  void release_input_mutex_if_necessary (void)
+  {
+release_input_mutex ();
+  }
 
   char *&rabuf ();
   size_t &ralen ();
diff --git a/winsup/cygwin/fhandler_console.cc 
b/winsup/cygwin/fhandler_console.cc
index 02d0ac052..0b404411e 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -571,31 +571,34 @@ wait_retry:
 #define buf ((char *) pv)
 
   int ret;
-  acquire_attach_mutex (INFINITE);
   acquire_input_mutex (INFINITE);
+  acquire_attach_mutex (INFINITE);
   ret = process_input_message ();
-  release_input_mutex ();
   release_attach_mutex ();
   switch (ret)
{
case input_error:
+ release_input_mutex ();
  goto err;
case input_processing:
+ release_input_mutex ();
  continue;
case input_ok: /* input ready */
  break;
case input_signalled: /* signalled */
+ release_input_mutex ();
  goto sig_exit;
case input_winch:
+ release_input_mutex ();
  continue;
default:
  /* Should not come here */
+ release_input_mutex ();
  goto err;
}
 }
 
   /* Check console read-ahead buffer filled from terminal requests */
-  acquire_input_mutex (INFINITE);
   while (con.cons_rapoi && *con.cons_rapoi && buflen)
 {
   buf[copied_chars++] = *con.cons_rapoi++;
@@ -984,9 +987,7 @@ fhandler_console::process_input_message (void)
   if (toadd)
{
  ssize_t ret;
- release_input_mutex ();
  line_edit_status res = line_edit (toadd, nread, *ti, &ret);
- acquire_input_mutex (INFINITE);
  if (res == line_edit_signalled)
{
  stat = input_signalled;
diff --git a/winsup/cygwin/fhandler_termios.cc 
b/winsup/cygwin/fhandler_termios.cc
index 36bc6255f..9fbace95c 100644
--- a/winsup/cygwin/fhandler_termios.cc
+++ b/winsup/cygwin/fhandler_termios.cc
@@ -332,7 +332,9 @@ fhandler_termios::line_edit (const char *rptr, size_t 
nread, termios& ti,
 
  termios_printf ("got interrupt %d, sending signal %d", c, sig);
  eat_readahead (-1);
+ release_input_mutex_if_necessary ();
  tc ()->kill_pgrp (sig);
+ acquire_input_mutex_if_necessary (INFINITE);
  ti.c_lflag &= ~FLUSHO;
  sawsig = true;
  goto restart_output;
-- 
2.30.0



[PATCH v3 0/2] Make terminal read() thread-safe.

2021-01-28 Thread Takashi Yano via Cygwin-patches
Currently read() for console and pty slave are somehow
not thread-safe. These patches fix the issue.

Takashi Yano (2):
  Cygwin: console: Make read() thread-safe.
  Cygwin: pty: Make slave read() thread-safe.

 winsup/cygwin/fhandler.h  | 10 ++
 winsup/cygwin/fhandler_console.cc | 11 ++-
 winsup/cygwin/fhandler_termios.cc |  2 ++
 winsup/cygwin/fhandler_tty.cc |  6 ++
 4 files changed, 24 insertions(+), 5 deletions(-)

-- 
2.30.0



Re: [PATCH v2 1/2] Cygwin: console: Make read() thread-safe.

2021-01-28 Thread Takashi Yano via Cygwin-patches
On Thu, 28 Jan 2021 21:20:09 +0900
Takashi Yano wrote:
> - Currently read() is somehow not thread-safe. This patch fixes the
>   issue.
> ---
>  winsup/cygwin/fhandler_console.cc | 10 +-
>  1 file changed, 5 insertions(+), 5 deletions(-)

Sorry again. This also has a problem..

-- 
Takashi Yano 


[PATCH v2 2/2] Cygwin: pty: Make slave read() thread-safe.

2021-01-28 Thread Takashi Yano via Cygwin-patches
- Currently slave read() is somehow not thread-safe. This patch
  fixes the issue.
---
 winsup/cygwin/fhandler_tty.cc | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 06fc19ac2..48b89ae77 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -1241,6 +1241,7 @@ fhandler_pty_slave::read (void *ptr, size_t& len)
time_to_wait = !vtime ? INFINITE : 100 * vtime;
 }
 
+wait_retry:
   while (len)
 {
   switch (cygwait (input_available_event, time_to_wait))
@@ -1319,6 +1320,11 @@ fhandler_pty_slave::read (void *ptr, size_t& len)
}
  goto out;
}
+  if (!IsEventSignalled (input_available_event))
+   { /* Maybe another thread has processed input. */
+ ReleaseMutex (input_mutex);
+ goto wait_retry;
+   }
 
   if (!bytes_available (bytes_in_pipe))
{
-- 
2.30.0



[PATCH v2 1/2] Cygwin: console: Make read() thread-safe.

2021-01-28 Thread Takashi Yano via Cygwin-patches
- Currently read() is somehow not thread-safe. This patch fixes the
  issue.
---
 winsup/cygwin/fhandler_console.cc | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/winsup/cygwin/fhandler_console.cc 
b/winsup/cygwin/fhandler_console.cc
index 02d0ac052..d0e5bb33a 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -530,12 +530,14 @@ fhandler_console::read (void *pv, size_t& buflen)
   if (wincap.has_con_24bit_colors ())
 request_xterm_mode_input (true, &handle_set);
 
+  acquire_input_mutex (INFINITE);
   while (!input_ready && !get_cons_readahead_valid ())
 {
   int bgres;
   if ((bgres = bg_check (SIGTTIN)) <= bg_eof)
{
  buflen = bgres;
+ release_input_mutex ();
  return;
}
 
@@ -552,6 +554,7 @@ wait_retry:
  pthread::static_cancel_self ();
  /*NOTREACHED*/
case WAIT_TIMEOUT:
+ release_input_mutex ();
  set_sig_errno (EAGAIN);
  buflen = (size_t) -1;
  return;
@@ -572,9 +575,7 @@ wait_retry:
 
   int ret;
   acquire_attach_mutex (INFINITE);
-  acquire_input_mutex (INFINITE);
   ret = process_input_message ();
-  release_input_mutex ();
   release_attach_mutex ();
   switch (ret)
{
@@ -595,7 +596,6 @@ wait_retry:
 }
 
   /* Check console read-ahead buffer filled from terminal requests */
-  acquire_input_mutex (INFINITE);
   while (con.cons_rapoi && *con.cons_rapoi && buflen)
 {
   buf[copied_chars++] = *con.cons_rapoi++;
@@ -615,11 +615,13 @@ wait_retry:
   return;
 
 err:
+  release_input_mutex ();
   __seterrno ();
   buflen = (size_t) -1;
   return;
 
 sig_exit:
+  release_input_mutex ();
   set_sig_errno (EINTR);
   buflen = (size_t) -1;
 }
@@ -984,9 +986,7 @@ fhandler_console::process_input_message (void)
   if (toadd)
{
  ssize_t ret;
- release_input_mutex ();
  line_edit_status res = line_edit (toadd, nread, *ti, &ret);
- acquire_input_mutex (INFINITE);
  if (res == line_edit_signalled)
{
  stat = input_signalled;
-- 
2.30.0



[PATCH v2 0/2] Make terminal read() thread-safe.

2021-01-28 Thread Takashi Yano via Cygwin-patches
Currently read() for console and pty slave are somehow
not thread-safe. These patches fix the issue.

Takashi Yano (2):
  Cygwin: console: Make read() thread-safe.
  Cygwin: pty: Make slave read() thread-safe.

 winsup/cygwin/fhandler_console.cc | 10 +-
 winsup/cygwin/fhandler_tty.cc |  6 ++
 2 files changed, 11 insertions(+), 5 deletions(-)

-- 
2.30.0



Re: [PATCH 1/2] Cygwin: console: Make read() thread-safe.

2021-01-28 Thread Takashi Yano via Cygwin-patches
On Thu, 28 Jan 2021 20:14:08 +0900
Takashi Yano wrote:
> - Currently read() is somehow not thread-safe. This patch fixes the
>   issue.
> ---
>  winsup/cygwin/fhandler_console.cc | 7 +++
>  winsup/cygwin/select.cc   | 3 ---
>  2 files changed, 3 insertions(+), 7 deletions(-)

Sorry, this does not seem to be enough. Please wait a while.

-- 
Takashi Yano 


[PATCH 2/2] Cygwin: pty: Make slave read() thread-safe.

2021-01-28 Thread Takashi Yano via Cygwin-patches
- Currently slave read() is somehow not thread-safe. This patch
  fixes the issue.
---
 winsup/cygwin/fhandler_tty.cc | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 06fc19ac2..48b89ae77 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -1241,6 +1241,7 @@ fhandler_pty_slave::read (void *ptr, size_t& len)
time_to_wait = !vtime ? INFINITE : 100 * vtime;
 }
 
+wait_retry:
   while (len)
 {
   switch (cygwait (input_available_event, time_to_wait))
@@ -1319,6 +1320,11 @@ fhandler_pty_slave::read (void *ptr, size_t& len)
}
  goto out;
}
+  if (!IsEventSignalled (input_available_event))
+   { /* Maybe another thread has processed input. */
+ ReleaseMutex (input_mutex);
+ goto wait_retry;
+   }
 
   if (!bytes_available (bytes_in_pipe))
{
-- 
2.30.0



[PATCH 1/2] Cygwin: console: Make read() thread-safe.

2021-01-28 Thread Takashi Yano via Cygwin-patches
- Currently read() is somehow not thread-safe. This patch fixes the
  issue.
---
 winsup/cygwin/fhandler_console.cc | 7 +++
 winsup/cygwin/select.cc   | 3 ---
 2 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/winsup/cygwin/fhandler_console.cc 
b/winsup/cygwin/fhandler_console.cc
index 02d0ac052..8324faaa2 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -572,9 +572,7 @@ wait_retry:
 
   int ret;
   acquire_attach_mutex (INFINITE);
-  acquire_input_mutex (INFINITE);
   ret = process_input_message ();
-  release_input_mutex ();
   release_attach_mutex ();
   switch (ret)
{
@@ -632,6 +630,7 @@ fhandler_console::process_input_message (void)
   if (!shared_console_info)
 return input_error;
 
+  acquire_input_mutex (INFINITE);
   termios *ti = &(get_ttyp ()->ti);
 
   fhandler_console::input_states stat = input_processing;
@@ -641,6 +640,7 @@ fhandler_console::process_input_message (void)
   if (!PeekConsoleInputW (get_handle (), input_rec, INREC_SIZE, &total_read))
 {
   termios_printf ("PeekConsoleInput failed, %E");
+  release_input_mutex ();
   return input_error;
 }
 
@@ -984,9 +984,7 @@ fhandler_console::process_input_message (void)
   if (toadd)
{
  ssize_t ret;
- release_input_mutex ();
  line_edit_status res = line_edit (toadd, nread, *ti, &ret);
- acquire_input_mutex (INFINITE);
  if (res == line_edit_signalled)
{
  stat = input_signalled;
@@ -1007,6 +1005,7 @@ out:
   DWORD discard_len = min (total_read, i + 1);
   if (discard_len)
 ReadConsoleInputW (get_handle (), input_rec, discard_len, &dummy);
+  release_input_mutex ();
   return stat;
 }
 
diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc
index dc75a2dbf..a4f401403 100644
--- a/winsup/cygwin/select.cc
+++ b/winsup/cygwin/select.cc
@@ -1083,17 +1083,14 @@ peek_console (select_record *me, bool)
}
   else if (!PeekConsoleInputW (h, &irec, 1, &events_read) || !events_read)
break;
-  fh->acquire_input_mutex (INFINITE);
   if (fhandler_console::input_winch == fh->process_input_message ()
  && global_sigs[SIGWINCH].sa_handler != SIG_IGN
  && global_sigs[SIGWINCH].sa_handler != SIG_DFL)
{
  set_sig_errno (EINTR);
- fh->release_input_mutex ();
  release_attach_mutex ();
  return -1;
}
-  fh->release_input_mutex ();
 }
   release_attach_mutex ();
   if (fh->input_ready || fh->get_cons_readahead_valid ())
-- 
2.30.0



[PATCH 0/2] Make terminal read() thread-safe.

2021-01-28 Thread Takashi Yano via Cygwin-patches
Currently read() for console and pty slave are somehow
not thread-safe. These patches fix the issue.

Takashi Yano (2):
  Cygwin: console: Make read() thread-safe.
  Cygwin: pty: Make slave read() thread-safe.

 winsup/cygwin/fhandler_console.cc | 7 +++
 winsup/cygwin/fhandler_tty.cc | 6 ++
 winsup/cygwin/select.cc   | 3 ---
 3 files changed, 9 insertions(+), 7 deletions(-)

-- 
2.30.0



[PATCH v7 4/4] Cygwin: pty: Allow multiple apps to enable pseudo console simultaneously.

2021-01-27 Thread Takashi Yano via Cygwin-patches
- After commit bb428520, there has been the disadvantage:
  7) Pseudo console cannot be activated if it is already activated for
 another process on same pty.
  This patch clears this disadvantage.
---
 winsup/cygwin/fhandler.h  |   7 +-
 winsup/cygwin/fhandler_tty.cc | 344 ++
 winsup/cygwin/select.cc   |   4 +-
 winsup/cygwin/spawn.cc|  44 +++--
 winsup/cygwin/tty.cc  |   2 +-
 winsup/cygwin/tty.h   |   6 +-
 6 files changed, 314 insertions(+), 93 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 3db33ea78..a4c1a3816 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -2273,6 +2273,9 @@ class fhandler_pty_common: public fhandler_termios
   }
 
   void resize_pseudo_console (struct winsize *);
+  static DWORD get_console_process_id (DWORD pid, bool match,
+  bool cygwin = false,
+  bool stub_only = false);
 
  protected:
   static BOOL process_opost_output (HANDLE h, const void *ptr, ssize_t& len,
@@ -2354,14 +2357,14 @@ class fhandler_pty_slave: public fhandler_pty_common
   bool term_has_pcon_cap (const WCHAR *env);
   void set_switch_to_pcon (void);
   void reset_switch_to_pcon (void);
-  void mask_switch_to_pcon_in (bool mask);
+  void mask_switch_to_pcon_in (bool mask, bool xfer);
   void setup_locale (void);
   tty *get_ttyp () { return (tty *) tc (); } /* Override as public */
   void create_invisible_console (void);
   static void transfer_input (xfer_dir dir, HANDLE from, tty *ttyp,
  _minor_t unit, HANDLE input_available_event);
   HANDLE get_input_available_event (void) { return input_available_event; }
-  bool pcon_activated (void) { return get_ttyp ()->h_pseudo_console; }
+  bool pcon_activated (void) { return get_ttyp ()->pcon_activated; }
 };
 
 #define __ptsname(buf, unit) __small_sprintf ((buf), "/dev/pty%d", (unit))
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index c74e38c3d..06fc19ac2 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -64,8 +64,9 @@ struct pipe_reply {
 
 extern HANDLE attach_mutex; /* Defined in fhandler_console.cc */
 
-static DWORD
-get_console_process_id (DWORD pid, bool match)
+DWORD
+fhandler_pty_common::get_console_process_id (DWORD pid, bool match,
+bool cygwin, bool stub_only)
 {
   tmp_pathbuf tp;
   DWORD *list = (DWORD *) tp.c_get ();
@@ -75,16 +76,34 @@ get_console_process_id (DWORD pid, bool match)
   if (num == 0 || num > buf_size)
 return 0;
 
-  DWORD res = 0;
+  DWORD res_pri = 0, res = 0;
   /* Last one is the oldest. */
   /* https://github.com/microsoft/terminal/issues/95 */
   for (int i = (int) num - 1; i >= 0; i--)
 if ((match && list[i] == pid) || (!match && list[i] != pid))
   {
-   res = list[i];
-   break;
+   if (!cygwin)
+ {
+   res_pri = list[i];
+   break;
+ }
+   else
+ {
+   pinfo p (cygwin_pid (list[i]));
+   if (!!p && p->dwProcessId && p->exec_dwProcessId
+   && p->dwProcessId != p->exec_dwProcessId)
+ {
+   res_pri = list[i];
+   break;
+ }
+   if (!!p && !res)
+ res = list[i];
+ }
   }
-  return res;
+  if (stub_only)
+return res_pri;
+  else
+return res_pri ?: res;
 }
 
 static bool isHybrid;
@@ -937,7 +956,7 @@ fhandler_pty_slave::init (HANDLE h, DWORD a, mode_t)
 void
 fhandler_pty_slave::set_switch_to_pcon (void)
 {
-  if (!get_ttyp ()->switch_to_pcon_in)
+  if (!isHybrid)
 {
   isHybrid = true;
   setup_locale ();
@@ -964,9 +983,10 @@ fhandler_pty_slave::reset_switch_to_pcon (void)
{
  CloseHandle (h_gdb_process);
  h_gdb_process = NULL;
- if (isHybrid && get_ttyp ()->pcon_pid == myself->pid)
+ if (isHybrid)
{
- if (get_ttyp ()->switch_to_pcon_in)
+ if (get_ttyp ()->switch_to_pcon_in
+ && get_ttyp ()->pcon_pid == myself->pid)
fhandler_pty_slave::transfer_input (fhandler_pty_slave::to_cyg,
get_handle (),
get_ttyp (), get_minor (),
@@ -976,7 +996,7 @@ fhandler_pty_slave::reset_switch_to_pcon (void)
   the console of the parent process will fail.
   Therefore, never close pseudo console here. */
return;
- bool need_restore_handles = !!get_ttyp ()->h_pseudo_console;
+ bool need_restore_handles = get_ttyp ()->pcon_activated;
  close_pseudoconsole (get_ttyp ());
  if (need_restore_handles)
{
@@ -1027,11 +1047,8 @@ fhandler_pty_slave::reset_switch_to_pcon (void)
  if (fix_err)
 

[PATCH v7 3/4] Cygwin: pty: Make apps using console APIs be able to debug with gdb.

2021-01-27 Thread Takashi Yano via Cygwin-patches
- After commit bb428520, there has been the disadvantage:
  2) The apps which use console API cannot be debugged with gdb. This
 is because pseudo console is not activated since gdb uses
 CreateProcess() rather than exec(). Even with this limitation,
 attaching gdb to native app, in which pseudo console is already
 activated, works.
  This patch clears this disadvantage.
---
 winsup/cygwin/fhandler.h  |   3 +
 winsup/cygwin/fhandler_tty.cc | 299 ++
 winsup/cygwin/select.cc   |   5 +-
 winsup/cygwin/spawn.cc|   2 +
 winsup/cygwin/tty.cc  |   7 +-
 winsup/cygwin/tty.h   |   5 +-
 6 files changed, 279 insertions(+), 42 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 378e9c13b..3db33ea78 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -2284,6 +2284,8 @@ 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;
+  HANDLE slave_reading;
+  LONG num_reader;
 
   /* Helper functions for fchmod and fchown. */
   bool fch_open_handles (bool chown);
@@ -2359,6 +2361,7 @@ class fhandler_pty_slave: public fhandler_pty_common
   static void transfer_input (xfer_dir dir, HANDLE from, tty *ttyp,
  _minor_t unit, HANDLE input_available_event);
   HANDLE get_input_available_event (void) { return input_available_event; }
+  bool pcon_activated (void) { return get_ttyp ()->h_pseudo_console; }
 };
 
 #define __ptsname(buf, unit) __small_sprintf ((buf), "/dev/pty%d", (unit))
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 34cff2ae5..c74e38c3d 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -27,6 +27,7 @@ details. */
 #include "cygwait.h"
 #include "registry.h"
 #include "tls_pbuf.h"
+#include "winf.h"
 
 #ifndef PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE
 #define PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE 0x00020016
@@ -87,21 +88,47 @@ get_console_process_id (DWORD pid, bool match)
 }
 
 static bool isHybrid;
+static HANDLE h_gdb_process;
 
 static void
-set_switch_to_pcon (HANDLE h)
+set_switch_to_pcon (HANDLE *in, HANDLE *out, HANDLE *err, bool iscygwin)
 {
   cygheap_fdenum cfd (false);
   int fd;
+  fhandler_base *replace_in = NULL, *replace_out = NULL, *replace_err = NULL;
+  fhandler_pty_slave *ptys_pcon = NULL;
   while ((fd = cfd.next ()) >= 0)
-if (cfd->get_major () == DEV_PTYS_MAJOR)
-  {
-   fhandler_base *fh = cfd;
-   fhandler_pty_slave *ptys = (fhandler_pty_slave *) fh;
-   if (h == ptys->get_handle ())
- ptys->set_switch_to_pcon ();
-   return;
-  }
+{
+  if (*in == cfd->get_handle () ||
+ (fd == 0 && *in == GetStdHandle (STD_INPUT_HANDLE)))
+   replace_in = (fhandler_base *) cfd;
+  if (*out == cfd->get_output_handle () ||
+ (fd == 1 && *out == GetStdHandle (STD_OUTPUT_HANDLE)))
+   replace_out = (fhandler_base *) cfd;
+  if (*err == cfd->get_output_handle () ||
+ (fd == 2 && *err == GetStdHandle (STD_ERROR_HANDLE)))
+   replace_err = (fhandler_base *) cfd;
+  if (cfd->get_major () == DEV_PTYS_MAJOR)
+   {
+ fhandler_base *fh = cfd;
+ fhandler_pty_slave *ptys = (fhandler_pty_slave *) fh;
+ if (*in == ptys->get_handle ())
+   ptys_pcon = ptys;
+   }
+}
+  if (!iscygwin && ptys_pcon)
+ptys_pcon->set_switch_to_pcon ();
+  if (replace_in)
+{
+  if (iscygwin && ptys_pcon->pcon_activated ())
+   *in = replace_in->get_handle_cyg ();
+  else
+   *in = replace_in->get_handle ();
+}
+  if (replace_out)
+*out = replace_out->get_output_handle ();
+  if (replace_err)
+*err = replace_err->get_output_handle ();
 }
 
 #define DEF_HOOK(name) static __typeof__ (name) *name##_Orig
@@ -115,16 +142,55 @@ CreateProcessA_Hooked
   BOOL inh, DWORD f, LPVOID e, LPCSTR d,
   LPSTARTUPINFOA si, LPPROCESS_INFORMATION pi)
 {
-  HANDLE h;
-  if (!isHybrid)
+  STARTUPINFOEXA siex = {0, };
+  if (si->cb == sizeof (STARTUPINFOEXA))
+siex = *(STARTUPINFOEXA *)si;
+  else
+siex.StartupInfo = *si;
+  STARTUPINFOA *siov = &siex.StartupInfo;
+  if (!(si->dwFlags & STARTF_USESTDHANDLES))
 {
-  if (si->dwFlags & STARTF_USESTDHANDLES)
-   h = si->hStdInput;
-  else
-   h = GetStdHandle (STD_INPUT_HANDLE);
-  set_switch_to_pcon (h);
+  siov->dwFlags |= STARTF_USESTDHANDLES;
+  siov->hStdInput = GetStdHandle (STD_INPUT_HANDLE);
+  siov->hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);
+  siov->hStdError = GetStdHandle (STD_ERROR_HANDLE);
 }
-  return CreateProcessA_Orig (n, c, pa, ta, inh, f, e, d, si, pi);
+  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 = 

[PATCH v7 2/4] Cygwin: pty: Keep code page between non-cygwin apps.

2021-01-27 Thread Takashi Yano via Cygwin-patches
- After commit bb428520, there has been the disadvantage:
  4) Code page cannot be changed by chcp.com. Acctually, chcp works
 itself and changes code page of its own pseudo console.  However,
 since pseudo console is recreated for another process, it cannot
 inherit the code page.
  This patch clears this disadvantage.
---
 winsup/cygwin/fhandler_tty.cc | 7 +++
 winsup/cygwin/tty.cc  | 2 ++
 winsup/cygwin/tty.h   | 2 ++
 3 files changed, 11 insertions(+)

diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index f0b2cd60a..34cff2ae5 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -2845,6 +2845,11 @@ fhandler_pty_slave::setup_pseudoconsole (bool nopcon)
   HPCON_INTERNAL *hp = (HPCON_INTERNAL *) get_ttyp ()->h_pseudo_console;
   get_ttyp ()->h_pcon_write_pipe = hp->hWritePipe;
 }
+
+  if (get_ttyp ()->previous_code_page)
+SetConsoleCP (get_ttyp ()->previous_code_page);
+  if (get_ttyp ()->previous_output_code_page)
+SetConsoleOutputCP (get_ttyp ()->previous_output_code_page);
   return true;
 
 cleanup_pcon_in:
@@ -2884,6 +2889,8 @@ fhandler_pty_slave::close_pseudoconsole (tty *ttyp)
   if (ttyp->h_pseudo_console)
 {
   ttyp->wait_pcon_fwd ();
+  ttyp->previous_code_page = GetConsoleCP ();
+  ttyp->previous_output_code_page = GetConsoleOutputCP ();
   FreeConsole ();
   AttachConsole (ATTACH_PARENT_PROCESS);
   HPCON_INTERNAL *hp = (HPCON_INTERNAL *) ttyp->h_pseudo_console;
diff --git a/winsup/cygwin/tty.cc b/winsup/cygwin/tty.cc
index 436f5c6c3..908166a37 100644
--- a/winsup/cygwin/tty.cc
+++ b/winsup/cygwin/tty.cc
@@ -246,6 +246,8 @@ tty::init ()
   has_csi6n = false;
   need_invisible_console = false;
   invisible_console_pid = 0;
+  previous_code_page = 0;
+  previous_output_code_page = 0;
 }
 
 HANDLE
diff --git a/winsup/cygwin/tty.h b/winsup/cygwin/tty.h
index eb604588c..061357437 100644
--- a/winsup/cygwin/tty.h
+++ b/winsup/cygwin/tty.h
@@ -107,6 +107,8 @@ private:
   bool has_csi6n;
   bool need_invisible_console;
   pid_t invisible_console_pid;
+  UINT previous_code_page;
+  UINT previous_output_code_page;
 
 public:
   HANDLE from_master () const { return _from_master; }
-- 
2.30.0



[PATCH v7 1/4] Cygwin: pty: Inherit typeahead data between two input pipes.

2021-01-27 Thread Takashi Yano via Cygwin-patches
- PTY has a problem that the key input, which is typed during windows
  native app is running, disappears when it returns to shell. This is
  beacuse pty has two input pipes, one is for cygwin apps and the other
  one is for native windows apps. The key input during windows native
  program is running is sent to the second input pipe while cygwin
  shell reads input from the first input pipe. This issue had been
  fixed once by commit 29431fcb, however, the new implementation of
  pseudo console support by commit bb428520 could not inherit this
  feature. This patch realize transfering input data between these
  two pipes bidirectionally by utilizing cygwin-console-helper process.
  The helper process is launched prior to starting the non-cygwin app,
  however, exits immediately unlike previous implementation.
---
 winsup/cygwin/fhandler.h  |  14 +-
 winsup/cygwin/fhandler_tty.cc | 545 +++---
 winsup/cygwin/spawn.cc|  82 +++--
 winsup/cygwin/tty.cc  |   2 -
 winsup/cygwin/tty.h   |   8 +-
 5 files changed, 504 insertions(+), 147 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index af1ef3a45..378e9c13b 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -2291,6 +2291,13 @@ class fhandler_pty_slave: public fhandler_pty_common
   void fch_close_handles ();
 
  public:
+  /* Transfer direction for transfer_input() */
+  enum xfer_dir
+  {
+to_nat,
+to_cyg
+  };
+
   /* Constructor */
   fhandler_pty_slave (int);
 
@@ -2340,7 +2347,7 @@ class fhandler_pty_slave: public fhandler_pty_common
 copyto (fh);
 return fh;
   }
-  bool setup_pseudoconsole (STARTUPINFOEXW *si, bool nopcon);
+  bool setup_pseudoconsole (bool nopcon);
   static void close_pseudoconsole (tty *ttyp);
   bool term_has_pcon_cap (const WCHAR *env);
   void set_switch_to_pcon (void);
@@ -2349,6 +2356,9 @@ class fhandler_pty_slave: public fhandler_pty_common
   void setup_locale (void);
   tty *get_ttyp () { return (tty *) tc (); } /* Override as public */
   void create_invisible_console (void);
+  static void transfer_input (xfer_dir dir, HANDLE from, tty *ttyp,
+ _minor_t unit, HANDLE input_available_event);
+  HANDLE get_input_available_event (void) { return input_available_event; }
 };
 
 #define __ptsname(buf, unit) __small_sprintf ((buf), "/dev/pty%d", (unit))
@@ -2361,6 +2371,8 @@ public:
 HANDLE from_master_cyg;
 HANDLE to_master;
 HANDLE to_master_cyg;
+HANDLE to_slave;
+HANDLE to_slave_cyg;
 HANDLE master_ctl;
 HANDLE input_available_event;
   };
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 7f0752614..f0b2cd60a 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -56,6 +56,8 @@ struct pipe_reply {
   HANDLE from_master_cyg;
   HANDLE to_master;
   HANDLE to_master_cyg;
+  HANDLE to_slave;
+  HANDLE to_slave_cyg;
   DWORD error;
 };
 
@@ -848,8 +850,14 @@ fhandler_pty_slave::reset_switch_to_pcon (void)
 return;
   if (isHybrid)
 return;
+  if (get_ttyp ()->switch_to_pcon_in && !get_ttyp ()->h_pseudo_console)
+fhandler_pty_slave::transfer_input (fhandler_pty_slave::to_cyg,
+   get_handle (),
+   get_ttyp (), get_minor (),
+   input_available_event);
   get_ttyp ()->pcon_pid = 0;
   get_ttyp ()->switch_to_pcon_in = false;
+  get_ttyp ()->h_pseudo_console = NULL;
 }
 
 ssize_t __stdcall
@@ -891,6 +899,22 @@ fhandler_pty_slave::write (const void *ptr, size_t len)
 void
 fhandler_pty_slave::mask_switch_to_pcon_in (bool mask)
 {
+  if (get_ttyp ()->switch_to_pcon_in
+  && (get_ttyp ()->pcon_pid == myself->pid
+ || !get_ttyp ()->h_pseudo_console)
+  && get_ttyp ()->mask_switch_to_pcon_in != mask)
+{
+  if (mask)
+   fhandler_pty_slave::transfer_input (fhandler_pty_slave::to_cyg,
+   get_handle (),
+   get_ttyp (), get_minor (),
+   input_available_event);
+  else
+   fhandler_pty_slave::transfer_input (fhandler_pty_slave::to_nat,
+   get_handle_cyg (),
+   get_ttyp (), get_minor (),
+   input_available_event);
+}
   get_ttyp ()->mask_switch_to_pcon_in = mask;
 }
 
@@ -1591,7 +1615,7 @@ fhandler_pty_common::resize_pseudo_console (struct 
winsize *ws)
   size.X = ws->ws_col;
   size.Y = ws->ws_row;
   pinfo p (get_ttyp ()->pcon_pid);
-  if (p && !get_ttyp ()->do_not_resize_pcon)
+  if (p)
 {
   HPCON_INTERNAL hpcon_local;
   HANDLE pcon_owner =
@@ -1763,6 +1787,17 @@ fhandler_pty_master::write (const void *ptr, size_t len)
  get_ttyp ()->pcon_start = false;
}
  ReleaseM

[PATCH v7 0/4] Improve pseudo console support.

2021-01-27 Thread Takashi Yano via Cygwin-patches
The new implementation of pseudo console support by commit bb428520
provides the important advantages, while there also has been several
disadvantages compared to the previous implementation.

These patches overturn some of them.

The disadvantage:
 1) The cygwin program which calls console API directly does not work.
is supposed to be able to be overcome as well, however, I am not sure
it is worth enough. This will need a lot of hooks for console APIs.
 --> Respecting Corinna's opinion, we decided not to implement this.

v3: Fix typeahead input issue in GDB. Several other bugs have also
been fixed.
v4: Change the conditions for calling transfer_input() slightly in
reset_switch_to_pcon() to avoid calling it if uncecessary or
with no effect.
v5: Small bug fix in v4.
v6: Yet another bug fix.
Add missing CloseHandle().
Take into account when the master is running as a service (such
as ssh session).
v7: Specify FILE_FLAG_OVERLAPPED for to_slave pipe to prevent
PeekNamedPipe() from blocking in transfer_input().
Simplify the code determining if the slave is reading.

Takashi Yano (4):
  Cygwin: pty: Inherit typeahead data between two input pipes.
  Cygwin: pty: Keep code page between non-cygwin apps.
  Cygwin: pty: Make apps using console APIs be able to debug with gdb.
  Cygwin: pty: Allow multiple apps to enable pseudo console
simultaneously.

 winsup/cygwin/fhandler.h  |   22 +-
 winsup/cygwin/fhandler_tty.cc | 1123 +++--
 winsup/cygwin/select.cc   |7 +-
 winsup/cygwin/spawn.cc|  106 +++-
 winsup/cygwin/tty.cc  |   13 +-
 winsup/cygwin/tty.h   |   21 +-
 6 files changed, 1059 insertions(+), 233 deletions(-)

-- 
2.30.0



[PATCH v6 4/4] Cygwin: pty: Allow multiple apps to enable pseudo console simultaneously.

2021-01-26 Thread Takashi Yano via Cygwin-patches
- After commit bb428520, there has been the disadvantage:
  7) Pseudo console cannot be activated if it is already activated for
 another process on same pty.
  This patch clears this disadvantage.
---
 winsup/cygwin/fhandler.h  |   7 +-
 winsup/cygwin/fhandler_tty.cc | 344 ++
 winsup/cygwin/select.cc   |   4 +-
 winsup/cygwin/spawn.cc|  44 +++--
 winsup/cygwin/tty.cc  |   2 +-
 winsup/cygwin/tty.h   |   6 +-
 6 files changed, 314 insertions(+), 93 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 0cbc18877..b1f3150ff 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -2274,6 +2274,9 @@ class fhandler_pty_common: public fhandler_termios
   }
 
   void resize_pseudo_console (struct winsize *);
+  static DWORD get_console_process_id (DWORD pid, bool match,
+  bool cygwin = false,
+  bool stub_only = false);
 
  protected:
   static BOOL process_opost_output (HANDLE h, const void *ptr, ssize_t& len,
@@ -2353,14 +2356,14 @@ class fhandler_pty_slave: public fhandler_pty_common
   bool term_has_pcon_cap (const WCHAR *env);
   void set_switch_to_pcon (void);
   void reset_switch_to_pcon (void);
-  void mask_switch_to_pcon_in (bool mask);
+  void mask_switch_to_pcon_in (bool mask, bool xfer);
   void setup_locale (void);
   tty *get_ttyp () { return (tty *) tc (); } /* Override as public */
   void create_invisible_console (void);
   static void transfer_input (xfer_dir dir, HANDLE from, tty *ttyp,
  _minor_t unit, HANDLE input_available_event);
   HANDLE get_input_available_event (void) { return input_available_event; }
-  bool pcon_activated (void) { return get_ttyp ()->h_pseudo_console; }
+  bool pcon_activated (void) { return get_ttyp ()->pcon_activated; }
 };
 
 #define __ptsname(buf, unit) __small_sprintf ((buf), "/dev/pty%d", (unit))
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 6c88e1abf..8c875efc1 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -64,8 +64,9 @@ struct pipe_reply {
 
 extern HANDLE attach_mutex; /* Defined in fhandler_console.cc */
 
-static DWORD
-get_console_process_id (DWORD pid, bool match)
+DWORD
+fhandler_pty_common::get_console_process_id (DWORD pid, bool match,
+bool cygwin, bool stub_only)
 {
   tmp_pathbuf tp;
   DWORD *list = (DWORD *) tp.c_get ();
@@ -75,16 +76,34 @@ get_console_process_id (DWORD pid, bool match)
   if (num == 0 || num > buf_size)
 return 0;
 
-  DWORD res = 0;
+  DWORD res_pri = 0, res = 0;
   /* Last one is the oldest. */
   /* https://github.com/microsoft/terminal/issues/95 */
   for (int i = (int) num - 1; i >= 0; i--)
 if ((match && list[i] == pid) || (!match && list[i] != pid))
   {
-   res = list[i];
-   break;
+   if (!cygwin)
+ {
+   res_pri = list[i];
+   break;
+ }
+   else
+ {
+   pinfo p (cygwin_pid (list[i]));
+   if (!!p && p->dwProcessId && p->exec_dwProcessId
+   && p->dwProcessId != p->exec_dwProcessId)
+ {
+   res_pri = list[i];
+   break;
+ }
+   if (!!p && !res)
+ res = list[i];
+ }
   }
-  return res;
+  if (stub_only)
+return res_pri;
+  else
+return res_pri ?: res;
 }
 
 static bool isHybrid;
@@ -938,7 +957,7 @@ fhandler_pty_slave::init (HANDLE h, DWORD a, mode_t)
 void
 fhandler_pty_slave::set_switch_to_pcon (void)
 {
-  if (!get_ttyp ()->switch_to_pcon_in)
+  if (!isHybrid)
 {
   isHybrid = true;
   setup_locale ();
@@ -965,9 +984,10 @@ fhandler_pty_slave::reset_switch_to_pcon (void)
{
  CloseHandle (h_gdb_process);
  h_gdb_process = NULL;
- if (isHybrid && get_ttyp ()->pcon_pid == myself->pid)
+ if (isHybrid)
{
- if (get_ttyp ()->switch_to_pcon_in)
+ if (get_ttyp ()->switch_to_pcon_in
+ && get_ttyp ()->pcon_pid == myself->pid)
fhandler_pty_slave::transfer_input (fhandler_pty_slave::to_cyg,
get_handle (),
get_ttyp (), get_minor (),
@@ -977,7 +997,7 @@ fhandler_pty_slave::reset_switch_to_pcon (void)
   the console of the parent process will fail.
   Therefore, never close pseudo console here. */
return;
- bool need_restore_handles = !!get_ttyp ()->h_pseudo_console;
+ bool need_restore_handles = get_ttyp ()->pcon_activated;
  close_pseudoconsole (get_ttyp ());
  if (need_restore_handles)
{
@@ -1028,11 +1048,8 @@ fhandler_pty_slave::reset_switch_to_pcon (void)
  if (fix_err)
 

[PATCH v6 3/4] Cygwin: pty: Make apps using console APIs be able to debug with gdb.

2021-01-26 Thread Takashi Yano via Cygwin-patches
- After commit bb428520, there has been the disadvantage:
  2) The apps which use console API cannot be debugged with gdb. This
 is because pseudo console is not activated since gdb uses
 CreateProcess() rather than exec(). Even with this limitation,
 attaching gdb to native app, in which pseudo console is already
 activated, works.
  This patch clears this disadvantage.
---
 winsup/cygwin/fhandler.h  |   4 +-
 winsup/cygwin/fhandler_tty.cc | 294 ++
 winsup/cygwin/select.cc   |   5 +-
 winsup/cygwin/spawn.cc|   2 +
 winsup/cygwin/tty.cc  |   7 +-
 winsup/cygwin/tty.h   |   5 +-
 6 files changed, 277 insertions(+), 40 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 378e9c13b..0cbc18877 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -2235,13 +2235,14 @@ class fhandler_pty_common: public fhandler_termios
   fhandler_pty_common ()
 : fhandler_termios (),
 output_mutex (NULL), input_mutex (NULL),
-input_available_event (NULL)
+input_available_event (NULL), slave_reading (NULL)
   {
 pc.file_attributes (FILE_ATTRIBUTE_NORMAL);
   }
   static const unsigned pipesize = 128 * 1024;
   HANDLE output_mutex, input_mutex;
   HANDLE input_available_event;
+  HANDLE slave_reading;
 
   bool use_archetype () const {return true;}
   DWORD __acquire_output_mutex (const char *fn, int ln, DWORD ms);
@@ -2359,6 +2360,7 @@ class fhandler_pty_slave: public fhandler_pty_common
   static void transfer_input (xfer_dir dir, HANDLE from, tty *ttyp,
  _minor_t unit, HANDLE input_available_event);
   HANDLE get_input_available_event (void) { return input_available_event; }
+  bool pcon_activated (void) { return get_ttyp ()->h_pseudo_console; }
 };
 
 #define __ptsname(buf, unit) __small_sprintf ((buf), "/dev/pty%d", (unit))
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 34cff2ae5..6c88e1abf 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -27,6 +27,7 @@ details. */
 #include "cygwait.h"
 #include "registry.h"
 #include "tls_pbuf.h"
+#include "winf.h"
 
 #ifndef PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE
 #define PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE 0x00020016
@@ -87,21 +88,47 @@ get_console_process_id (DWORD pid, bool match)
 }
 
 static bool isHybrid;
+static HANDLE h_gdb_process;
 
 static void
-set_switch_to_pcon (HANDLE h)
+set_switch_to_pcon (HANDLE *in, HANDLE *out, HANDLE *err, bool iscygwin)
 {
   cygheap_fdenum cfd (false);
   int fd;
+  fhandler_base *replace_in = NULL, *replace_out = NULL, *replace_err = NULL;
+  fhandler_pty_slave *ptys_pcon = NULL;
   while ((fd = cfd.next ()) >= 0)
-if (cfd->get_major () == DEV_PTYS_MAJOR)
-  {
-   fhandler_base *fh = cfd;
-   fhandler_pty_slave *ptys = (fhandler_pty_slave *) fh;
-   if (h == ptys->get_handle ())
- ptys->set_switch_to_pcon ();
-   return;
-  }
+{
+  if (*in == cfd->get_handle () ||
+ (fd == 0 && *in == GetStdHandle (STD_INPUT_HANDLE)))
+   replace_in = (fhandler_base *) cfd;
+  if (*out == cfd->get_output_handle () ||
+ (fd == 1 && *out == GetStdHandle (STD_OUTPUT_HANDLE)))
+   replace_out = (fhandler_base *) cfd;
+  if (*err == cfd->get_output_handle () ||
+ (fd == 2 && *err == GetStdHandle (STD_ERROR_HANDLE)))
+   replace_err = (fhandler_base *) cfd;
+  if (cfd->get_major () == DEV_PTYS_MAJOR)
+   {
+ fhandler_base *fh = cfd;
+ fhandler_pty_slave *ptys = (fhandler_pty_slave *) fh;
+ if (*in == ptys->get_handle ())
+   ptys_pcon = ptys;
+   }
+}
+  if (!iscygwin && ptys_pcon)
+ptys_pcon->set_switch_to_pcon ();
+  if (replace_in)
+{
+  if (iscygwin && ptys_pcon->pcon_activated ())
+   *in = replace_in->get_handle_cyg ();
+  else
+   *in = replace_in->get_handle ();
+}
+  if (replace_out)
+*out = replace_out->get_output_handle ();
+  if (replace_err)
+*err = replace_err->get_output_handle ();
 }
 
 #define DEF_HOOK(name) static __typeof__ (name) *name##_Orig
@@ -115,16 +142,55 @@ CreateProcessA_Hooked
   BOOL inh, DWORD f, LPVOID e, LPCSTR d,
   LPSTARTUPINFOA si, LPPROCESS_INFORMATION pi)
 {
-  HANDLE h;
-  if (!isHybrid)
+  STARTUPINFOEXA siex = {0, };
+  if (si->cb == sizeof (STARTUPINFOEXA))
+siex = *(STARTUPINFOEXA *)si;
+  else
+siex.StartupInfo = *si;
+  STARTUPINFOA *siov = &siex.StartupInfo;
+  if (!(si->dwFlags & STARTF_USESTDHANDLES))
 {
-  if (si->dwFlags & STARTF_USESTDHANDLES)
-   h = si->hStdInput;
-  else
-   h = GetStdHandle (STD_INPUT_HANDLE);
-  set_switch_to_pcon (h);
+  siov->dwFlags |= STARTF_USESTDHANDLES;
+  siov->hStdInput = GetStdHandle (STD_INPUT_HANDLE);
+  siov->hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);
+  siov->hStdError = GetStdHandle (STD_ERROR_HANDLE);
 }
-  retur

[PATCH v6 2/4] Cygwin: pty: Keep code page between non-cygwin apps.

2021-01-26 Thread Takashi Yano via Cygwin-patches
- After commit bb428520, there has been the disadvantage:
  4) Code page cannot be changed by chcp.com. Acctually, chcp works
 itself and changes code page of its own pseudo console.  However,
 since pseudo console is recreated for another process, it cannot
 inherit the code page.
  This patch clears this disadvantage.
---
 winsup/cygwin/fhandler_tty.cc | 7 +++
 winsup/cygwin/tty.cc  | 2 ++
 winsup/cygwin/tty.h   | 2 ++
 3 files changed, 11 insertions(+)

diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index f0b2cd60a..34cff2ae5 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -2845,6 +2845,11 @@ fhandler_pty_slave::setup_pseudoconsole (bool nopcon)
   HPCON_INTERNAL *hp = (HPCON_INTERNAL *) get_ttyp ()->h_pseudo_console;
   get_ttyp ()->h_pcon_write_pipe = hp->hWritePipe;
 }
+
+  if (get_ttyp ()->previous_code_page)
+SetConsoleCP (get_ttyp ()->previous_code_page);
+  if (get_ttyp ()->previous_output_code_page)
+SetConsoleOutputCP (get_ttyp ()->previous_output_code_page);
   return true;
 
 cleanup_pcon_in:
@@ -2884,6 +2889,8 @@ fhandler_pty_slave::close_pseudoconsole (tty *ttyp)
   if (ttyp->h_pseudo_console)
 {
   ttyp->wait_pcon_fwd ();
+  ttyp->previous_code_page = GetConsoleCP ();
+  ttyp->previous_output_code_page = GetConsoleOutputCP ();
   FreeConsole ();
   AttachConsole (ATTACH_PARENT_PROCESS);
   HPCON_INTERNAL *hp = (HPCON_INTERNAL *) ttyp->h_pseudo_console;
diff --git a/winsup/cygwin/tty.cc b/winsup/cygwin/tty.cc
index 436f5c6c3..908166a37 100644
--- a/winsup/cygwin/tty.cc
+++ b/winsup/cygwin/tty.cc
@@ -246,6 +246,8 @@ tty::init ()
   has_csi6n = false;
   need_invisible_console = false;
   invisible_console_pid = 0;
+  previous_code_page = 0;
+  previous_output_code_page = 0;
 }
 
 HANDLE
diff --git a/winsup/cygwin/tty.h b/winsup/cygwin/tty.h
index eb604588c..061357437 100644
--- a/winsup/cygwin/tty.h
+++ b/winsup/cygwin/tty.h
@@ -107,6 +107,8 @@ private:
   bool has_csi6n;
   bool need_invisible_console;
   pid_t invisible_console_pid;
+  UINT previous_code_page;
+  UINT previous_output_code_page;
 
 public:
   HANDLE from_master () const { return _from_master; }
-- 
2.30.0



[PATCH v6 1/4] Cygwin: pty: Inherit typeahead data between two input pipes.

2021-01-26 Thread Takashi Yano via Cygwin-patches
- PTY has a problem that the key input, which is typed during windows
  native app is running, disappears when it returns to shell. This is
  beacuse pty has two input pipes, one is for cygwin apps and the other
  one is for native windows apps. The key input during windows native
  program is running is sent to the second input pipe while cygwin
  shell reads input from the first input pipe. This issue had been
  fixed once by commit 29431fcb, however, the new implementation of
  pseudo console support by commit bb428520 could not inherit this
  feature. This patch realize transfering input data between these
  two pipes bidirectionally by utilizing cygwin-console-helper process.
  The helper process is launched prior to starting the non-cygwin app,
  however, exits immediately unlike previous implementation.
---
 winsup/cygwin/fhandler.h  |  14 +-
 winsup/cygwin/fhandler_tty.cc | 545 +++---
 winsup/cygwin/spawn.cc|  82 +++--
 winsup/cygwin/tty.cc  |   2 -
 winsup/cygwin/tty.h   |   8 +-
 5 files changed, 504 insertions(+), 147 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index af1ef3a45..378e9c13b 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -2291,6 +2291,13 @@ class fhandler_pty_slave: public fhandler_pty_common
   void fch_close_handles ();
 
  public:
+  /* Transfer direction for transfer_input() */
+  enum xfer_dir
+  {
+to_nat,
+to_cyg
+  };
+
   /* Constructor */
   fhandler_pty_slave (int);
 
@@ -2340,7 +2347,7 @@ class fhandler_pty_slave: public fhandler_pty_common
 copyto (fh);
 return fh;
   }
-  bool setup_pseudoconsole (STARTUPINFOEXW *si, bool nopcon);
+  bool setup_pseudoconsole (bool nopcon);
   static void close_pseudoconsole (tty *ttyp);
   bool term_has_pcon_cap (const WCHAR *env);
   void set_switch_to_pcon (void);
@@ -2349,6 +2356,9 @@ class fhandler_pty_slave: public fhandler_pty_common
   void setup_locale (void);
   tty *get_ttyp () { return (tty *) tc (); } /* Override as public */
   void create_invisible_console (void);
+  static void transfer_input (xfer_dir dir, HANDLE from, tty *ttyp,
+ _minor_t unit, HANDLE input_available_event);
+  HANDLE get_input_available_event (void) { return input_available_event; }
 };
 
 #define __ptsname(buf, unit) __small_sprintf ((buf), "/dev/pty%d", (unit))
@@ -2361,6 +2371,8 @@ public:
 HANDLE from_master_cyg;
 HANDLE to_master;
 HANDLE to_master_cyg;
+HANDLE to_slave;
+HANDLE to_slave_cyg;
 HANDLE master_ctl;
 HANDLE input_available_event;
   };
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 7f0752614..f0b2cd60a 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -56,6 +56,8 @@ struct pipe_reply {
   HANDLE from_master_cyg;
   HANDLE to_master;
   HANDLE to_master_cyg;
+  HANDLE to_slave;
+  HANDLE to_slave_cyg;
   DWORD error;
 };
 
@@ -848,8 +850,14 @@ fhandler_pty_slave::reset_switch_to_pcon (void)
 return;
   if (isHybrid)
 return;
+  if (get_ttyp ()->switch_to_pcon_in && !get_ttyp ()->h_pseudo_console)
+fhandler_pty_slave::transfer_input (fhandler_pty_slave::to_cyg,
+   get_handle (),
+   get_ttyp (), get_minor (),
+   input_available_event);
   get_ttyp ()->pcon_pid = 0;
   get_ttyp ()->switch_to_pcon_in = false;
+  get_ttyp ()->h_pseudo_console = NULL;
 }
 
 ssize_t __stdcall
@@ -891,6 +899,22 @@ fhandler_pty_slave::write (const void *ptr, size_t len)
 void
 fhandler_pty_slave::mask_switch_to_pcon_in (bool mask)
 {
+  if (get_ttyp ()->switch_to_pcon_in
+  && (get_ttyp ()->pcon_pid == myself->pid
+ || !get_ttyp ()->h_pseudo_console)
+  && get_ttyp ()->mask_switch_to_pcon_in != mask)
+{
+  if (mask)
+   fhandler_pty_slave::transfer_input (fhandler_pty_slave::to_cyg,
+   get_handle (),
+   get_ttyp (), get_minor (),
+   input_available_event);
+  else
+   fhandler_pty_slave::transfer_input (fhandler_pty_slave::to_nat,
+   get_handle_cyg (),
+   get_ttyp (), get_minor (),
+   input_available_event);
+}
   get_ttyp ()->mask_switch_to_pcon_in = mask;
 }
 
@@ -1591,7 +1615,7 @@ fhandler_pty_common::resize_pseudo_console (struct 
winsize *ws)
   size.X = ws->ws_col;
   size.Y = ws->ws_row;
   pinfo p (get_ttyp ()->pcon_pid);
-  if (p && !get_ttyp ()->do_not_resize_pcon)
+  if (p)
 {
   HPCON_INTERNAL hpcon_local;
   HANDLE pcon_owner =
@@ -1763,6 +1787,17 @@ fhandler_pty_master::write (const void *ptr, size_t len)
  get_ttyp ()->pcon_start = false;
}
  ReleaseM

[PATCH v6 0/4] Improve pseudo console support.

2021-01-26 Thread Takashi Yano via Cygwin-patches
The new implementation of pseudo console support by commit bb428520
provides the important advantages, while there also has been several
disadvantages compared to the previous implementation.

These patches overturn some of them.

The disadvantage:
 1) The cygwin program which calls console API directly does not work.
is supposed to be able to be overcome as well, however, I am not sure
it is worth enough. This will need a lot of hooks for console APIs.
 --> Respecting Corinna's opinion, we decided not to implement this.

v3: Fix typeahead input issue in GDB. Several other bugs have also
been fixed.
v4: Change the conditions for calling transfer_input() slightly in
reset_switch_to_pcon() to avoid calling it if uncecessary or
with no effect.
v5: Small bug fix in v4.
v6: Yet another bug fix.
Add missing CloseHandle().
Take into account when the master is running as a service (such
as ssh session).

Takashi Yano (4):
  Cygwin: pty: Inherit typeahead data between two input pipes.
  Cygwin: pty: Keep code page between non-cygwin apps.
  Cygwin: pty: Make apps using console APIs be able to debug with gdb.
  Cygwin: pty: Allow multiple apps to enable pseudo console
simultaneously.

 winsup/cygwin/fhandler.h  |   23 +-
 winsup/cygwin/fhandler_tty.cc | 1120 +++--
 winsup/cygwin/select.cc   |7 +-
 winsup/cygwin/spawn.cc|  106 +++-
 winsup/cygwin/tty.cc  |   13 +-
 winsup/cygwin/tty.h   |   21 +-
 6 files changed, 1058 insertions(+), 232 deletions(-)

-- 
2.30.0



Re: [PATCH v5 0/4] Improve pseudo console support.

2021-01-26 Thread Takashi Yano via Cygwin-patches
On Tue, 26 Jan 2021 12:52:25 +0900
Takashi Yano wrote:
> The new implementation of pseudo console support by commit bb428520
> provides the important advantages, while there also has been several
> disadvantages compared to the previous implementation.
> 
> These patches overturn some of them.
> 
> The disadvantage:
>  1) The cygwin program which calls console API directly does not work.
> is supposed to be able to be overcome as well, however, I am not sure
> it is worth enough. This will need a lot of hooks for console APIs.
>  --> Respecting Corinna's opinion, we decided not to implement this.
> 
> v3: Fix typeahead input issue in GDB. Several other bugs have also
> been fixed.
> v4: Change the conditions for calling transfer_input() slightly in
> reset_switch_to_pcon() to avoid calling it if uncecessary or
> with no effect.
> v5: Small bug fix in v4.

I have another fix for v5. Please wait for v6.

-- 
Takashi Yano 


[PATCH v5 4/4] Cygwin: pty: Allow multiple apps to enable pseudo console simultaneously.

2021-01-25 Thread Takashi Yano via Cygwin-patches
- After commit bb428520, there has been the disadvantage:
  7) Pseudo console cannot be activated if it is already activated for
 another process on same pty.
  This patch clears this disadvantage.
---
 winsup/cygwin/fhandler.h  |   7 +-
 winsup/cygwin/fhandler_tty.cc | 346 ++
 winsup/cygwin/select.cc   |   4 +-
 winsup/cygwin/spawn.cc|  40 ++--
 winsup/cygwin/tty.cc  |   2 +-
 winsup/cygwin/tty.h   |   6 +-
 6 files changed, 313 insertions(+), 92 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index dcdf65292..9472cf504 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -2273,6 +2273,9 @@ class fhandler_pty_common: public fhandler_termios
   }
 
   void resize_pseudo_console (struct winsize *);
+  static DWORD get_console_process_id (DWORD pid, bool match,
+  bool cygwin = false,
+  bool stub_only = false);
 
  protected:
   static BOOL process_opost_output (HANDLE h, const void *ptr, ssize_t& len,
@@ -2352,14 +2355,14 @@ class fhandler_pty_slave: public fhandler_pty_common
   bool term_has_pcon_cap (const WCHAR *env);
   void set_switch_to_pcon (void);
   void reset_switch_to_pcon (void);
-  bool mask_switch_to_pcon_in (bool mask);
+  bool mask_switch_to_pcon_in (bool mask, bool xfer);
   void setup_locale (void);
   tty *get_ttyp () { return (tty *) tc (); } /* Override as public */
   void create_invisible_console (void);
   static void transfer_input (xfer_dir dir, HANDLE from, tty *ttyp,
  HANDLE input_available_event);
   HANDLE get_input_available_event (void) { return input_available_event; }
-  bool pcon_activated (void) { return get_ttyp ()->h_pseudo_console; }
+  bool pcon_activated (void) { return get_ttyp ()->pcon_activated; }
 };
 
 #define __ptsname(buf, unit) __small_sprintf ((buf), "/dev/pty%d", (unit))
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 09e5b3e97..c2a39cd41 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -62,8 +62,9 @@ struct pipe_reply {
 
 extern HANDLE attach_mutex; /* Defined in fhandler_console.cc */
 
-static DWORD
-get_console_process_id (DWORD pid, bool match)
+DWORD
+fhandler_pty_common::get_console_process_id (DWORD pid, bool match,
+bool cygwin, bool stub_only)
 {
   tmp_pathbuf tp;
   DWORD *list = (DWORD *) tp.c_get ();
@@ -73,16 +74,34 @@ get_console_process_id (DWORD pid, bool match)
   if (num == 0 || num > buf_size)
 return 0;
 
-  DWORD res = 0;
+  DWORD res_pri = 0, res = 0;
   /* Last one is the oldest. */
   /* https://github.com/microsoft/terminal/issues/95 */
   for (int i = (int) num - 1; i >= 0; i--)
 if ((match && list[i] == pid) || (!match && list[i] != pid))
   {
-   res = list[i];
-   break;
+   if (!cygwin)
+ {
+   res_pri = list[i];
+   break;
+ }
+   else
+ {
+   pinfo p (cygwin_pid (list[i]));
+   if (!!p && p->dwProcessId && p->exec_dwProcessId
+   && p->dwProcessId != p->exec_dwProcessId)
+ {
+   res_pri = list[i];
+   break;
+ }
+   if (!!p && !res)
+ res = list[i];
+ }
   }
-  return res;
+  if (stub_only)
+return res_pri;
+  else
+return res_pri ?: res;
 }
 
 static bool isHybrid;
@@ -935,7 +954,7 @@ fhandler_pty_slave::init (HANDLE h, DWORD a, mode_t)
 void
 fhandler_pty_slave::set_switch_to_pcon (void)
 {
-  if (!get_ttyp ()->switch_to_pcon_in)
+  if (!isHybrid)
 {
   isHybrid = true;
   setup_locale ();
@@ -951,10 +970,6 @@ fhandler_pty_slave::set_switch_to_pcon (void)
 void
 fhandler_pty_slave::reset_switch_to_pcon (void)
 {
-  if (get_ttyp ()->pcon_pid && get_ttyp ()->pcon_pid != myself->pid
-  && !!pinfo (get_ttyp ()->pcon_pid))
-/* There is a process which is grabbing pseudo console. */
-return;
   if (h_gdb_process)
 {
   if (WaitForSingleObject (h_gdb_process, 0) == WAIT_TIMEOUT)
@@ -976,7 +991,7 @@ fhandler_pty_slave::reset_switch_to_pcon (void)
  HANDLE pty_owner = NULL;
  if (p)
pty_owner = OpenProcess (PROCESS_DUP_HANDLE, FALSE, p->dwProcessId);
- if (pty_owner && get_ttyp ()->pcon_pid == myself->pid)
+ if (pty_owner)
{
  close_pseudoconsole (get_ttyp ());
  bool fixin, fixout, fixerr;
@@ -997,23 +1012,25 @@ fhandler_pty_slave::reset_switch_to_pcon (void)
SetStdHandle (STD_OUTPUT_HANDLE, get_output_handle ());
  if (fixerr)
SetStdHandle (STD_ERROR_HANDLE, get_output_handle ());
+ isHybrid = false;
}
- isHybrid = false;
- get_ttyp ()->pcon_pid = 0;
- get_ttyp ()->switch_to_pcon_in = false;
  return;
}
   

[PATCH v5 3/4] Cygwin: pty: Make apps using console APIs be able to debug with gdb.

2021-01-25 Thread Takashi Yano via Cygwin-patches
- After commit bb428520, there has been the disadvantage:
  2) The apps which use console API cannot be debugged with gdb. This
 is because pseudo console is not activated since gdb uses
 CreateProcess() rather than exec(). Even with this limitation,
 attaching gdb to native app, in which pseudo console is already
 activated, works.
  This patch clears this disadvantage.
---
 winsup/cygwin/fhandler.h  |   3 +-
 winsup/cygwin/fhandler_tty.cc | 236 +-
 winsup/cygwin/select.cc   |  18 ++-
 winsup/cygwin/select.h|   8 +-
 winsup/cygwin/spawn.cc|   2 +
 winsup/cygwin/tty.cc  |   5 +-
 winsup/cygwin/tty.h   |   2 +-
 7 files changed, 226 insertions(+), 48 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 10c5973dd..dcdf65292 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -2352,13 +2352,14 @@ class fhandler_pty_slave: public fhandler_pty_common
   bool term_has_pcon_cap (const WCHAR *env);
   void set_switch_to_pcon (void);
   void reset_switch_to_pcon (void);
-  void mask_switch_to_pcon_in (bool mask);
+  bool mask_switch_to_pcon_in (bool mask);
   void setup_locale (void);
   tty *get_ttyp () { return (tty *) tc (); } /* Override as public */
   void create_invisible_console (void);
   static void transfer_input (xfer_dir dir, HANDLE from, tty *ttyp,
  HANDLE input_available_event);
   HANDLE get_input_available_event (void) { return input_available_event; }
+  bool pcon_activated (void) { return get_ttyp ()->h_pseudo_console; }
 };
 
 #define __ptsname(buf, unit) __small_sprintf ((buf), "/dev/pty%d", (unit))
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index cd6b71620..09e5b3e97 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -27,6 +27,7 @@ details. */
 #include "cygwait.h"
 #include "registry.h"
 #include "tls_pbuf.h"
+#include "winf.h"
 
 #ifndef PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE
 #define PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE 0x00020016
@@ -85,21 +86,47 @@ get_console_process_id (DWORD pid, bool match)
 }
 
 static bool isHybrid;
+static HANDLE h_gdb_process;
 
 static void
-set_switch_to_pcon (HANDLE h)
+set_switch_to_pcon (HANDLE *in, HANDLE *out, HANDLE *err, bool iscygwin)
 {
   cygheap_fdenum cfd (false);
   int fd;
+  fhandler_base *replace_in = NULL, *replace_out = NULL, *replace_err = NULL;
+  fhandler_pty_slave *ptys_pcon = NULL;
   while ((fd = cfd.next ()) >= 0)
-if (cfd->get_major () == DEV_PTYS_MAJOR)
-  {
-   fhandler_base *fh = cfd;
-   fhandler_pty_slave *ptys = (fhandler_pty_slave *) fh;
-   if (h == ptys->get_handle ())
- ptys->set_switch_to_pcon ();
-   return;
-  }
+{
+  if (*in == cfd->get_handle () ||
+ (fd == 0 && *in == GetStdHandle (STD_INPUT_HANDLE)))
+   replace_in = (fhandler_base *) cfd;
+  if (*out == cfd->get_output_handle () ||
+ (fd == 1 && *out == GetStdHandle (STD_OUTPUT_HANDLE)))
+   replace_out = (fhandler_base *) cfd;
+  if (*err == cfd->get_output_handle () ||
+ (fd == 2 && *err == GetStdHandle (STD_ERROR_HANDLE)))
+   replace_err = (fhandler_base *) cfd;
+  if (cfd->get_major () == DEV_PTYS_MAJOR)
+   {
+ fhandler_base *fh = cfd;
+ fhandler_pty_slave *ptys = (fhandler_pty_slave *) fh;
+ if (*in == ptys->get_handle ())
+   ptys_pcon = ptys;
+   }
+}
+  if (!iscygwin && ptys_pcon)
+ptys_pcon->set_switch_to_pcon ();
+  if (replace_in)
+{
+  if (iscygwin && ptys_pcon->pcon_activated ())
+   *in = replace_in->get_handle_cyg ();
+  else
+   *in = replace_in->get_handle ();
+}
+  if (replace_out)
+*out = replace_out->get_output_handle ();
+  if (replace_err)
+*err = replace_err->get_output_handle ();
 }
 
 #define DEF_HOOK(name) static __typeof__ (name) *name##_Orig
@@ -113,16 +140,55 @@ CreateProcessA_Hooked
   BOOL inh, DWORD f, LPVOID e, LPCSTR d,
   LPSTARTUPINFOA si, LPPROCESS_INFORMATION pi)
 {
-  HANDLE h;
-  if (!isHybrid)
+  STARTUPINFOEXA siex = {0, };
+  if (si->cb == sizeof (STARTUPINFOEXA))
+siex = *(STARTUPINFOEXA *)si;
+  else
+siex.StartupInfo = *si;
+  STARTUPINFOA *siov = &siex.StartupInfo;
+  if (!(si->dwFlags & STARTF_USESTDHANDLES))
 {
-  if (si->dwFlags & STARTF_USESTDHANDLES)
-   h = si->hStdInput;
-  else
-   h = GetStdHandle (STD_INPUT_HANDLE);
-  set_switch_to_pcon (h);
+  siov->dwFlags |= STARTF_USESTDHANDLES;
+  siov->hStdInput = GetStdHandle (STD_INPUT_HANDLE);
+  siov->hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);
+  siov->hStdError = GetStdHandle (STD_ERROR_HANDLE);
 }
-  return CreateProcessA_Orig (n, c, pa, ta, inh, f, e, d, si, pi);
+  path_conv path;
+  tmp_pathbuf tp;
+  char *prog =tp.c_get ();
+  if (n)
+__small_sprintf (prog, "%s", n);
+  else
+{
+  __small_spri

[PATCH v5 2/4] Cygwin: pty: Keep code page between non-cygwin apps.

2021-01-25 Thread Takashi Yano via Cygwin-patches
- After commit bb428520, there has been the disadvantage:
  4) Code page cannot be changed by chcp.com. Acctually, chcp works
 itself and changes code page of its own pseudo console.  However,
 since pseudo console is recreated for another process, it cannot
 inherit the code page.
  This patch clears this disadvantage.
---
 winsup/cygwin/fhandler_tty.cc | 7 +++
 winsup/cygwin/tty.cc  | 2 ++
 winsup/cygwin/tty.h   | 2 ++
 3 files changed, 11 insertions(+)

diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index def2fe150..cd6b71620 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -2829,6 +2829,11 @@ fhandler_pty_slave::setup_pseudoconsole (bool nopcon)
   HPCON_INTERNAL *hp = (HPCON_INTERNAL *) get_ttyp ()->h_pseudo_console;
   get_ttyp ()->h_pcon_write_pipe = hp->hWritePipe;
 }
+
+  if (get_ttyp ()->previous_code_page)
+SetConsoleCP (get_ttyp ()->previous_code_page);
+  if (get_ttyp ()->previous_output_code_page)
+SetConsoleOutputCP (get_ttyp ()->previous_output_code_page);
   return true;
 
 cleanup_pcon_in:
@@ -2868,6 +2873,8 @@ fhandler_pty_slave::close_pseudoconsole (tty *ttyp)
   if (ttyp->h_pseudo_console)
 {
   ttyp->wait_pcon_fwd ();
+  ttyp->previous_code_page = GetConsoleCP ();
+  ttyp->previous_output_code_page = GetConsoleOutputCP ();
   FreeConsole ();
   AttachConsole (ATTACH_PARENT_PROCESS);
   HPCON_INTERNAL *hp = (HPCON_INTERNAL *) ttyp->h_pseudo_console;
diff --git a/winsup/cygwin/tty.cc b/winsup/cygwin/tty.cc
index 436f5c6c3..908166a37 100644
--- a/winsup/cygwin/tty.cc
+++ b/winsup/cygwin/tty.cc
@@ -246,6 +246,8 @@ tty::init ()
   has_csi6n = false;
   need_invisible_console = false;
   invisible_console_pid = 0;
+  previous_code_page = 0;
+  previous_output_code_page = 0;
 }
 
 HANDLE
diff --git a/winsup/cygwin/tty.h b/winsup/cygwin/tty.h
index eb604588c..061357437 100644
--- a/winsup/cygwin/tty.h
+++ b/winsup/cygwin/tty.h
@@ -107,6 +107,8 @@ private:
   bool has_csi6n;
   bool need_invisible_console;
   pid_t invisible_console_pid;
+  UINT previous_code_page;
+  UINT previous_output_code_page;
 
 public:
   HANDLE from_master () const { return _from_master; }
-- 
2.30.0



[PATCH v5 1/4] Cygwin: pty: Inherit typeahead data between two input pipes.

2021-01-25 Thread Takashi Yano via Cygwin-patches
- PTY has a problem that the key input, which is typed during windows
  native app is running, disappears when it returns to shell. This is
  beacuse pty has two input pipes, one is for cygwin apps and the other
  one is for native windows apps. The key input during windows native
  program is running is sent to the second input pipe while cygwin
  shell reads input from the first input pipe. This issue had been
  fixed once by commit 29431fcb, however, the new implementation of
  pseudo console support by commit bb428520 could not inherit this
  feature. This patch realize transfering input data between these
  two pipes bidirectionally by utilizing cygwin-console-helper process.
  The helper process is launched prior to starting the non-cygwin app,
  however, exits immediately unlike previous implementation.
---
 winsup/cygwin/fhandler.h  |  12 +-
 winsup/cygwin/fhandler_tty.cc | 504 ++
 winsup/cygwin/spawn.cc|  78 --
 winsup/cygwin/tty.cc  |   2 -
 winsup/cygwin/tty.h   |   8 +-
 5 files changed, 458 insertions(+), 146 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index af1ef3a45..10c5973dd 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -2291,6 +2291,13 @@ class fhandler_pty_slave: public fhandler_pty_common
   void fch_close_handles ();
 
  public:
+  /* Transfer direction for transfer_input() */
+  enum xfer_dir
+  {
+to_nat,
+to_cyg
+  };
+
   /* Constructor */
   fhandler_pty_slave (int);
 
@@ -2340,7 +2347,7 @@ class fhandler_pty_slave: public fhandler_pty_common
 copyto (fh);
 return fh;
   }
-  bool setup_pseudoconsole (STARTUPINFOEXW *si, bool nopcon);
+  bool setup_pseudoconsole (bool nopcon);
   static void close_pseudoconsole (tty *ttyp);
   bool term_has_pcon_cap (const WCHAR *env);
   void set_switch_to_pcon (void);
@@ -2349,6 +2356,9 @@ class fhandler_pty_slave: public fhandler_pty_common
   void setup_locale (void);
   tty *get_ttyp () { return (tty *) tc (); } /* Override as public */
   void create_invisible_console (void);
+  static void transfer_input (xfer_dir dir, HANDLE from, tty *ttyp,
+ HANDLE input_available_event);
+  HANDLE get_input_available_event (void) { return input_available_event; }
 };
 
 #define __ptsname(buf, unit) __small_sprintf ((buf), "/dev/pty%d", (unit))
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 7f0752614..def2fe150 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -848,8 +848,14 @@ fhandler_pty_slave::reset_switch_to_pcon (void)
 return;
   if (isHybrid)
 return;
+  if (get_ttyp ()->switch_to_pcon_in && !get_ttyp ()->h_pseudo_console)
+fhandler_pty_slave::transfer_input (fhandler_pty_slave::to_cyg,
+   get_handle (),
+   get_ttyp (),
+   input_available_event);
   get_ttyp ()->pcon_pid = 0;
   get_ttyp ()->switch_to_pcon_in = false;
+  get_ttyp ()->h_pseudo_console = NULL;
 }
 
 ssize_t __stdcall
@@ -891,6 +897,22 @@ fhandler_pty_slave::write (const void *ptr, size_t len)
 void
 fhandler_pty_slave::mask_switch_to_pcon_in (bool mask)
 {
+  if (get_ttyp ()->switch_to_pcon_in
+  && (get_ttyp ()->pcon_pid == myself->pid
+ || !get_ttyp ()->h_pseudo_console)
+  && get_ttyp ()->mask_switch_to_pcon_in != mask)
+{
+  if (mask)
+   fhandler_pty_slave::transfer_input (fhandler_pty_slave::to_cyg,
+   get_handle (),
+   get_ttyp (),
+   input_available_event);
+  else
+   fhandler_pty_slave::transfer_input (fhandler_pty_slave::to_nat,
+   get_handle_cyg (),
+   get_ttyp (),
+   input_available_event);
+}
   get_ttyp ()->mask_switch_to_pcon_in = mask;
 }
 
@@ -1591,7 +1613,7 @@ fhandler_pty_common::resize_pseudo_console (struct 
winsize *ws)
   size.X = ws->ws_col;
   size.Y = ws->ws_row;
   pinfo p (get_ttyp ()->pcon_pid);
-  if (p && !get_ttyp ()->do_not_resize_pcon)
+  if (p)
 {
   HPCON_INTERNAL hpcon_local;
   HANDLE pcon_owner =
@@ -1763,6 +1785,17 @@ fhandler_pty_master::write (const void *ptr, size_t len)
  get_ttyp ()->pcon_start = false;
}
  ReleaseMutex (input_mutex);
+ if (get_ttyp ()->switch_to_pcon_in)
+   {
+ fhandler_pty_slave::transfer_input (fhandler_pty_slave::to_nat,
+ from_master_cyg,
+ get_ttyp (),
+ input_available_event);
+ /* This accept_input() call is needed in order to transfer input
+ 

[PATCH v5 0/4] Improve pseudo console support.

2021-01-25 Thread Takashi Yano via Cygwin-patches
The new implementation of pseudo console support by commit bb428520
provides the important advantages, while there also has been several
disadvantages compared to the previous implementation.

These patches overturn some of them.

The disadvantage:
 1) The cygwin program which calls console API directly does not work.
is supposed to be able to be overcome as well, however, I am not sure
it is worth enough. This will need a lot of hooks for console APIs.
 --> Respecting Corinna's opinion, we decided not to implement this.

v3: Fix typeahead input issue in GDB. Several other bugs have also
been fixed.
v4: Change the conditions for calling transfer_input() slightly in
reset_switch_to_pcon() to avoid calling it if uncecessary or
with no effect.
v5: Small bug fix in v4.

Takashi Yano (4):
  Cygwin: pty: Inherit typeahead data between two input pipes.
  Cygwin: pty: Keep code page between non-cygwin apps.
  Cygwin: pty: Make apps using console APIs be able to debug with gdb.
  Cygwin: pty: Allow multiple apps to enable pseudo console
simultaneously.

 winsup/cygwin/fhandler.h  |   18 +-
 winsup/cygwin/fhandler_tty.cc | 1017 +++--
 winsup/cygwin/select.cc   |   18 +-
 winsup/cygwin/select.h|8 +-
 winsup/cygwin/spawn.cc|  102 ++--
 winsup/cygwin/tty.cc  |   11 +-
 winsup/cygwin/tty.h   |   18 +-
 7 files changed, 957 insertions(+), 235 deletions(-)

-- 
2.30.0



[PATCH v4 4/4] Cygwin: pty: Allow multiple apps to enable pseudo console simultaneously.

2021-01-25 Thread Takashi Yano via Cygwin-patches
- After commit bb428520, there has been the disadvantage:
  7) Pseudo console cannot be activated if it is already activated for
 another process on same pty.
  This patch clears this disadvantage.
---
 winsup/cygwin/fhandler.h  |   7 +-
 winsup/cygwin/fhandler_tty.cc | 346 ++
 winsup/cygwin/select.cc   |   4 +-
 winsup/cygwin/spawn.cc|  40 ++--
 winsup/cygwin/tty.cc  |   2 +-
 winsup/cygwin/tty.h   |   6 +-
 6 files changed, 313 insertions(+), 92 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index dcdf65292..9472cf504 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -2273,6 +2273,9 @@ class fhandler_pty_common: public fhandler_termios
   }
 
   void resize_pseudo_console (struct winsize *);
+  static DWORD get_console_process_id (DWORD pid, bool match,
+  bool cygwin = false,
+  bool stub_only = false);
 
  protected:
   static BOOL process_opost_output (HANDLE h, const void *ptr, ssize_t& len,
@@ -2352,14 +2355,14 @@ class fhandler_pty_slave: public fhandler_pty_common
   bool term_has_pcon_cap (const WCHAR *env);
   void set_switch_to_pcon (void);
   void reset_switch_to_pcon (void);
-  bool mask_switch_to_pcon_in (bool mask);
+  bool mask_switch_to_pcon_in (bool mask, bool xfer);
   void setup_locale (void);
   tty *get_ttyp () { return (tty *) tc (); } /* Override as public */
   void create_invisible_console (void);
   static void transfer_input (xfer_dir dir, HANDLE from, tty *ttyp,
  HANDLE input_available_event);
   HANDLE get_input_available_event (void) { return input_available_event; }
-  bool pcon_activated (void) { return get_ttyp ()->h_pseudo_console; }
+  bool pcon_activated (void) { return get_ttyp ()->pcon_activated; }
 };
 
 #define __ptsname(buf, unit) __small_sprintf ((buf), "/dev/pty%d", (unit))
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 878cf59b6..0b7aae1bb 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -62,8 +62,9 @@ struct pipe_reply {
 
 extern HANDLE attach_mutex; /* Defined in fhandler_console.cc */
 
-static DWORD
-get_console_process_id (DWORD pid, bool match)
+DWORD
+fhandler_pty_common::get_console_process_id (DWORD pid, bool match,
+bool cygwin, bool stub_only)
 {
   tmp_pathbuf tp;
   DWORD *list = (DWORD *) tp.c_get ();
@@ -73,16 +74,34 @@ get_console_process_id (DWORD pid, bool match)
   if (num == 0 || num > buf_size)
 return 0;
 
-  DWORD res = 0;
+  DWORD res_pri = 0, res = 0;
   /* Last one is the oldest. */
   /* https://github.com/microsoft/terminal/issues/95 */
   for (int i = (int) num - 1; i >= 0; i--)
 if ((match && list[i] == pid) || (!match && list[i] != pid))
   {
-   res = list[i];
-   break;
+   if (!cygwin)
+ {
+   res_pri = list[i];
+   break;
+ }
+   else
+ {
+   pinfo p (cygwin_pid (list[i]));
+   if (!!p && p->dwProcessId && p->exec_dwProcessId
+   && p->dwProcessId != p->exec_dwProcessId)
+ {
+   res_pri = list[i];
+   break;
+ }
+   if (!!p && !res)
+ res = list[i];
+ }
   }
-  return res;
+  if (stub_only)
+return res_pri;
+  else
+return res_pri ?: res;
 }
 
 static bool isHybrid;
@@ -935,7 +954,7 @@ fhandler_pty_slave::init (HANDLE h, DWORD a, mode_t)
 void
 fhandler_pty_slave::set_switch_to_pcon (void)
 {
-  if (!get_ttyp ()->switch_to_pcon_in)
+  if (!isHybrid)
 {
   isHybrid = true;
   setup_locale ();
@@ -951,10 +970,6 @@ fhandler_pty_slave::set_switch_to_pcon (void)
 void
 fhandler_pty_slave::reset_switch_to_pcon (void)
 {
-  if (get_ttyp ()->pcon_pid && get_ttyp ()->pcon_pid != myself->pid
-  && !!pinfo (get_ttyp ()->pcon_pid))
-/* There is a process which is grabbing pseudo console. */
-return;
   if (h_gdb_process)
 {
   if (WaitForSingleObject (h_gdb_process, 0) == WAIT_TIMEOUT)
@@ -976,7 +991,7 @@ fhandler_pty_slave::reset_switch_to_pcon (void)
  HANDLE pty_owner = NULL;
  if (p)
pty_owner = OpenProcess (PROCESS_DUP_HANDLE, FALSE, p->dwProcessId);
- if (pty_owner && get_ttyp ()->pcon_pid == myself->pid)
+ if (pty_owner)
{
  close_pseudoconsole (get_ttyp ());
  bool fixin, fixout, fixerr;
@@ -997,23 +1012,25 @@ fhandler_pty_slave::reset_switch_to_pcon (void)
SetStdHandle (STD_OUTPUT_HANDLE, get_output_handle ());
  if (fixerr)
SetStdHandle (STD_ERROR_HANDLE, get_output_handle ());
+ isHybrid = false;
}
- isHybrid = false;
- get_ttyp ()->pcon_pid = 0;
- get_ttyp ()->switch_to_pcon_in = false;
  return;
}
   

[PATCH v4 3/4] Cygwin: pty: Make apps using console APIs be able to debug with gdb.

2021-01-25 Thread Takashi Yano via Cygwin-patches
- After commit bb428520, there has been the disadvantage:
  2) The apps which use console API cannot be debugged with gdb. This
 is because pseudo console is not activated since gdb uses
 CreateProcess() rather than exec(). Even with this limitation,
 attaching gdb to native app, in which pseudo console is already
 activated, works.
  This patch clears this disadvantage.
---
 winsup/cygwin/fhandler.h  |   3 +-
 winsup/cygwin/fhandler_tty.cc | 236 +-
 winsup/cygwin/select.cc   |  18 ++-
 winsup/cygwin/select.h|   8 +-
 winsup/cygwin/spawn.cc|   2 +
 winsup/cygwin/tty.cc  |   5 +-
 winsup/cygwin/tty.h   |   2 +-
 7 files changed, 226 insertions(+), 48 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 10c5973dd..dcdf65292 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -2352,13 +2352,14 @@ class fhandler_pty_slave: public fhandler_pty_common
   bool term_has_pcon_cap (const WCHAR *env);
   void set_switch_to_pcon (void);
   void reset_switch_to_pcon (void);
-  void mask_switch_to_pcon_in (bool mask);
+  bool mask_switch_to_pcon_in (bool mask);
   void setup_locale (void);
   tty *get_ttyp () { return (tty *) tc (); } /* Override as public */
   void create_invisible_console (void);
   static void transfer_input (xfer_dir dir, HANDLE from, tty *ttyp,
  HANDLE input_available_event);
   HANDLE get_input_available_event (void) { return input_available_event; }
+  bool pcon_activated (void) { return get_ttyp ()->h_pseudo_console; }
 };
 
 #define __ptsname(buf, unit) __small_sprintf ((buf), "/dev/pty%d", (unit))
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index cd6b71620..878cf59b6 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -27,6 +27,7 @@ details. */
 #include "cygwait.h"
 #include "registry.h"
 #include "tls_pbuf.h"
+#include "winf.h"
 
 #ifndef PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE
 #define PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE 0x00020016
@@ -85,21 +86,47 @@ get_console_process_id (DWORD pid, bool match)
 }
 
 static bool isHybrid;
+static HANDLE h_gdb_process;
 
 static void
-set_switch_to_pcon (HANDLE h)
+set_switch_to_pcon (HANDLE *in, HANDLE *out, HANDLE *err, bool iscygwin)
 {
   cygheap_fdenum cfd (false);
   int fd;
+  fhandler_base *replace_in = NULL, *replace_out = NULL, *replace_err = NULL;
+  fhandler_pty_slave *ptys_pcon = NULL;
   while ((fd = cfd.next ()) >= 0)
-if (cfd->get_major () == DEV_PTYS_MAJOR)
-  {
-   fhandler_base *fh = cfd;
-   fhandler_pty_slave *ptys = (fhandler_pty_slave *) fh;
-   if (h == ptys->get_handle ())
- ptys->set_switch_to_pcon ();
-   return;
-  }
+{
+  if (*in == cfd->get_handle () ||
+ (fd == 0 && *in == GetStdHandle (STD_INPUT_HANDLE)))
+   replace_in = (fhandler_base *) cfd;
+  if (*out == cfd->get_output_handle () ||
+ (fd == 1 && *out == GetStdHandle (STD_OUTPUT_HANDLE)))
+   replace_out = (fhandler_base *) cfd;
+  if (*err == cfd->get_output_handle () ||
+ (fd == 2 && *err == GetStdHandle (STD_ERROR_HANDLE)))
+   replace_err = (fhandler_base *) cfd;
+  if (cfd->get_major () == DEV_PTYS_MAJOR)
+   {
+ fhandler_base *fh = cfd;
+ fhandler_pty_slave *ptys = (fhandler_pty_slave *) fh;
+ if (*in == ptys->get_handle ())
+   ptys_pcon = ptys;
+   }
+}
+  if (!iscygwin && ptys_pcon)
+ptys_pcon->set_switch_to_pcon ();
+  if (replace_in)
+{
+  if (iscygwin && ptys_pcon->pcon_activated ())
+   *in = replace_in->get_handle_cyg ();
+  else
+   *in = replace_in->get_handle ();
+}
+  if (replace_out)
+*out = replace_out->get_output_handle ();
+  if (replace_err)
+*err = replace_err->get_output_handle ();
 }
 
 #define DEF_HOOK(name) static __typeof__ (name) *name##_Orig
@@ -113,16 +140,55 @@ CreateProcessA_Hooked
   BOOL inh, DWORD f, LPVOID e, LPCSTR d,
   LPSTARTUPINFOA si, LPPROCESS_INFORMATION pi)
 {
-  HANDLE h;
-  if (!isHybrid)
+  STARTUPINFOEXA siex = {0, };
+  if (si->cb == sizeof (STARTUPINFOEXA))
+siex = *(STARTUPINFOEXA *)si;
+  else
+siex.StartupInfo = *si;
+  STARTUPINFOA *siov = &siex.StartupInfo;
+  if (!(si->dwFlags & STARTF_USESTDHANDLES))
 {
-  if (si->dwFlags & STARTF_USESTDHANDLES)
-   h = si->hStdInput;
-  else
-   h = GetStdHandle (STD_INPUT_HANDLE);
-  set_switch_to_pcon (h);
+  siov->dwFlags |= STARTF_USESTDHANDLES;
+  siov->hStdInput = GetStdHandle (STD_INPUT_HANDLE);
+  siov->hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);
+  siov->hStdError = GetStdHandle (STD_ERROR_HANDLE);
 }
-  return CreateProcessA_Orig (n, c, pa, ta, inh, f, e, d, si, pi);
+  path_conv path;
+  tmp_pathbuf tp;
+  char *prog =tp.c_get ();
+  if (n)
+__small_sprintf (prog, "%s", n);
+  else
+{
+  __small_spri

[PATCH v4 2/4] Cygwin: pty: Keep code page between non-cygwin apps.

2021-01-25 Thread Takashi Yano via Cygwin-patches
- After commit bb428520, there has been the disadvantage:
  4) Code page cannot be changed by chcp.com. Acctually, chcp works
 itself and changes code page of its own pseudo console.  However,
 since pseudo console is recreated for another process, it cannot
 inherit the code page.
  This patch clears this disadvantage.
---
 winsup/cygwin/fhandler_tty.cc | 7 +++
 winsup/cygwin/tty.cc  | 2 ++
 winsup/cygwin/tty.h   | 2 ++
 3 files changed, 11 insertions(+)

diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index def2fe150..cd6b71620 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -2829,6 +2829,11 @@ fhandler_pty_slave::setup_pseudoconsole (bool nopcon)
   HPCON_INTERNAL *hp = (HPCON_INTERNAL *) get_ttyp ()->h_pseudo_console;
   get_ttyp ()->h_pcon_write_pipe = hp->hWritePipe;
 }
+
+  if (get_ttyp ()->previous_code_page)
+SetConsoleCP (get_ttyp ()->previous_code_page);
+  if (get_ttyp ()->previous_output_code_page)
+SetConsoleOutputCP (get_ttyp ()->previous_output_code_page);
   return true;
 
 cleanup_pcon_in:
@@ -2868,6 +2873,8 @@ fhandler_pty_slave::close_pseudoconsole (tty *ttyp)
   if (ttyp->h_pseudo_console)
 {
   ttyp->wait_pcon_fwd ();
+  ttyp->previous_code_page = GetConsoleCP ();
+  ttyp->previous_output_code_page = GetConsoleOutputCP ();
   FreeConsole ();
   AttachConsole (ATTACH_PARENT_PROCESS);
   HPCON_INTERNAL *hp = (HPCON_INTERNAL *) ttyp->h_pseudo_console;
diff --git a/winsup/cygwin/tty.cc b/winsup/cygwin/tty.cc
index 436f5c6c3..908166a37 100644
--- a/winsup/cygwin/tty.cc
+++ b/winsup/cygwin/tty.cc
@@ -246,6 +246,8 @@ tty::init ()
   has_csi6n = false;
   need_invisible_console = false;
   invisible_console_pid = 0;
+  previous_code_page = 0;
+  previous_output_code_page = 0;
 }
 
 HANDLE
diff --git a/winsup/cygwin/tty.h b/winsup/cygwin/tty.h
index eb604588c..061357437 100644
--- a/winsup/cygwin/tty.h
+++ b/winsup/cygwin/tty.h
@@ -107,6 +107,8 @@ private:
   bool has_csi6n;
   bool need_invisible_console;
   pid_t invisible_console_pid;
+  UINT previous_code_page;
+  UINT previous_output_code_page;
 
 public:
   HANDLE from_master () const { return _from_master; }
-- 
2.30.0



[PATCH v4 1/4] Cygwin: pty: Inherit typeahead data between two input pipes.

2021-01-25 Thread Takashi Yano via Cygwin-patches
- PTY has a problem that the key input, which is typed during windows
  native app is running, disappears when it returns to shell. This is
  beacuse pty has two input pipes, one is for cygwin apps and the other
  one is for native windows apps. The key input during windows native
  program is running is sent to the second input pipe while cygwin
  shell reads input from the first input pipe. This issue had been
  fixed once by commit 29431fcb, however, the new implementation of
  pseudo console support by commit bb428520 could not inherit this
  feature. This patch realize transfering input data between these
  two pipes bidirectionally by utilizing cygwin-console-helper process.
  The helper process is launched prior to starting the non-cygwin app,
  however, exits immediately unlike previous implementation.
---
 winsup/cygwin/fhandler.h  |  12 +-
 winsup/cygwin/fhandler_tty.cc | 504 ++
 winsup/cygwin/spawn.cc|  78 --
 winsup/cygwin/tty.cc  |   2 -
 winsup/cygwin/tty.h   |   8 +-
 5 files changed, 458 insertions(+), 146 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index af1ef3a45..10c5973dd 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -2291,6 +2291,13 @@ class fhandler_pty_slave: public fhandler_pty_common
   void fch_close_handles ();
 
  public:
+  /* Transfer direction for transfer_input() */
+  enum xfer_dir
+  {
+to_nat,
+to_cyg
+  };
+
   /* Constructor */
   fhandler_pty_slave (int);
 
@@ -2340,7 +2347,7 @@ class fhandler_pty_slave: public fhandler_pty_common
 copyto (fh);
 return fh;
   }
-  bool setup_pseudoconsole (STARTUPINFOEXW *si, bool nopcon);
+  bool setup_pseudoconsole (bool nopcon);
   static void close_pseudoconsole (tty *ttyp);
   bool term_has_pcon_cap (const WCHAR *env);
   void set_switch_to_pcon (void);
@@ -2349,6 +2356,9 @@ class fhandler_pty_slave: public fhandler_pty_common
   void setup_locale (void);
   tty *get_ttyp () { return (tty *) tc (); } /* Override as public */
   void create_invisible_console (void);
+  static void transfer_input (xfer_dir dir, HANDLE from, tty *ttyp,
+ HANDLE input_available_event);
+  HANDLE get_input_available_event (void) { return input_available_event; }
 };
 
 #define __ptsname(buf, unit) __small_sprintf ((buf), "/dev/pty%d", (unit))
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 7f0752614..def2fe150 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -848,8 +848,14 @@ fhandler_pty_slave::reset_switch_to_pcon (void)
 return;
   if (isHybrid)
 return;
+  if (get_ttyp ()->switch_to_pcon_in && !get_ttyp ()->h_pseudo_console)
+fhandler_pty_slave::transfer_input (fhandler_pty_slave::to_cyg,
+   get_handle (),
+   get_ttyp (),
+   input_available_event);
   get_ttyp ()->pcon_pid = 0;
   get_ttyp ()->switch_to_pcon_in = false;
+  get_ttyp ()->h_pseudo_console = NULL;
 }
 
 ssize_t __stdcall
@@ -891,6 +897,22 @@ fhandler_pty_slave::write (const void *ptr, size_t len)
 void
 fhandler_pty_slave::mask_switch_to_pcon_in (bool mask)
 {
+  if (get_ttyp ()->switch_to_pcon_in
+  && (get_ttyp ()->pcon_pid == myself->pid
+ || !get_ttyp ()->h_pseudo_console)
+  && get_ttyp ()->mask_switch_to_pcon_in != mask)
+{
+  if (mask)
+   fhandler_pty_slave::transfer_input (fhandler_pty_slave::to_cyg,
+   get_handle (),
+   get_ttyp (),
+   input_available_event);
+  else
+   fhandler_pty_slave::transfer_input (fhandler_pty_slave::to_nat,
+   get_handle_cyg (),
+   get_ttyp (),
+   input_available_event);
+}
   get_ttyp ()->mask_switch_to_pcon_in = mask;
 }
 
@@ -1591,7 +1613,7 @@ fhandler_pty_common::resize_pseudo_console (struct 
winsize *ws)
   size.X = ws->ws_col;
   size.Y = ws->ws_row;
   pinfo p (get_ttyp ()->pcon_pid);
-  if (p && !get_ttyp ()->do_not_resize_pcon)
+  if (p)
 {
   HPCON_INTERNAL hpcon_local;
   HANDLE pcon_owner =
@@ -1763,6 +1785,17 @@ fhandler_pty_master::write (const void *ptr, size_t len)
  get_ttyp ()->pcon_start = false;
}
  ReleaseMutex (input_mutex);
+ if (get_ttyp ()->switch_to_pcon_in)
+   {
+ fhandler_pty_slave::transfer_input (fhandler_pty_slave::to_nat,
+ from_master_cyg,
+ get_ttyp (),
+ input_available_event);
+ /* This accept_input() call is needed in order to transfer input
+ 

[PATCH v4 0/4] Improve pseudo console support.

2021-01-25 Thread Takashi Yano via Cygwin-patches
The new implementation of pseudo console support by commit bb428520
provides the important advantages, while there also has been several
disadvantages compared to the previous implementation.

These patches overturn some of them.

The disadvantage:
 1) The cygwin program which calls console API directly does not work.
is supposed to be able to be overcome as well, however, I am not sure
it is worth enough. This will need a lot of hooks for console APIs.
 --> Respecting Corinna's opinion, we decided not to implement this.

v3: Fix typeahead input issue in GDB. Several other bugs have also
been fixed.
v4: Change the conditions for calling transfer_input() slightly in
reset_switch_to_pcon() to avoid calling it if uncecessary or
with no effect.

Takashi Yano (4):
  Cygwin: pty: Inherit typeahead data between two input pipes.
  Cygwin: pty: Keep code page between non-cygwin apps.
  Cygwin: pty: Make apps using console APIs be able to debug with gdb.
  Cygwin: pty: Allow multiple apps to enable pseudo console
simultaneously.

 winsup/cygwin/fhandler.h  |   18 +-
 winsup/cygwin/fhandler_tty.cc | 1017 +++--
 winsup/cygwin/select.cc   |   18 +-
 winsup/cygwin/select.h|8 +-
 winsup/cygwin/spawn.cc|  102 ++--
 winsup/cygwin/tty.cc  |   11 +-
 winsup/cygwin/tty.h   |   18 +-
 7 files changed, 957 insertions(+), 235 deletions(-)

-- 
2.30.0



[PATCH v3 4/4] Cygwin: pty: Allow multiple apps to enable pseudo console simultaneously.

2021-01-25 Thread Takashi Yano via Cygwin-patches
- After commit bb428520, there has been the disadvantage:
  7) Pseudo console cannot be activated if it is already activated for
 another process on same pty.
  This patch clears this disadvantage.
---
 winsup/cygwin/fhandler.h  |   7 +-
 winsup/cygwin/fhandler_tty.cc | 342 +++---
 winsup/cygwin/select.cc   |   4 +-
 winsup/cygwin/spawn.cc|  40 ++--
 winsup/cygwin/tty.cc  |   2 +-
 winsup/cygwin/tty.h   |   6 +-
 6 files changed, 312 insertions(+), 89 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index dcdf65292..9472cf504 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -2273,6 +2273,9 @@ class fhandler_pty_common: public fhandler_termios
   }
 
   void resize_pseudo_console (struct winsize *);
+  static DWORD get_console_process_id (DWORD pid, bool match,
+  bool cygwin = false,
+  bool stub_only = false);
 
  protected:
   static BOOL process_opost_output (HANDLE h, const void *ptr, ssize_t& len,
@@ -2352,14 +2355,14 @@ class fhandler_pty_slave: public fhandler_pty_common
   bool term_has_pcon_cap (const WCHAR *env);
   void set_switch_to_pcon (void);
   void reset_switch_to_pcon (void);
-  bool mask_switch_to_pcon_in (bool mask);
+  bool mask_switch_to_pcon_in (bool mask, bool xfer);
   void setup_locale (void);
   tty *get_ttyp () { return (tty *) tc (); } /* Override as public */
   void create_invisible_console (void);
   static void transfer_input (xfer_dir dir, HANDLE from, tty *ttyp,
  HANDLE input_available_event);
   HANDLE get_input_available_event (void) { return input_available_event; }
-  bool pcon_activated (void) { return get_ttyp ()->h_pseudo_console; }
+  bool pcon_activated (void) { return get_ttyp ()->pcon_activated; }
 };
 
 #define __ptsname(buf, unit) __small_sprintf ((buf), "/dev/pty%d", (unit))
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 3471facd2..8a23260c7 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -62,8 +62,9 @@ struct pipe_reply {
 
 extern HANDLE attach_mutex; /* Defined in fhandler_console.cc */
 
-static DWORD
-get_console_process_id (DWORD pid, bool match)
+DWORD
+fhandler_pty_common::get_console_process_id (DWORD pid, bool match,
+bool cygwin, bool stub_only)
 {
   tmp_pathbuf tp;
   DWORD *list = (DWORD *) tp.c_get ();
@@ -73,16 +74,34 @@ get_console_process_id (DWORD pid, bool match)
   if (num == 0 || num > buf_size)
 return 0;
 
-  DWORD res = 0;
+  DWORD res_pri = 0, res = 0;
   /* Last one is the oldest. */
   /* https://github.com/microsoft/terminal/issues/95 */
   for (int i = (int) num - 1; i >= 0; i--)
 if ((match && list[i] == pid) || (!match && list[i] != pid))
   {
-   res = list[i];
-   break;
+   if (!cygwin)
+ {
+   res_pri = list[i];
+   break;
+ }
+   else
+ {
+   pinfo p (cygwin_pid (list[i]));
+   if (!!p && p->dwProcessId && p->exec_dwProcessId
+   && p->dwProcessId != p->exec_dwProcessId)
+ {
+   res_pri = list[i];
+   break;
+ }
+   if (!!p && !res)
+ res = list[i];
+ }
   }
-  return res;
+  if (stub_only)
+return res_pri;
+  else
+return res_pri ?: res;
 }
 
 static bool isHybrid;
@@ -935,7 +954,7 @@ fhandler_pty_slave::init (HANDLE h, DWORD a, mode_t)
 void
 fhandler_pty_slave::set_switch_to_pcon (void)
 {
-  if (!get_ttyp ()->switch_to_pcon_in)
+  if (!isHybrid)
 {
   isHybrid = true;
   setup_locale ();
@@ -951,10 +970,6 @@ fhandler_pty_slave::set_switch_to_pcon (void)
 void
 fhandler_pty_slave::reset_switch_to_pcon (void)
 {
-  if (get_ttyp ()->pcon_pid && get_ttyp ()->pcon_pid != myself->pid
-  && !!pinfo (get_ttyp ()->pcon_pid))
-/* There is a process which is grabbing pseudo console. */
-return;
   if (h_gdb_process)
 {
   if (WaitForSingleObject (h_gdb_process, 0) == WAIT_TIMEOUT)
@@ -975,7 +990,7 @@ fhandler_pty_slave::reset_switch_to_pcon (void)
  HANDLE pty_owner = NULL;
  if (p)
pty_owner = OpenProcess (PROCESS_DUP_HANDLE, FALSE, p->dwProcessId);
- if (pty_owner && get_ttyp ()->pcon_pid == myself->pid)
+ if (pty_owner)
{
  close_pseudoconsole (get_ttyp ());
  bool fixin, fixout, fixerr;
@@ -996,13 +1011,15 @@ fhandler_pty_slave::reset_switch_to_pcon (void)
SetStdHandle (STD_OUTPUT_HANDLE, get_output_handle ());
  if (fixerr)
SetStdHandle (STD_ERROR_HANDLE, get_output_handle ());
+ isHybrid = false;
}
- isHybrid = false;
- get_ttyp ()->pcon_pid = 0;
- get_ttyp ()->switch_to_pcon_in = false;
  return;
}
   

[PATCH v3 3/4] Cygwin: pty: Make apps using console APIs be able to debug with gdb.

2021-01-25 Thread Takashi Yano via Cygwin-patches
- After commit bb428520, there has been the disadvantage:
  2) The apps which use console API cannot be debugged with gdb. This
 is because pseudo console is not activated since gdb uses
 CreateProcess() rather than exec(). Even with this limitation,
 attaching gdb to native app, in which pseudo console is already
 activated, works.
  This patch clears this disadvantage.
---
 winsup/cygwin/fhandler.h  |   3 +-
 winsup/cygwin/fhandler_tty.cc | 240 +-
 winsup/cygwin/select.cc   |  18 ++-
 winsup/cygwin/select.h|   8 +-
 winsup/cygwin/spawn.cc|   2 +
 winsup/cygwin/tty.cc  |   5 +-
 winsup/cygwin/tty.h   |   2 +-
 7 files changed, 230 insertions(+), 48 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 10c5973dd..dcdf65292 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -2352,13 +2352,14 @@ class fhandler_pty_slave: public fhandler_pty_common
   bool term_has_pcon_cap (const WCHAR *env);
   void set_switch_to_pcon (void);
   void reset_switch_to_pcon (void);
-  void mask_switch_to_pcon_in (bool mask);
+  bool mask_switch_to_pcon_in (bool mask);
   void setup_locale (void);
   tty *get_ttyp () { return (tty *) tc (); } /* Override as public */
   void create_invisible_console (void);
   static void transfer_input (xfer_dir dir, HANDLE from, tty *ttyp,
  HANDLE input_available_event);
   HANDLE get_input_available_event (void) { return input_available_event; }
+  bool pcon_activated (void) { return get_ttyp ()->h_pseudo_console; }
 };
 
 #define __ptsname(buf, unit) __small_sprintf ((buf), "/dev/pty%d", (unit))
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 7cd4ea17e..3471facd2 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -27,6 +27,7 @@ details. */
 #include "cygwait.h"
 #include "registry.h"
 #include "tls_pbuf.h"
+#include "winf.h"
 
 #ifndef PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE
 #define PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE 0x00020016
@@ -85,21 +86,47 @@ get_console_process_id (DWORD pid, bool match)
 }
 
 static bool isHybrid;
+static HANDLE h_gdb_process;
 
 static void
-set_switch_to_pcon (HANDLE h)
+set_switch_to_pcon (HANDLE *in, HANDLE *out, HANDLE *err, bool iscygwin)
 {
   cygheap_fdenum cfd (false);
   int fd;
+  fhandler_base *replace_in = NULL, *replace_out = NULL, *replace_err = NULL;
+  fhandler_pty_slave *ptys_pcon = NULL;
   while ((fd = cfd.next ()) >= 0)
-if (cfd->get_major () == DEV_PTYS_MAJOR)
-  {
-   fhandler_base *fh = cfd;
-   fhandler_pty_slave *ptys = (fhandler_pty_slave *) fh;
-   if (h == ptys->get_handle ())
- ptys->set_switch_to_pcon ();
-   return;
-  }
+{
+  if (*in == cfd->get_handle () ||
+ (fd == 0 && *in == GetStdHandle (STD_INPUT_HANDLE)))
+   replace_in = (fhandler_base *) cfd;
+  if (*out == cfd->get_output_handle () ||
+ (fd == 1 && *out == GetStdHandle (STD_OUTPUT_HANDLE)))
+   replace_out = (fhandler_base *) cfd;
+  if (*err == cfd->get_output_handle () ||
+ (fd == 2 && *err == GetStdHandle (STD_ERROR_HANDLE)))
+   replace_err = (fhandler_base *) cfd;
+  if (cfd->get_major () == DEV_PTYS_MAJOR)
+   {
+ fhandler_base *fh = cfd;
+ fhandler_pty_slave *ptys = (fhandler_pty_slave *) fh;
+ if (*in == ptys->get_handle ())
+   ptys_pcon = ptys;
+   }
+}
+  if (!iscygwin && ptys_pcon)
+ptys_pcon->set_switch_to_pcon ();
+  if (replace_in)
+{
+  if (iscygwin && ptys_pcon->pcon_activated ())
+   *in = replace_in->get_handle_cyg ();
+  else
+   *in = replace_in->get_handle ();
+}
+  if (replace_out)
+*out = replace_out->get_output_handle ();
+  if (replace_err)
+*err = replace_err->get_output_handle ();
 }
 
 #define DEF_HOOK(name) static __typeof__ (name) *name##_Orig
@@ -113,16 +140,55 @@ CreateProcessA_Hooked
   BOOL inh, DWORD f, LPVOID e, LPCSTR d,
   LPSTARTUPINFOA si, LPPROCESS_INFORMATION pi)
 {
-  HANDLE h;
-  if (!isHybrid)
+  STARTUPINFOEXA siex = {0, };
+  if (si->cb == sizeof (STARTUPINFOEXA))
+siex = *(STARTUPINFOEXA *)si;
+  else
+siex.StartupInfo = *si;
+  STARTUPINFOA *siov = &siex.StartupInfo;
+  if (!(si->dwFlags & STARTF_USESTDHANDLES))
 {
-  if (si->dwFlags & STARTF_USESTDHANDLES)
-   h = si->hStdInput;
-  else
-   h = GetStdHandle (STD_INPUT_HANDLE);
-  set_switch_to_pcon (h);
+  siov->dwFlags |= STARTF_USESTDHANDLES;
+  siov->hStdInput = GetStdHandle (STD_INPUT_HANDLE);
+  siov->hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);
+  siov->hStdError = GetStdHandle (STD_ERROR_HANDLE);
 }
-  return CreateProcessA_Orig (n, c, pa, ta, inh, f, e, d, si, pi);
+  path_conv path;
+  tmp_pathbuf tp;
+  char *prog =tp.c_get ();
+  if (n)
+__small_sprintf (prog, "%s", n);
+  else
+{
+  __small_spri

[PATCH v3 2/4] Cygwin: pty: Keep code page between non-cygwin apps.

2021-01-25 Thread Takashi Yano via Cygwin-patches
- After commit bb428520, there has been the disadvantage:
  4) Code page cannot be changed by chcp.com. Acctually, chcp works
 itself and changes code page of its own pseudo console.  However,
 since pseudo console is recreated for another process, it cannot
 inherit the code page.
  This patch clears this disadvantage.
---
 winsup/cygwin/fhandler_tty.cc | 7 +++
 winsup/cygwin/tty.cc  | 2 ++
 winsup/cygwin/tty.h   | 2 ++
 3 files changed, 11 insertions(+)

diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index dc7afa774..7cd4ea17e 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -2822,6 +2822,11 @@ fhandler_pty_slave::setup_pseudoconsole (bool nopcon)
   HPCON_INTERNAL *hp = (HPCON_INTERNAL *) get_ttyp ()->h_pseudo_console;
   get_ttyp ()->h_pcon_write_pipe = hp->hWritePipe;
 }
+
+  if (get_ttyp ()->previous_code_page)
+SetConsoleCP (get_ttyp ()->previous_code_page);
+  if (get_ttyp ()->previous_output_code_page)
+SetConsoleOutputCP (get_ttyp ()->previous_output_code_page);
   return true;
 
 cleanup_pcon_in:
@@ -2861,6 +2866,8 @@ fhandler_pty_slave::close_pseudoconsole (tty *ttyp)
   if (ttyp->h_pseudo_console)
 {
   ttyp->wait_pcon_fwd ();
+  ttyp->previous_code_page = GetConsoleCP ();
+  ttyp->previous_output_code_page = GetConsoleOutputCP ();
   FreeConsole ();
   AttachConsole (ATTACH_PARENT_PROCESS);
   HPCON_INTERNAL *hp = (HPCON_INTERNAL *) ttyp->h_pseudo_console;
diff --git a/winsup/cygwin/tty.cc b/winsup/cygwin/tty.cc
index 436f5c6c3..908166a37 100644
--- a/winsup/cygwin/tty.cc
+++ b/winsup/cygwin/tty.cc
@@ -246,6 +246,8 @@ tty::init ()
   has_csi6n = false;
   need_invisible_console = false;
   invisible_console_pid = 0;
+  previous_code_page = 0;
+  previous_output_code_page = 0;
 }
 
 HANDLE
diff --git a/winsup/cygwin/tty.h b/winsup/cygwin/tty.h
index eb604588c..061357437 100644
--- a/winsup/cygwin/tty.h
+++ b/winsup/cygwin/tty.h
@@ -107,6 +107,8 @@ private:
   bool has_csi6n;
   bool need_invisible_console;
   pid_t invisible_console_pid;
+  UINT previous_code_page;
+  UINT previous_output_code_page;
 
 public:
   HANDLE from_master () const { return _from_master; }
-- 
2.30.0



[PATCH v3 1/4] Cygwin: pty: Inherit typeahead data between two input pipes.

2021-01-25 Thread Takashi Yano via Cygwin-patches
- PTY has a problem that the key input, which is typed during windows
  native app is running, disappears when it returns to shell. This is
  beacuse pty has two input pipes, one is for cygwin apps and the other
  one is for native windows apps. The key input during windows native
  program is running is sent to the second input pipe while cygwin
  shell reads input from the first input pipe. This issue had been
  fixed once by commit 29431fcb, however, the new implementation of
  pseudo console support by commit bb428520 could not inherit this
  feature. This patch realize transfering input data between these
  two pipes bidirectionally by utilizing cygwin-console-helper process.
  The helper process is launched prior to starting the non-cygwin app,
  however, exits immediately unlike previous implementation.
---
 winsup/cygwin/fhandler.h  |  12 +-
 winsup/cygwin/fhandler_tty.cc | 497 ++
 winsup/cygwin/spawn.cc|  78 --
 winsup/cygwin/tty.cc  |   2 -
 winsup/cygwin/tty.h   |   8 +-
 5 files changed, 451 insertions(+), 146 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index af1ef3a45..10c5973dd 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -2291,6 +2291,13 @@ class fhandler_pty_slave: public fhandler_pty_common
   void fch_close_handles ();
 
  public:
+  /* Transfer direction for transfer_input() */
+  enum xfer_dir
+  {
+to_nat,
+to_cyg
+  };
+
   /* Constructor */
   fhandler_pty_slave (int);
 
@@ -2340,7 +2347,7 @@ class fhandler_pty_slave: public fhandler_pty_common
 copyto (fh);
 return fh;
   }
-  bool setup_pseudoconsole (STARTUPINFOEXW *si, bool nopcon);
+  bool setup_pseudoconsole (bool nopcon);
   static void close_pseudoconsole (tty *ttyp);
   bool term_has_pcon_cap (const WCHAR *env);
   void set_switch_to_pcon (void);
@@ -2349,6 +2356,9 @@ class fhandler_pty_slave: public fhandler_pty_common
   void setup_locale (void);
   tty *get_ttyp () { return (tty *) tc (); } /* Override as public */
   void create_invisible_console (void);
+  static void transfer_input (xfer_dir dir, HANDLE from, tty *ttyp,
+ HANDLE input_available_event);
+  HANDLE get_input_available_event (void) { return input_available_event; }
 };
 
 #define __ptsname(buf, unit) __small_sprintf ((buf), "/dev/pty%d", (unit))
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 7f0752614..dc7afa774 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -850,6 +850,7 @@ fhandler_pty_slave::reset_switch_to_pcon (void)
 return;
   get_ttyp ()->pcon_pid = 0;
   get_ttyp ()->switch_to_pcon_in = false;
+  get_ttyp ()->h_pseudo_console = NULL;
 }
 
 ssize_t __stdcall
@@ -891,6 +892,20 @@ fhandler_pty_slave::write (const void *ptr, size_t len)
 void
 fhandler_pty_slave::mask_switch_to_pcon_in (bool mask)
 {
+  if (get_ttyp ()->switch_to_pcon_in && get_ttyp ()->pcon_pid == myself->pid
+  && get_ttyp ()->mask_switch_to_pcon_in != mask)
+{
+  if (mask)
+   fhandler_pty_slave::transfer_input (fhandler_pty_slave::to_cyg,
+   get_handle (),
+   get_ttyp (),
+   input_available_event);
+  else
+   fhandler_pty_slave::transfer_input (fhandler_pty_slave::to_nat,
+   get_handle_cyg (),
+   get_ttyp (),
+   input_available_event);
+}
   get_ttyp ()->mask_switch_to_pcon_in = mask;
 }
 
@@ -1591,7 +1606,7 @@ fhandler_pty_common::resize_pseudo_console (struct 
winsize *ws)
   size.X = ws->ws_col;
   size.Y = ws->ws_row;
   pinfo p (get_ttyp ()->pcon_pid);
-  if (p && !get_ttyp ()->do_not_resize_pcon)
+  if (p)
 {
   HPCON_INTERNAL hpcon_local;
   HANDLE pcon_owner =
@@ -1763,6 +1778,17 @@ fhandler_pty_master::write (const void *ptr, size_t len)
  get_ttyp ()->pcon_start = false;
}
  ReleaseMutex (input_mutex);
+ if (get_ttyp ()->switch_to_pcon_in)
+   {
+ fhandler_pty_slave::transfer_input (fhandler_pty_slave::to_nat,
+ from_master_cyg,
+ get_ttyp (),
+ input_available_event);
+ /* This accept_input() call is needed in order to transfer input
+which is not accepted yet to non-cygwin pipe. */
+ if (get_readahead_valid ())
+   accept_input ();
+   }
  return len;
}
 
@@ -2130,22 +2156,44 @@ fhandler_pty_master::pty_master_fwd_thread (const 
master_fwd_thread_param_t *p)
   char *ptr = outbuf;
   if (p->ttyp->h_pseudo_console)
{
- if (!p->ttyp->has_set_title)
-   

[PATCH v3 0/4] Improve pseudo console support.

2021-01-25 Thread Takashi Yano via Cygwin-patches
The new implementation of pseudo console support by commit bb428520
provides the important advantages, while there also has been several
disadvantages compared to the previous implementation.

These patches overturn some of them.

The disadvantage:
 1) The cygwin program which calls console API directly does not work.
is supposed to be able to be overcome as well, however, I am not sure
it is worth enough. This will need a lot of hooks for console APIs.
 --> Respecting Corinna's opinion, we decided not to implement this.

v3: Fix typeahead input issue in GDB. Several other bugs have also
been fixed.

Takashi Yano (4):
  Cygwin: pty: Inherit typeahead data between two input pipes.
  Cygwin: pty: Keep code page between non-cygwin apps.
  Cygwin: pty: Make apps using console APIs be able to debug with gdb.
  Cygwin: pty: Allow multiple apps to enable pseudo console
simultaneously.

 winsup/cygwin/fhandler.h  |   18 +-
 winsup/cygwin/fhandler_tty.cc | 1016 +++--
 winsup/cygwin/select.cc   |   18 +-
 winsup/cygwin/select.h|8 +-
 winsup/cygwin/spawn.cc|  102 ++--
 winsup/cygwin/tty.cc  |   11 +-
 winsup/cygwin/tty.h   |   18 +-
 7 files changed, 956 insertions(+), 235 deletions(-)

-- 
2.30.0



Re: [PATCH v2 0/4] Improve pseudo console support.

2021-01-25 Thread Takashi Yano via Cygwin-patches
Hi Corinna,

Thanks for testing.

On Fri, 22 Jan 2021 13:20:57 +0100
Corinna Vinschen wrote:
> Hi Takashi,
> 
> On Jan 22 05:58, Takashi Yano via Cygwin-patches wrote:
> > The new implementation of pseudo console support by commit bb428520
> > provides the important advantages, while there also has been several
> > disadvantages compared to the previous implementation.
> > 
> > These patches overturn some of them.
> > 
> > The disadvantage:
> >  1) The cygwin program which calls console API directly does not work.
> > is supposed to be able to be overcome as well, however, I am not sure
> > it is worth enough. This will need a lot of hooks for console APIs.
> > 
> > Takashi Yano (4):
> >   Cygwin: pty: Inherit typeahead data between two input pipes.
> >   Cygwin: pty: Keep code page between non-cygwin apps.
> >   Cygwin: pty: Make apps using console APIs be able to debug with gdb.
> >   Cygwin: pty: Allow multiple apps to enable pseudo console
> > simultaneously.
> > 
> >  winsup/cygwin/fhandler.h  |  15 +-
> >  winsup/cygwin/fhandler_tty.cc | 805 ++
> >  winsup/cygwin/spawn.cc| 102 +++--
> >  winsup/cygwin/tty.cc  |  11 +-
> >  winsup/cygwin/tty.h   |  18 +-
> >  5 files changed, 730 insertions(+), 221 deletions(-)
> > 
> > -- 
> > 2.30.0
> 
> I found a problem with this patchset.
> 
> Try this:
> 
>   Start mintty
> 
>   $ touch foo
>   $ attrib +r foo
>   $ gdb /bin/rm
>   $ start foo
> 
>   At this point, starting rm will take a few seconds.  While GDB is
>   still working on this, *before* GDB returns to the prompt, type some
>   keys on keyboard, e. g., "1234".
> 
> Without this patchset, you'll see the keys being echoed in mintty, and
> as soon as GDB returns to the prompt, the keys are copied to GDBs input
> buffer and the keys you typed show up after the prompt.  This is the
> expected behaviour.
> 
>   (gdb) 1234
> 
> With this patchset, the keys are *not* echoed in mintty, and as soon
> as the GDB prompt returns, the keys are still not visible.

I have fixed this issue. Please try v3 patch set. In v3 patch set,
pseudo console is not activated for GDB if the app to be debugged
is cygwin program. Also, for non-cygwin apps, I added the code to
transfer input when switching occurs between GDB and the debugging
process.

> Now continue the execution of rm:
> 
>   (gdb) c
>   /usr/bin/rm: remove write-protected regular file 'foo'? 
> 
> Without this patchset, I get
> 
>   /usr/bin/rm: error closing file
>   [...]
>   [Inferior 1 (process 1224) exited with code 01]
>   (gdb)

This seems to be a bug of cygwin GDB. The cause is that the pgid
setting for /usr/bin/rm is lost after break. The following patch
for GDB source resolves the issue. In the following section,
winpid is passed to getpgid() rather than cygwin pid. Also, winpid
is passed to other POSIX system calls such as kill() elsewhere. 

I hope the GDB maintainer will check it out.

--- inflow.c.orig   2020-05-24 06:10:29.0 +0900
+++ inflow.c2021-01-23 17:48:27.963609500 +0900
@@ -364,11 +364,11 @@
 #ifdef HAVE_TERMIOS_H
  /* If we can't tell the inferior's actual process group,
 then restore whatever was the foreground pgrp the last
 time the inferior was running.  See also comments
 describing terminal_state::process_group.  */
-#ifdef HAVE_GETPGID
+#if defined (HAVE_GETPGID) && !defined (__CYGWIN__)
  result = tcsetpgrp (0, getpgid (inf->pid));
 #else
  result = tcsetpgrp (0, tinfo->process_group);
 #endif
  if (result == -1)


> That's not optimal, apparently.  With this patchset:
> 
>   (gdb) c
>   /usr/bin/rm: remove write-protected regular file 'foo'? 1234
> 
> so the keys typed while gdb was starting rm have been saved up and then
> used as input for rm.  That's not quite right either, is it?

Another undesired behavior of cygwin GDB is that the debugging program
in pty cannot continue to execute after interrupted by Ctrl-C. If pseudo
console is activated for the debugging program, it seems to be able to
do this for some unknown reason.

-- 
Takashi Yano 


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

2021-01-25 Thread Takashi Yano via Cygwin-patches
- The commit a545 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; ic_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



Re: [PATCH v2 0/4] Improve pseudo console support.

2021-01-22 Thread Takashi Yano via Cygwin-patches
On Fri, 22 Jan 2021 10:50:28 +0100
Corinna Vinschen wrote:
> On Jan 22 05:58, Takashi Yano via Cygwin-patches wrote:
> > The new implementation of pseudo console support by commit bb428520
> > provides the important advantages, while there also has been several
> > disadvantages compared to the previous implementation.
> > 
> > These patches overturn some of them.
> > 
> > The disadvantage:
> >  1) The cygwin program which calls console API directly does not work.
> > is supposed to be able to be overcome as well, however, I am not sure
> > it is worth enough. This will need a lot of hooks for console APIs.
> 
> Definitely not.  We should really not cave in to such expectations.
> Cygwin apps are POSIX apps in the first place and should use the API
> provided by Cygwin and other Cygwin libs.  Yes, there are border cases
> like the X server or cygrunsrv, but these are limited and should stay
> limited.

I agree. I will stop working on it.

-- 
Takashi Yano 


[PATCH v2 4/4] Cygwin: pty: Allow multiple apps to enable pseudo console simultaneously.

2021-01-21 Thread Takashi Yano via Cygwin-patches
- After commit bb428520, there has been the disadvantage:
  7) Pseudo console cannot be activated if it is already activated for
 another process on same pty.
  This patch clears this disadvantage.
---
 winsup/cygwin/fhandler.h  |   3 +
 winsup/cygwin/fhandler_tty.cc | 240 ++
 winsup/cygwin/spawn.cc|  40 --
 winsup/cygwin/tty.cc  |   2 +-
 winsup/cygwin/tty.h   |   6 +-
 5 files changed, 226 insertions(+), 65 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 10c5973dd..698de051d 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -2273,6 +2273,9 @@ class fhandler_pty_common: public fhandler_termios
   }
 
   void resize_pseudo_console (struct winsize *);
+  static DWORD get_console_process_id (DWORD pid, bool match,
+  bool cygwin = false,
+  bool stub_only = false);
 
  protected:
   static BOOL process_opost_output (HANDLE h, const void *ptr, ssize_t& len,
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index b599ff5d1..b2f352964 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -61,8 +61,9 @@ struct pipe_reply {
 
 extern HANDLE attach_mutex; /* Defined in fhandler_console.cc */
 
-static DWORD
-get_console_process_id (DWORD pid, bool match)
+DWORD
+fhandler_pty_common::get_console_process_id (DWORD pid, bool match,
+bool cygwin, bool stub_only)
 {
   tmp_pathbuf tp;
   DWORD *list = (DWORD *) tp.c_get ();
@@ -72,16 +73,34 @@ get_console_process_id (DWORD pid, bool match)
   if (num == 0 || num > buf_size)
 return 0;
 
-  DWORD res = 0;
+  DWORD res_pri = 0, res = 0;
   /* Last one is the oldest. */
   /* https://github.com/microsoft/terminal/issues/95 */
   for (int i = (int) num - 1; i >= 0; i--)
 if ((match && list[i] == pid) || (!match && list[i] != pid))
   {
-   res = list[i];
-   break;
+   if (!cygwin)
+ {
+   res_pri = list[i];
+   break;
+ }
+   else
+ {
+   pinfo p (cygwin_pid (list[i]));
+   if (!!p && p->dwProcessId && p->exec_dwProcessId
+   && p->dwProcessId != p->exec_dwProcessId)
+ {
+   res_pri = list[i];
+   break;
+ }
+   if (!!p && !res)
+ res = list[i];
+ }
   }
-  return res;
+  if (stub_only)
+return res_pri;
+  else
+return res_pri ?: res;
 }
 
 static bool isHybrid;
@@ -871,7 +890,7 @@ fhandler_pty_slave::init (HANDLE h, DWORD a, mode_t)
 void
 fhandler_pty_slave::set_switch_to_pcon (void)
 {
-  if (!get_ttyp ()->switch_to_pcon_in)
+  if (!isHybrid)
 {
   isHybrid = true;
   setup_locale ();
@@ -883,10 +902,6 @@ fhandler_pty_slave::set_switch_to_pcon (void)
 void
 fhandler_pty_slave::reset_switch_to_pcon (void)
 {
-  if (get_ttyp ()->pcon_pid && get_ttyp ()->pcon_pid != myself->pid
-  && !!pinfo (get_ttyp ()->pcon_pid))
-/* There is a process which is grabbing pseudo console. */
-return;
   if (h_gdb_process)
 {
   if (WaitForSingleObject (h_gdb_process, 0) == WAIT_TIMEOUT)
@@ -897,6 +912,10 @@ fhandler_pty_slave::reset_switch_to_pcon (void)
  h_gdb_process = NULL;
}
 }
+  if (get_ttyp ()->pcon_pid && get_ttyp ()->pcon_pid != myself->pid
+  && !!pinfo (get_ttyp ()->pcon_pid))
+/* There is a process which is grabbing pseudo console. */
+return;
   if (isHybrid)
 return;
   get_ttyp ()->pcon_pid = 0;
@@ -1236,7 +1255,7 @@ fhandler_pty_slave::tcgetattr (struct termios *t)
   {
if (get_ttyp ()->pcon_start)
  t->c_lflag &= ~(ICANON | ECHO);
-   if (get_ttyp ()->h_pseudo_console)
+   if (get_ttyp ()->pcon_activated)
  t->c_iflag &= ~ICRNL;
break;
   }
@@ -1351,7 +1370,7 @@ fhandler_pty_slave::ioctl (unsigned int cmd, void *arg)
   if (get_ttyp ()->winsize.ws_row != ((struct winsize *) arg)->ws_row
  || get_ttyp ()->winsize.ws_col != ((struct winsize *) arg)->ws_col)
{
- if (get_ttyp ()->h_pseudo_console && get_ttyp ()->pcon_pid)
+ if (get_ttyp ()->pcon_activated && get_ttyp ()->pcon_pid)
resize_pseudo_console ((struct winsize *) arg);
  get_ttyp ()->arg.winsize = *(struct winsize *) arg;
  get_ttyp ()->winsize = *(struct winsize *) arg;
@@ -1766,7 +1785,7 @@ fhandler_pty_master::write (const void *ptr, size_t len)
 
   /* Write terminal input to to_slave pipe instead of output_handle
  if current application is native console application. */
-  if (to_be_read_from_pcon () && get_ttyp ()->h_pseudo_console)
+  if (to_be_read_from_pcon () && get_ttyp ()->pcon_activated)
 {
   tmp_pathbuf tp;
   char *buf = (char *) ptr;
@@ -1861,7 +1880,7 @@ fhandler_pty_master::tcgetattr (struct termios *t)
   /* Workaround for rlwrap v0

[PATCH v2 3/4] Cygwin: pty: Make apps using console APIs be able to debug with gdb.

2021-01-21 Thread Takashi Yano via Cygwin-patches
- After commit bb428520, there has been the disadvantage:
  2) The apps which use console API cannot be debugged with gdb. This
 is because pseudo console is not activated since gdb uses
 CreateProcess() rather than exec(). Even with this limitation,
 attaching gdb to native app, in which pseudo console is already
 activated, works.
  This patch clears this disadvantage.
---
 winsup/cygwin/fhandler_tty.cc | 124 +-
 winsup/cygwin/spawn.cc|   2 +
 winsup/cygwin/tty.cc  |   5 +-
 winsup/cygwin/tty.h   |   2 +-
 4 files changed, 97 insertions(+), 36 deletions(-)

diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 1396f9b1b..b599ff5d1 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -85,21 +85,42 @@ get_console_process_id (DWORD pid, bool match)
 }
 
 static bool isHybrid;
+static HANDLE h_gdb_process;
 
 static void
-set_switch_to_pcon (HANDLE h)
+set_switch_to_pcon (HANDLE *in, HANDLE *out, HANDLE *err)
 {
   cygheap_fdenum cfd (false);
   int fd;
+  fhandler_base *replace_in = NULL, *replace_out = NULL, *replace_err = NULL;
+  fhandler_pty_slave *ptys_pcon = NULL;
   while ((fd = cfd.next ()) >= 0)
-if (cfd->get_major () == DEV_PTYS_MAJOR)
-  {
-   fhandler_base *fh = cfd;
-   fhandler_pty_slave *ptys = (fhandler_pty_slave *) fh;
-   if (h == ptys->get_handle ())
- ptys->set_switch_to_pcon ();
-   return;
-  }
+{
+  if (*in == cfd->get_handle () ||
+ (fd == 0 && *in == GetStdHandle (STD_INPUT_HANDLE)))
+   replace_in = (fhandler_base *) cfd;
+  if (*out == cfd->get_output_handle () ||
+ (fd == 1 && *out == GetStdHandle (STD_OUTPUT_HANDLE)))
+   replace_out = (fhandler_base *) cfd;
+  if (*err == cfd->get_output_handle () ||
+ (fd == 2 && *err == GetStdHandle (STD_ERROR_HANDLE)))
+   replace_err = (fhandler_base *) cfd;
+  if (cfd->get_major () == DEV_PTYS_MAJOR)
+   {
+ fhandler_base *fh = cfd;
+ fhandler_pty_slave *ptys = (fhandler_pty_slave *) fh;
+ if (*in == ptys->get_handle ())
+   ptys_pcon = ptys;
+   }
+}
+  if (ptys_pcon)
+ptys_pcon->set_switch_to_pcon ();
+  if (replace_in)
+*in = replace_in->get_handle ();
+  if (replace_out)
+*out = replace_out->get_output_handle ();
+  if (replace_err)
+*err = replace_err->get_output_handle ();
 }
 
 #define DEF_HOOK(name) static __typeof__ (name) *name##_Orig
@@ -113,16 +134,26 @@ CreateProcessA_Hooked
   BOOL inh, DWORD f, LPVOID e, LPCSTR d,
   LPSTARTUPINFOA si, LPPROCESS_INFORMATION pi)
 {
-  HANDLE h;
-  if (!isHybrid)
-{
-  if (si->dwFlags & STARTF_USESTDHANDLES)
-   h = si->hStdInput;
-  else
-   h = GetStdHandle (STD_INPUT_HANDLE);
-  set_switch_to_pcon (h);
-}
-  return CreateProcessA_Orig (n, c, pa, ta, inh, f, e, d, si, pi);
+  STARTUPINFOEXA siex = {0, };
+  if (si->cb == sizeof (STARTUPINFOEXA))
+siex = *(STARTUPINFOEXA *)si;
+  else
+siex.StartupInfo = *si;
+  STARTUPINFOA *siov = &siex.StartupInfo;
+  if (!(si->dwFlags & STARTF_USESTDHANDLES))
+{
+  siov->dwFlags |= STARTF_USESTDHANDLES;
+  siov->hStdInput = GetStdHandle (STD_INPUT_HANDLE);
+  siov->hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);
+  siov->hStdError = GetStdHandle (STD_ERROR_HANDLE);
+}
+  set_switch_to_pcon (&siov->hStdInput, &siov->hStdOutput, &siov->hStdError);
+  BOOL ret = CreateProcessA_Orig (n, c, pa, ta, inh, f, e, d, siov, pi);
+  h_gdb_process = pi->hProcess;
+  DuplicateHandle (GetCurrentProcess (), h_gdb_process,
+  GetCurrentProcess (), &h_gdb_process,
+  0, 0, DUPLICATE_SAME_ACCESS);
+  return ret;
 }
 static BOOL WINAPI
 CreateProcessW_Hooked
@@ -130,16 +161,26 @@ CreateProcessW_Hooked
   BOOL inh, DWORD f, LPVOID e, LPCWSTR d,
   LPSTARTUPINFOW si, LPPROCESS_INFORMATION pi)
 {
-  HANDLE h;
-  if (!isHybrid)
-{
-  if (si->dwFlags & STARTF_USESTDHANDLES)
-   h = si->hStdInput;
-  else
-   h = GetStdHandle (STD_INPUT_HANDLE);
-  set_switch_to_pcon (h);
-}
-  return CreateProcessW_Orig (n, c, pa, ta, inh, f, e, d, si, pi);
+  STARTUPINFOEXW siex = {0, };
+  if (si->cb == sizeof (STARTUPINFOEXW))
+siex = *(STARTUPINFOEXW *)si;
+  else
+siex.StartupInfo = *si;
+  STARTUPINFOW *siov = &siex.StartupInfo;
+  if (!(si->dwFlags & STARTF_USESTDHANDLES))
+{
+  siov->dwFlags |= STARTF_USESTDHANDLES;
+  siov->hStdInput = GetStdHandle (STD_INPUT_HANDLE);
+  siov->hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);
+  siov->hStdError = GetStdHandle (STD_ERROR_HANDLE);
+}
+  set_switch_to_pcon (&siov->hStdInput, &siov->hStdOutput, &siov->hStdError);
+  BOOL ret = CreateProcessW_Orig (n, c, pa, ta, inh, f, e, d, siov, pi);
+  h_gdb_process = pi->hProcess;
+  DuplicateHandle (GetCurrentProcess (), h_gdb_process,
+  GetCurrentPro

[PATCH v2 2/4] Cygwin: pty: Keep code page between non-cygwin apps.

2021-01-21 Thread Takashi Yano via Cygwin-patches
- After commit bb428520, there has been the disadvantage:
  4) Code page cannot be changed by chcp.com. Acctually, chcp works
 itself and changes code page of its own pseudo console.  However,
 since pseudo console is recreated for another process, it cannot
 inherit the code page.
  This patch clears this disadvantage.
---
 winsup/cygwin/fhandler_tty.cc | 7 +++
 winsup/cygwin/tty.cc  | 2 ++
 winsup/cygwin/tty.h   | 2 ++
 3 files changed, 11 insertions(+)

diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 75ab500b1..1396f9b1b 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -2807,6 +2807,11 @@ fhandler_pty_slave::setup_pseudoconsole (bool nopcon)
   HPCON_INTERNAL *hp = (HPCON_INTERNAL *) get_ttyp ()->h_pseudo_console;
   get_ttyp ()->h_pcon_write_pipe = hp->hWritePipe;
 }
+
+  if (get_ttyp ()->previous_code_page)
+SetConsoleCP (get_ttyp ()->previous_code_page);
+  if (get_ttyp ()->previous_output_code_page)
+SetConsoleOutputCP (get_ttyp ()->previous_output_code_page);
   return true;
 
 cleanup_pcon_in:
@@ -2846,6 +2851,8 @@ fhandler_pty_slave::close_pseudoconsole (tty *ttyp)
   if (ttyp->h_pseudo_console)
 {
   ttyp->wait_pcon_fwd ();
+  ttyp->previous_code_page = GetConsoleCP ();
+  ttyp->previous_output_code_page = GetConsoleOutputCP ();
   FreeConsole ();
   AttachConsole (ATTACH_PARENT_PROCESS);
   HPCON_INTERNAL *hp = (HPCON_INTERNAL *) ttyp->h_pseudo_console;
diff --git a/winsup/cygwin/tty.cc b/winsup/cygwin/tty.cc
index 436f5c6c3..908166a37 100644
--- a/winsup/cygwin/tty.cc
+++ b/winsup/cygwin/tty.cc
@@ -246,6 +246,8 @@ tty::init ()
   has_csi6n = false;
   need_invisible_console = false;
   invisible_console_pid = 0;
+  previous_code_page = 0;
+  previous_output_code_page = 0;
 }
 
 HANDLE
diff --git a/winsup/cygwin/tty.h b/winsup/cygwin/tty.h
index eb604588c..061357437 100644
--- a/winsup/cygwin/tty.h
+++ b/winsup/cygwin/tty.h
@@ -107,6 +107,8 @@ private:
   bool has_csi6n;
   bool need_invisible_console;
   pid_t invisible_console_pid;
+  UINT previous_code_page;
+  UINT previous_output_code_page;
 
 public:
   HANDLE from_master () const { return _from_master; }
-- 
2.30.0



[PATCH v2 1/4] Cygwin: pty: Inherit typeahead data between two input pipes.

2021-01-21 Thread Takashi Yano via Cygwin-patches
- PTY has a problem that the key input, which is typed during windows
  native app is running, disappears when it returns to shell. This is
  beacuse pty has two input pipes, one is for cygwin apps and the other
  one is for native windows apps. The key input during windows native
  program is running is sent to the second input pipe while cygwin
  shell reads input from the first input pipe. This issue had been
  fixed once by commit 29431fcb, however, the new implementation of
  pseudo console support by commit bb428520 could not inherit this
  feature. This patch realize transfering input data between these
  two pipes bidirectionally by utilizing cygwin-console-helper process.
  The helper process is launched prior to starting the non-cygwin app,
  however, exits immediately unlike previous implementation.
---
 winsup/cygwin/fhandler.h  |  12 +-
 winsup/cygwin/fhandler_tty.cc | 468 ++
 winsup/cygwin/spawn.cc|  78 +++---
 winsup/cygwin/tty.cc  |   2 -
 winsup/cygwin/tty.h   |   8 +-
 5 files changed, 422 insertions(+), 146 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index af1ef3a45..10c5973dd 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -2291,6 +2291,13 @@ class fhandler_pty_slave: public fhandler_pty_common
   void fch_close_handles ();
 
  public:
+  /* Transfer direction for transfer_input() */
+  enum xfer_dir
+  {
+to_nat,
+to_cyg
+  };
+
   /* Constructor */
   fhandler_pty_slave (int);
 
@@ -2340,7 +2347,7 @@ class fhandler_pty_slave: public fhandler_pty_common
 copyto (fh);
 return fh;
   }
-  bool setup_pseudoconsole (STARTUPINFOEXW *si, bool nopcon);
+  bool setup_pseudoconsole (bool nopcon);
   static void close_pseudoconsole (tty *ttyp);
   bool term_has_pcon_cap (const WCHAR *env);
   void set_switch_to_pcon (void);
@@ -2349,6 +2356,9 @@ class fhandler_pty_slave: public fhandler_pty_common
   void setup_locale (void);
   tty *get_ttyp () { return (tty *) tc (); } /* Override as public */
   void create_invisible_console (void);
+  static void transfer_input (xfer_dir dir, HANDLE from, tty *ttyp,
+ HANDLE input_available_event);
+  HANDLE get_input_available_event (void) { return input_available_event; }
 };
 
 #define __ptsname(buf, unit) __small_sprintf ((buf), "/dev/pty%d", (unit))
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 7f0752614..75ab500b1 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -1591,7 +1591,7 @@ fhandler_pty_common::resize_pseudo_console (struct 
winsize *ws)
   size.X = ws->ws_col;
   size.Y = ws->ws_row;
   pinfo p (get_ttyp ()->pcon_pid);
-  if (p && !get_ttyp ()->do_not_resize_pcon)
+  if (p)
 {
   HPCON_INTERNAL hpcon_local;
   HANDLE pcon_owner =
@@ -1763,6 +1763,17 @@ fhandler_pty_master::write (const void *ptr, size_t len)
  get_ttyp ()->pcon_start = false;
}
  ReleaseMutex (input_mutex);
+ if (get_ttyp ()->switch_to_pcon_in)
+   {
+ fhandler_pty_slave::transfer_input (fhandler_pty_slave::to_nat,
+ from_master_cyg,
+ get_ttyp (),
+ input_available_event);
+ /* This accept_input() call is needed in order to transfer input
+which is not accepted yet to non-cygwin pipe. */
+ if (get_readahead_valid ())
+   accept_input ();
+   }
  return len;
}
 
@@ -2130,22 +2141,44 @@ fhandler_pty_master::pty_master_fwd_thread (const 
master_fwd_thread_param_t *p)
   char *ptr = outbuf;
   if (p->ttyp->h_pseudo_console)
{
- if (!p->ttyp->has_set_title)
-   {
- /* Remove Set title sequence */
- char *p0, *p1;
- p0 = outbuf;
- while ((p0 = (char *) memmem (p0, rlen, "\033]0;", 4))
-&& (p1 = (char *) memchr (p0, '\007', rlen-(p0-outbuf
-   {
- memmove (p0, p1 + 1, rlen - (p1 + 1 - outbuf));
- rlen -= p1 + 1 - p0;
- wlen = rlen;
-   }
-   }
- /* Remove CSI > Pm m */
+ /* Avoid setting window title to "cygwin-console-helper.exe" */
  int state = 0;
  int start_at = 0;
+ for (DWORD i=0; i Pm m */
+ state = 0;
+ start_at = 0;
  for (DWORD i = 0; i < rlen; i++)
if (outbuf[i] == '\033')
  {
@@ -2419,6 +2452,8 @@ fhandler_pty_master::setup ()
   t.set_from_master_cyg (from_master_cyg);
   t.set_to_master (to_master);
   t.set_to_master_cyg (to_master_cyg);
+  t.set_to_slave (to_slave);
+  t.set_to_slave_cyg (get_output_handle ());
   t.winsize.ws_col = 80;
   t.winsize.ws_row = 25;
   t.master_pid = myself-

[PATCH v2 0/4] Improve pseudo console support.

2021-01-21 Thread Takashi Yano via Cygwin-patches
The new implementation of pseudo console support by commit bb428520
provides the important advantages, while there also has been several
disadvantages compared to the previous implementation.

These patches overturn some of them.

The disadvantage:
 1) The cygwin program which calls console API directly does not work.
is supposed to be able to be overcome as well, however, I am not sure
it is worth enough. This will need a lot of hooks for console APIs.

Takashi Yano (4):
  Cygwin: pty: Inherit typeahead data between two input pipes.
  Cygwin: pty: Keep code page between non-cygwin apps.
  Cygwin: pty: Make apps using console APIs be able to debug with gdb.
  Cygwin: pty: Allow multiple apps to enable pseudo console
simultaneously.

 winsup/cygwin/fhandler.h  |  15 +-
 winsup/cygwin/fhandler_tty.cc | 805 ++
 winsup/cygwin/spawn.cc| 102 +++--
 winsup/cygwin/tty.cc  |  11 +-
 winsup/cygwin/tty.h   |  18 +-
 5 files changed, 730 insertions(+), 221 deletions(-)

-- 
2.30.0



[PATCH 4/4] Cygwin: pty: Allow multiple apps to enable pseudo console simultaneously.

2021-01-21 Thread Takashi Yano via Cygwin-patches
- After commit bb428520, there has been the disadvantage:
  7) Pseudo console cannot be activated if it is already activated for
 another process on same pty.
  This patch clears this disadvantage.
---
 winsup/cygwin/fhandler.h  |   3 +
 winsup/cygwin/fhandler_tty.cc | 239 ++
 winsup/cygwin/spawn.cc|  40 --
 winsup/cygwin/tty.cc  |   2 +-
 winsup/cygwin/tty.h   |   6 +-
 5 files changed, 225 insertions(+), 65 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 10c5973dd..698de051d 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -2273,6 +2273,9 @@ class fhandler_pty_common: public fhandler_termios
   }
 
   void resize_pseudo_console (struct winsize *);
+  static DWORD get_console_process_id (DWORD pid, bool match,
+  bool cygwin = false,
+  bool stub_only = false);
 
  protected:
   static BOOL process_opost_output (HANDLE h, const void *ptr, ssize_t& len,
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 8ac620acf..282a3b914 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -61,8 +61,9 @@ struct pipe_reply {
 
 extern HANDLE attach_mutex; /* Defined in fhandler_console.cc */
 
-static DWORD
-get_console_process_id (DWORD pid, bool match)
+DWORD
+fhandler_pty_common::get_console_process_id (DWORD pid, bool match,
+bool cygwin, bool stub_only)
 {
   tmp_pathbuf tp;
   DWORD *list = (DWORD *) tp.c_get ();
@@ -72,16 +73,34 @@ get_console_process_id (DWORD pid, bool match)
   if (num == 0 || num > buf_size)
 return 0;
 
-  DWORD res = 0;
+  DWORD res_pri = 0, res = 0;
   /* Last one is the oldest. */
   /* https://github.com/microsoft/terminal/issues/95 */
   for (int i = (int) num - 1; i >= 0; i--)
 if ((match && list[i] == pid) || (!match && list[i] != pid))
   {
-   res = list[i];
-   break;
+   if (!cygwin)
+ {
+   res_pri = list[i];
+   break;
+ }
+   else
+ {
+   pinfo p (cygwin_pid (list[i]));
+   if (!!p && p->dwProcessId && p->exec_dwProcessId
+   && p->dwProcessId != p->exec_dwProcessId)
+ {
+   res_pri = list[i];
+   break;
+ }
+   if (!!p && !res)
+ res = list[i];
+ }
   }
-  return res;
+  if (stub_only)
+return res_pri;
+  else
+return res_pri ?: res;
 }
 
 static bool isHybrid;
@@ -871,7 +890,7 @@ fhandler_pty_slave::init (HANDLE h, DWORD a, mode_t)
 void
 fhandler_pty_slave::set_switch_to_pcon (void)
 {
-  if (!get_ttyp ()->switch_to_pcon_in)
+  if (!isHybrid)
 {
   isHybrid = true;
   setup_locale ();
@@ -883,10 +902,6 @@ fhandler_pty_slave::set_switch_to_pcon (void)
 void
 fhandler_pty_slave::reset_switch_to_pcon (void)
 {
-  if (get_ttyp ()->pcon_pid && get_ttyp ()->pcon_pid != myself->pid
-  && !!pinfo (get_ttyp ()->pcon_pid))
-/* There is a process which is grabbing pseudo console. */
-return;
   if (h_gdb_process)
 {
   if (WaitForSingleObject (h_gdb_process, 0) == WAIT_TIMEOUT)
@@ -897,6 +912,10 @@ fhandler_pty_slave::reset_switch_to_pcon (void)
  h_gdb_process = NULL;
}
 }
+  if (get_ttyp ()->pcon_pid && get_ttyp ()->pcon_pid != myself->pid
+  && !!pinfo (get_ttyp ()->pcon_pid))
+/* There is a process which is grabbing pseudo console. */
+return;
   if (isHybrid)
 return;
   get_ttyp ()->pcon_pid = 0;
@@ -1236,7 +1255,7 @@ fhandler_pty_slave::tcgetattr (struct termios *t)
   {
if (get_ttyp ()->pcon_start)
  t->c_lflag &= ~(ICANON | ECHO);
-   if (get_ttyp ()->h_pseudo_console)
+   if (get_ttyp ()->pcon_activated)
  t->c_iflag &= ~ICRNL;
break;
   }
@@ -1351,7 +1370,7 @@ fhandler_pty_slave::ioctl (unsigned int cmd, void *arg)
   if (get_ttyp ()->winsize.ws_row != ((struct winsize *) arg)->ws_row
  || get_ttyp ()->winsize.ws_col != ((struct winsize *) arg)->ws_col)
{
- if (get_ttyp ()->h_pseudo_console && get_ttyp ()->pcon_pid)
+ if (get_ttyp ()->pcon_activated && get_ttyp ()->pcon_pid)
resize_pseudo_console ((struct winsize *) arg);
  get_ttyp ()->arg.winsize = *(struct winsize *) arg;
  get_ttyp ()->winsize = *(struct winsize *) arg;
@@ -1766,7 +1785,7 @@ fhandler_pty_master::write (const void *ptr, size_t len)
 
   /* Write terminal input to to_slave pipe instead of output_handle
  if current application is native console application. */
-  if (to_be_read_from_pcon () && get_ttyp ()->h_pseudo_console)
+  if (to_be_read_from_pcon () && get_ttyp ()->pcon_activated)
 {
   tmp_pathbuf tp;
   char *buf = (char *) ptr;
@@ -1861,7 +1880,7 @@ fhandler_pty_master::tcgetattr (struct termios *t)
   /* Workaround for rlwrap v0

  1   2   3   >