Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion winsup/cygwin/dtable.cc
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,17 @@ dtable::init_std_file_from_handle (int fd, HANDLE handle)
dev.parse (myself->ctty);
else
{
dev.parse (FH_CONSOLE);
/* Check whether the inherited console is actually a pseudo
console bridging a pty. This happens when our non-Cygwin
parent was itself spawned by a Cygwin process from a pty
(e.g. bash spawning git.exe which then spawns vim). In
that case, connect to the pty slave instead of treating
the handle as a real console. */
int pcon_minor = cygwin_shared->tty.find_pcon_pty ();
if (pcon_minor >= 0)
dev.parse (FHDEV (DEV_PTYS_MAJOR, pcon_minor));
else
dev.parse (FH_CONSOLE);
CloseHandle (handle);
handle = INVALID_HANDLE_VALUE;
}
Expand Down
5 changes: 5 additions & 0 deletions winsup/cygwin/local_includes/tty.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,10 @@ class tty: public tty_min
void wait_fwd ();
bool pty_input_state_eq (xfer_dir x) { return pty_input_state == x; }
bool nat_fg (pid_t pgid);
bool has_active_pcon () const
{ return pcon_activated && switch_to_nat_pipe; }
bool has_pcon_and_owner (DWORD pid) const
{ return pcon_activated && switch_to_nat_pipe && nat_pipe_owner_pid == pid; }
friend class fhandler_pty_common;
friend class fhandler_pty_master;
friend class fhandler_pty_slave;
Expand All @@ -193,6 +197,7 @@ class tty_list
int connect (int);
void init ();
tty_min *get_cttyp ();
int find_pcon_pty ();
int attach (int n);
static void init_session ();
friend class lock_ttys;
Expand Down
37 changes: 37 additions & 0 deletions winsup/cygwin/tty.cc
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,43 @@ tty_list::init ()
}
}

/* Search for a pty whose pseudo console owns our console.
Return tty minor number or -1 if not found.
Called from init_std_file_from_handle() for processes started by
non-Cygwin parents to detect that inherited console handles are
from a pcon-backed pty.

The cheap precondition (any tty with pcon active in shared memory)
short-circuits the common case where no pty has a pseudo console
active, avoiding the GetConsoleProcessList() LPC call entirely. */
int
tty_list::find_pcon_pty ()
{
DWORD pids[128];
DWORD count = 0;
bool got_pids = false;

for (int i = 0; i < NTTYS; i++)
{
if (!ttys[i].has_active_pcon ())
continue;

/* Fetch the console process list lazily, only on first candidate. */
if (!got_pids)
{
count = GetConsoleProcessList (pids, 128);
if (!count)
return -1;
got_pids = true;
}

for (DWORD j = 0; j < count; j++)
if (ttys[i].has_pcon_and_owner (pids[j]))
return i;
}
return -1;
}

/* Search for a free tty and allocate it.
Return tty number or -1 if error.
*/
Expand Down
Loading