From: Takashi Yano <takashi.yano@nifty.ne.jp>
To: cygwin-developers@cygwin.com
Subject: Re: New implementation of pseudo console support (experimental)
Date: Fri, 29 May 2020 00:40:24 +0900 [thread overview]
Message-ID: <20200529004024.0c2ac3c68b588bda987e0837@nifty.ne.jp> (raw)
In-Reply-To: <20200526100955.30b1a2baea517e0565f30db6@nifty.ne.jp>
[-- Attachment #1: Type: text/plain, Size: 1064 bytes --]
On Tue, 26 May 2020 10:09:55 +0900
Takashi Yano via Cygwin-developers <cygwin-developers@cygwin.com> wrote:
> On Mon, 25 May 2020 19:53:32 +0900
> Takashi Yano via Cygwin-developers <cygwin-developers@cygwin.com> wrote:
> > On Tue, 19 May 2020 22:40:18 +0900
> > Takashi Yano via Cygwin-developers <cygwin-developers@cygwin.com> wrote:
> > > On Sat, 16 May 2020 16:47:35 +0900
> > > Takashi Yano via Cygwin-developers <cygwin-developers@cygwin.com> wrote:
> > > > On Sat, 16 May 2020 09:29:56 +0900
> > > > Takashi Yano via Cygwin-developers <cygwin-developers@cygwin.com> wrote:
> > > > > Fix a small bug caused when stdio is redirected to another pty.
> > > >
> > > > Fix another bug caused when stdio is redirected to another pty.
> > >
> > > Revise the patch to fit the current git head.
> >
> > Revise the patch again to fit the current git head.
>
> Make app, which reads stdin, work under gdb.
* Prevent ResizePseudoConsole() calls unless the pty is resized.
* Revise the patch to fit the current git head.
--
Takashi Yano <takashi.yano@nifty.ne.jp>
[-- Attachment #2: pcon2-20200528.diff --]
[-- Type: text/plain, Size: 20327 bytes --]
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 76ad2aab0..7006aa060 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -2264,6 +2264,7 @@ class fhandler_pty_common: public fhandler_termios
return get_ttyp ()->h_pseudo_console;
}
bool to_be_read_from_pcon (void);
+ void resize_pseudo_console2 (struct winsize *);
protected:
BOOL process_opost_output (HANDLE h,
@@ -2356,6 +2357,9 @@ class fhandler_pty_slave: public fhandler_pty_common
void wait_pcon_fwd (void);
void pull_pcon_input (void);
void update_pcon_input_state (bool need_lock);
+ bool setup_pseudoconsole2 (STARTUPINFOEXW *si);
+ void close_pseudoconsole2 (void);
+ void wait_pcon_fwd2 (void);
};
#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 b091765b3..6c042409a 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -41,6 +41,8 @@ extern "C" {
VOID WINAPI ClosePseudoConsole (HPCON);
}
+#define USE_PCON_MODE2 true
+
#define close_maybe(h) \
do { \
if (h && h != INVALID_HANDLE_VALUE) \
@@ -73,7 +75,7 @@ clear_pcon_attached_to (void)
}
static void
-set_switch_to_pcon (void)
+set_switch_to_pcon (HANDLE h)
{
cygheap_fdenum cfd (false);
int fd;
@@ -90,6 +92,8 @@ set_switch_to_pcon (void)
ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT;
SetConsoleMode (ptys->get_handle (), mode);
}
+ else if (USE_PCON_MODE2 && h == ptys->get_handle ())
+ ptys->set_switch_to_pcon (fd);
return;
}
/* No pty slave opened */
@@ -180,7 +184,7 @@ set_ishybrid_and_switch_to_pcon (HANDLE h)
|| GetLastError () != ERROR_INVALID_HANDLE))
{
isHybrid = true;
- set_switch_to_pcon ();
+ set_switch_to_pcon (h);
}
}
}
@@ -363,11 +367,25 @@ CreateProcessA_Hooked
LPSTARTUPINFOA si, LPPROCESS_INFORMATION pi)
{
HANDLE h;
- if (si->dwFlags & STARTF_USESTDHANDLES)
- h = si->hStdOutput;
+ if (USE_PCON_MODE2)
+ {
+ if (!isHybrid)
+ {
+ if (si->dwFlags & STARTF_USESTDHANDLES)
+ h = si->hStdInput;
+ else
+ h = GetStdHandle (STD_INPUT_HANDLE);
+ set_switch_to_pcon (h);
+ }
+ }
else
- h = GetStdHandle (STD_OUTPUT_HANDLE);
- set_ishybrid_and_switch_to_pcon (h);
+ {
+ if (si->dwFlags & STARTF_USESTDHANDLES)
+ h = si->hStdOutput;
+ else
+ h = GetStdHandle (STD_OUTPUT_HANDLE);
+ set_ishybrid_and_switch_to_pcon (h);
+ }
return CreateProcessA_Orig (n, c, pa, ta, inh, f, e, d, si, pi);
}
static BOOL WINAPI
@@ -377,11 +395,25 @@ CreateProcessW_Hooked
LPSTARTUPINFOW si, LPPROCESS_INFORMATION pi)
{
HANDLE h;
- if (si->dwFlags & STARTF_USESTDHANDLES)
- h = si->hStdOutput;
+ if (USE_PCON_MODE2)
+ {
+ if (!isHybrid)
+ {
+ if (si->dwFlags & STARTF_USESTDHANDLES)
+ h = si->hStdInput;
+ else
+ h = GetStdHandle (STD_INPUT_HANDLE);
+ set_switch_to_pcon (h);
+ }
+ }
else
- h = GetStdHandle (STD_OUTPUT_HANDLE);
- set_ishybrid_and_switch_to_pcon (h);
+ {
+ if (si->dwFlags & STARTF_USESTDHANDLES)
+ h = si->hStdOutput;
+ else
+ h = GetStdHandle (STD_OUTPUT_HANDLE);
+ set_ishybrid_and_switch_to_pcon (h);
+ }
return CreateProcessW_Orig (n, c, pa, ta, inh, f, e, d, si, pi);
}
@@ -542,22 +574,26 @@ fhandler_pty_master::accept_input ()
bytes_left = eat_readahead (-1);
+ HANDLE write_to = get_output_handle ();
+ if (to_be_read_from_pcon () && USE_PCON_MODE2)
+ write_to = to_slave;
+
if (!bytes_left)
{
termios_printf ("sending EOF to slave");
get_ttyp ()->read_retval = 0;
}
- else if (!to_be_read_from_pcon ())
+ else if (!to_be_read_from_pcon () || USE_PCON_MODE2)
{
char *p = rabuf ();
DWORD rc;
DWORD written = 0;
paranoid_printf ("about to write %u chars to slave", bytes_left);
- rc = WriteFile (get_output_handle (), p, bytes_left, &written, NULL);
+ rc = WriteFile (write_to, p, bytes_left, &written, NULL);
if (!rc)
{
- debug_printf ("error writing to pipe %p %E", get_output_handle ());
+ debug_printf ("error writing to pipe %p %E", write_to);
get_ttyp ()->read_retval = -1;
ret = -1;
}
@@ -1267,6 +1303,18 @@ fhandler_pty_slave::set_switch_to_pcon (int fd_set)
{
if (fd < 0)
fd = fd_set;
+ if (USE_PCON_MODE2)
+ {
+ if (!get_ttyp ()->switch_to_pcon_in)
+ {
+ isHybrid = true;
+ if (get_ttyp ()->pcon_pid == 0 ||
+ !pinfo (get_ttyp ()->pcon_pid))
+ get_ttyp ()->pcon_pid = myself->pid;
+ get_ttyp ()->switch_to_pcon_in = true;
+ }
+ return;
+ }
if (fd == 0 && !get_ttyp ()->switch_to_pcon_in)
{
pull_pcon_input ();
@@ -1311,6 +1359,7 @@ fhandler_pty_slave::reset_switch_to_pcon (void)
get_ttyp ()->switch_to_pcon_in = false;
get_ttyp ()->switch_to_pcon_out = false;
init_console_handler (true);
+ get_ttyp ()->h_pseudo_console2 = NULL;
}
void
@@ -1570,8 +1619,9 @@ fhandler_pty_slave::mask_switch_to_pcon_in (bool mask)
bool
fhandler_pty_common::to_be_read_from_pcon (void)
{
- return !get_ttyp ()->pcon_in_empty ||
- (get_ttyp ()->switch_to_pcon_in && !get_ttyp ()->mask_switch_to_pcon_in);
+ return !get_ttyp ()->pcon_in_empty || get_ttyp ()->pcon2_start
+ || (get_ttyp ()->switch_to_pcon_in
+ && !get_ttyp ()->mask_switch_to_pcon_in);
}
void __reg3
@@ -2079,6 +2129,8 @@ cleanup:
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_console2 && get_ttyp ()->pcon_pid)
+ resize_pseudo_console2 ((struct winsize *) arg);
get_ttyp ()->arg.winsize = *(struct winsize *) arg;
get_ttyp ()->winsize = *(struct winsize *) arg;
get_ttyp ()->kill_pgrp (SIGWINCH);
@@ -2364,6 +2416,27 @@ fhandler_pty_common::close ()
return 0;
}
+void
+fhandler_pty_common::resize_pseudo_console2 (struct winsize *ws)
+{
+ COORD size;
+ size.X = ws->ws_col;
+ size.Y = ws->ws_row;
+ pinfo p (get_ttyp ()->pcon_pid);
+ if (p)
+ {
+ HPCON_INTERNAL hpcon_local;
+ HANDLE pcon_owner =
+ OpenProcess (PROCESS_DUP_HANDLE, FALSE, p->exec_dwProcessId);
+ DuplicateHandle (pcon_owner, get_ttyp ()->h_pcon_write_pipe,
+ GetCurrentProcess (), &hpcon_local.hWritePipe,
+ 0, TRUE, DUPLICATE_SAME_ACCESS);
+ ResizePseudoConsole ((HPCON) &hpcon_local, size);
+ CloseHandle (pcon_owner);
+ CloseHandle (hpcon_local.hWritePipe);
+ }
+}
+
void
fhandler_pty_master::cleanup ()
{
@@ -2501,7 +2574,8 @@ 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 ())
+ if (to_be_read_from_pcon ()
+ && (!USE_PCON_MODE2 || get_ttyp ()->h_pseudo_console2))
{
size_t nlen;
char *buf = convert_mb_str
@@ -2513,11 +2587,52 @@ fhandler_pty_master::write (const void *ptr, size_t len)
get_ttyp ()->req_flush_pcon_input = true;
DWORD wLen;
+
+ if (get_ttyp ()->pcon2_start)
+ {
+ /* Pseudo condole support mode-2 uses "CSI6n" to get cursor
+ position. If the reply for "CSI6n" is divided into multiple
+ writes, pseudo console sometimes does not recognize it.
+ Therefore, put them together into wpbuf and write all at once. */
+ static const int wpbuf_len = 64;
+ static char wpbuf[wpbuf_len];
+ static int ixput = 0;
+
+ if (ixput == 0 && buf[0] != '\033')
+ { /* fail-safe */
+ WriteFile (to_slave, "\033[1;1R", 6, &wLen, NULL); /* dummy */
+ get_ttyp ()->pcon2_start = false;
+ }
+ else
+ {
+ if (ixput + nlen < wpbuf_len)
+ for (size_t i=0; i<nlen; i++)
+ wpbuf[ixput++] = buf[i];
+ else
+ {
+ WriteFile (to_slave, wpbuf, ixput, &wLen, NULL);
+ ixput = 0;
+ get_ttyp ()->pcon2_start = false;
+ WriteFile (to_slave, buf, nlen, &wLen, NULL);
+ }
+ if (ixput && memchr (wpbuf, 'R', ixput))
+ {
+ WriteFile (to_slave, wpbuf, ixput, &wLen, NULL);
+ ixput = 0;
+ get_ttyp ()->pcon2_start = false;
+ }
+ ReleaseMutex (input_mutex);
+ mb_str_free (buf);
+ return len;
+ }
+ }
+
WriteFile (to_slave, buf, nlen, &wLen, NULL);
get_ttyp ()->pcon_in_empty = false;
ReleaseMutex (input_mutex);
+#if !USE_PCON_MODE2
/* Use line_edit () in order to set input_available_event. */
bool is_echo = tc ()->ti.c_lflag & ECHO;
if (!get_ttyp ()->mask_switch_to_pcon_in)
@@ -2543,6 +2658,7 @@ fhandler_pty_master::write (const void *ptr, size_t len)
eat_readahead (-1);
SetEvent (input_available_event);
}
+#endif /* USE_PCON_MODE2 */
mb_str_free (buf);
return len;
@@ -2627,6 +2743,8 @@ fhandler_pty_master::ioctl (unsigned int cmd, void *arg)
size.Y = ((struct winsize *) arg)->ws_row;
ResizePseudoConsole (get_pseudo_console (), size);
}
+ if (get_ttyp ()->h_pseudo_console2 && get_ttyp ()->pcon_pid)
+ resize_pseudo_console2 ((struct winsize *) arg);
get_ttyp ()->winsize = *(struct winsize *) arg;
get_ttyp ()->kill_pgrp (SIGWINCH);
}
@@ -2901,6 +3019,12 @@ fhandler_pty_slave::wait_pcon_fwd (void)
&& cygwait (get_ttyp ()->fwd_done, 1) == WAIT_TIMEOUT);
}
+void
+fhandler_pty_slave::wait_pcon_fwd2 (void)
+{
+ get_ttyp ()->wait_pcon_fwd ();
+}
+
void
fhandler_pty_slave::trigger_redraw_screen (void)
{
@@ -3054,6 +3178,12 @@ fhandler_pty_slave::fixup_after_exec ()
DO_HOOK (NULL, CreateProcessA);
DO_HOOK (NULL, CreateProcessW);
}
+ if (USE_PCON_MODE2)
+ {
+ /* CreateProcess() is hooked for GDB etc. */
+ DO_HOOK (NULL, CreateProcessA);
+ DO_HOOK (NULL, CreateProcessW);
+ }
}
/* This thread function handles the master control pipe. It waits for a
@@ -3270,6 +3400,8 @@ fhandler_pty_master::pty_master_fwd_thread ()
Sleep (1);
}
}
+ if (USE_PCON_MODE2)
+ get_ttyp ()->pcon_last_time = GetTickCount ();
if (!ReadFile (from_slave, outbuf, sizeof outbuf, &rlen, NULL))
{
termios_printf ("ReadFile for forwarding failed, %E");
@@ -3277,8 +3409,9 @@ fhandler_pty_master::pty_master_fwd_thread ()
}
ssize_t wlen = rlen;
char *ptr = outbuf;
- if (get_pseudo_console ())
+ if (get_pseudo_console () || get_ttyp ()->h_pseudo_console2)
{
+#if !USE_PCON_MODE2
/* Avoid duplicating slave output which is already sent to
to_master_cyg */
if (!get_ttyp ()->switch_to_pcon_out)
@@ -3331,6 +3464,7 @@ fhandler_pty_master::pty_master_fwd_thread ()
rlen -= 4;
}
wlen = rlen;
+#endif /* USE_PCON_MODE2 */
size_t nlen;
char *buf = convert_mb_str
@@ -3700,7 +3834,19 @@ fhandler_pty_master::setup ()
t.winsize.ws_col = 80;
t.winsize.ws_row = 25;
- setup_pseudoconsole ();
+ if (!USE_PCON_MODE2)
+ setup_pseudoconsole ();
+ else
+ {
+ __small_sprintf (pipename, "pty%d-to-slave", unit);
+ res = fhandler_pipe::create (&sec_none, &from_master, &to_slave,
+ fhandler_pty_common::pipesize, pipename, 0);
+ if (res)
+ {
+ errstr = "input pipe";
+ goto err;
+ }
+ }
t.set_from_master (from_master);
t.set_from_master_cyg (from_master_cyg);
@@ -3718,6 +3864,7 @@ fhandler_pty_master::setup ()
err:
__seterrno ();
close_maybe (from_slave);
+ close_maybe (to_slave);
close_maybe (get_handle ());
close_maybe (get_output_handle ());
close_maybe (input_available_event);
@@ -3862,3 +4009,126 @@ fhandler_pty_common::process_opost_output (HANDLE h, const void *ptr, ssize_t& l
len -= towrite;
return res;
}
+
+bool
+fhandler_pty_slave::setup_pseudoconsole2 (STARTUPINFOEXW *si)
+{
+ if (USE_PCON_MODE2)
+ {
+ fhandler_base *fh = (fhandler_pty_slave *) ::cygheap->fdtab[0];
+ if (fh && fh->get_major () == DEV_PTYS_MAJOR)
+ {
+ fhandler_pty_slave *ptys = (fhandler_pty_slave *) fh;
+ ptys->get_ttyp ()->switch_to_pcon_in = true;
+ if (ptys->get_ttyp ()->pcon_pid == 0 ||
+ !pinfo (ptys->get_ttyp ()->pcon_pid))
+ ptys->get_ttyp ()->pcon_pid = myself->pid;
+ }
+ }
+ if (!USE_PCON_MODE2)
+ return false;
+ if (disable_pcon)
+ return false;
+ /* If the legacy console mode is enabled, pseudo console seems
+ not to work as expected. To determine console mode, registry
+ key ForceV2 in HKEY_CURRENT_USER\Console is checked. */
+ reg_key reg (HKEY_CURRENT_USER, KEY_READ, L"Console", NULL);
+ if (reg.error ())
+ return false;
+ if (reg.get_dword (L"ForceV2", 1) == 0)
+ {
+ termios_printf ("Pseudo console is disabled "
+ "because the legacy console mode is enabled.");
+ return false;
+ }
+
+ COORD size = {
+ (SHORT) get_ttyp ()->winsize.ws_col,
+ (SHORT) get_ttyp ()->winsize.ws_row
+ };
+ SetLastError (ERROR_SUCCESS);
+ HRESULT res = CreatePseudoConsole (size, get_handle (), get_output_handle (),
+ 1, &get_ttyp ()->h_pseudo_console2);
+ if (res != S_OK || GetLastError () == ERROR_PROC_NOT_FOUND)
+ {
+ if (res != S_OK)
+ system_printf ("CreatePseudoConsole() failed. %08x %08x\n",
+ GetLastError (), res);
+ goto fallback;
+ }
+
+ SIZE_T bytesRequired;
+ InitializeProcThreadAttributeList (NULL, 1, 0, &bytesRequired);
+ ZeroMemory (si, sizeof (*si));
+ si->StartupInfo.cb = sizeof (STARTUPINFOEXW);
+ si->lpAttributeList = (PPROC_THREAD_ATTRIBUTE_LIST)
+ HeapAlloc (GetProcessHeap (), 0, bytesRequired);
+ if (si->lpAttributeList == NULL)
+ goto cleanup_pseudo_console;
+ if (!InitializeProcThreadAttributeList (si->lpAttributeList,
+ 1, 0, &bytesRequired))
+ goto cleanup_heap;
+ if (!UpdateProcThreadAttribute (si->lpAttributeList,
+ 0,
+ PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE,
+ get_ttyp ()->h_pseudo_console2,
+ sizeof (get_ttyp ()->h_pseudo_console2),
+ NULL, NULL))
+ goto cleanup_heap;
+ si->StartupInfo.dwFlags = STARTF_USESTDHANDLES;
+ si->StartupInfo.hStdInput = NULL;
+ si->StartupInfo.hStdOutput = NULL;
+ si->StartupInfo.hStdError = NULL;
+
+ {
+ fhandler_pty_slave *p0 = (fhandler_pty_slave *) ::cygheap->fdtab[0];
+ if (p0 && p0->get_device () != get_device ())
+ si->StartupInfo.hStdInput = p0->get_handle ();
+ fhandler_pty_slave *p1 = (fhandler_pty_slave *) ::cygheap->fdtab[1];
+ if (p1 && p1->get_device () != get_device ())
+ si->StartupInfo.hStdOutput = p1->get_output_handle ();
+ fhandler_pty_slave *p2 = (fhandler_pty_slave *) ::cygheap->fdtab[2];
+ if (p2 && p2->get_device () != get_device ())
+ si->StartupInfo.hStdError = p2->get_output_handle ();
+ }
+
+ if (get_ttyp ()->pcon_pid == 0 || !pinfo (get_ttyp ()->pcon_pid))
+ get_ttyp ()->pcon_pid = myself->pid;
+
+ if (get_ttyp ()->h_pseudo_console2 && get_ttyp ()->pcon_pid == myself->pid)
+ {
+ HPCON_INTERNAL *hp = (HPCON_INTERNAL *) get_ttyp ()->h_pseudo_console2;
+ get_ttyp ()->h_pcon_write_pipe = hp->hWritePipe;
+ }
+ get_ttyp ()->pcon2_start = true;
+ return true;
+
+cleanup_heap:
+ HeapFree (GetProcessHeap (), 0, si->lpAttributeList);
+cleanup_pseudo_console:
+ if (get_ttyp ()->h_pseudo_console2)
+ {
+ HPCON_INTERNAL *hp = (HPCON_INTERNAL *) get_ttyp ()->h_pseudo_console2;
+ HANDLE tmp = hp->hConHostProcess;
+ ClosePseudoConsole (get_ttyp ()->h_pseudo_console2);
+ CloseHandle (tmp);
+ }
+fallback:
+ get_ttyp ()->h_pseudo_console2 = NULL;
+ return false;
+}
+
+void
+fhandler_pty_slave::close_pseudoconsole2 (void)
+{
+ if (get_ttyp ()->h_pseudo_console2)
+ {
+ HPCON_INTERNAL *hp = (HPCON_INTERNAL *) get_ttyp ()->h_pseudo_console2;
+ HANDLE tmp = hp->hConHostProcess;
+ ClosePseudoConsole (get_ttyp ()->h_pseudo_console2);
+ CloseHandle (tmp);
+ get_ttyp ()->h_pseudo_console2 = NULL;
+ get_ttyp ()->switch_to_pcon_in = false;
+ get_ttyp ()->pcon_pid = 0;
+ }
+}
diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc
index 3e8c8367a..514125072 100644
--- a/winsup/cygwin/spawn.cc
+++ b/winsup/cygwin/spawn.cc
@@ -194,6 +194,24 @@ handle (int fd, bool writing)
return h;
}
+static bool
+is_console_app (WCHAR *filename)
+{
+ HANDLE h;
+ const int id_offset = 92;
+ h = CreateFileW (filename, GENERIC_READ, FILE_SHARE_READ,
+ NULL, OPEN_EXISTING, 0, NULL);
+ char buf[1024];
+ DWORD n;
+ ReadFile (h, buf, sizeof (buf), &n, 0);
+ CloseHandle (h);
+ char *p = (char *) memmem (buf, n, "PE\0\0", 4);
+ if (p && p + id_offset <= buf + n)
+ return p[id_offset] == '\003'; /* 02: GUI, 03: console */
+ else
+ return false;
+}
+
int
iscmd (const char *argv0, const char *what)
{
@@ -583,6 +601,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
/* Attach to pseudo console if pty salve is used */
pid_restore = fhandler_console::get_console_process_id
(GetCurrentProcessId (), false);
+ fhandler_pty_slave *ptys_primary = NULL;
for (int i = 0; i < 3; i ++)
{
const int chk_order[] = {1, 0, 2};
@@ -591,6 +610,8 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
if (fh && fh->get_major () == DEV_PTYS_MAJOR)
{
fhandler_pty_slave *ptys = (fhandler_pty_slave *) fh;
+ if (ptys_primary == NULL)
+ ptys_primary = ptys;
if (ptys->get_pseudo_console ())
{
DWORD helper_process_id = ptys->get_helper_process_id ();
@@ -632,6 +653,18 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
if (!iscygwin ())
init_console_handler (myself->ctty > 0);
+ bool use_pcon_mode2 = false;
+ STARTUPINFOEXW si_pcon;
+ ZeroMemory (&si_pcon, sizeof (si_pcon));
+ STARTUPINFOW *si_tmp = &si;
+ if (!iscygwin () && ptys_primary && is_console_app (runpath))
+ if (ptys_primary->setup_pseudoconsole2 (&si_pcon))
+ {
+ c_flags |= EXTENDED_STARTUPINFO_PRESENT;
+ si_tmp = &si_pcon.StartupInfo;
+ use_pcon_mode2 = true;
+ }
+
loop:
/* When ruid != euid we create the new process under the current original
account and impersonate in child, this way maintaining the different
@@ -660,7 +693,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
c_flags,
envblock, /* environment */
NULL,
- &si,
+ si_tmp,
&pi);
}
else
@@ -714,7 +747,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
c_flags,
envblock, /* environment */
NULL,
- &si,
+ si_tmp,
&pi);
if (hwst)
{
@@ -727,6 +760,11 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
CloseDesktop (hdsk);
}
}
+ if (use_pcon_mode2)
+ {
+ DeleteProcThreadAttributeList (si_pcon.lpAttributeList);
+ HeapFree (GetProcessHeap (), 0, si_pcon.lpAttributeList);
+ }
if (mode != _P_OVERLAY)
SetHandleInformation (my_wr_proc_pipe, HANDLE_FLAG_INHERIT,
@@ -897,6 +935,12 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
&& WaitForSingleObject (pi.hProcess, 0) == WAIT_TIMEOUT)
wait_for_myself ();
}
+ if (use_pcon_mode2)
+ {
+ WaitForSingleObject (pi.hProcess, INFINITE);
+ ptys_primary->wait_pcon_fwd2 ();
+ ptys_primary->close_pseudoconsole2 ();
+ }
myself.exit (EXITCODE_NOSET);
break;
case _P_WAIT:
diff --git a/winsup/cygwin/tty.cc b/winsup/cygwin/tty.cc
index efdae4697..28316ba6a 100644
--- a/winsup/cygwin/tty.cc
+++ b/winsup/cygwin/tty.cc
@@ -249,6 +249,8 @@ tty::init ()
pcon_in_empty = true;
req_transfer_input_to_pcon = false;
req_flush_pcon_input = false;
+ h_pseudo_console2 = NULL;
+ pcon2_start = false;
}
HANDLE
diff --git a/winsup/cygwin/tty.h b/winsup/cygwin/tty.h
index 7d6fc8fef..52f3872e2 100644
--- a/winsup/cygwin/tty.h
+++ b/winsup/cygwin/tty.h
@@ -110,6 +110,9 @@ private:
bool pcon_in_empty;
bool req_transfer_input_to_pcon;
bool req_flush_pcon_input;
+ HPCON h_pseudo_console2;
+ HANDLE h_pcon_write_pipe;
+ bool pcon2_start;
public:
HANDLE from_master () const { return _from_master; }
next prev parent reply other threads:[~2020-05-28 15:40 UTC|newest]
Thread overview: 73+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-05-13 12:16 Takashi Yano
2020-05-13 12:35 ` Thomas Wolff
2020-05-14 9:28 ` Takashi Yano
2020-05-14 9:34 ` Takashi Yano
2020-05-16 0:29 ` Takashi Yano
2020-05-16 7:47 ` Takashi Yano
2020-05-19 13:40 ` Takashi Yano
2020-05-25 10:53 ` Takashi Yano
2020-05-25 15:22 ` Corinna Vinschen
2020-05-25 19:16 ` Thomas Wolff
2020-05-26 1:00 ` Takashi Yano
2020-05-26 7:14 ` Thomas Wolff
2020-05-26 9:21 ` Takashi Yano
2020-05-26 9:32 ` Thomas Wolff
2020-05-26 8:33 ` Corinna Vinschen
2020-05-26 1:09 ` Takashi Yano
2020-05-28 15:40 ` Takashi Yano [this message]
2020-05-29 15:30 ` Corinna Vinschen
2020-05-30 7:36 ` Takashi Yano
2020-05-30 13:14 ` Takashi Yano
2020-05-30 17:43 ` Corinna Vinschen
2020-05-31 5:52 ` Takashi Yano
2020-07-01 11:47 ` Takashi Yano
2020-07-17 11:19 ` Corinna Vinschen
2020-07-17 12:47 ` Thomas Wolff
2020-07-17 14:59 ` Thomas Wolff
2020-07-18 5:05 ` Takashi Yano
2020-07-18 20:57 ` Thomas Wolff
2020-07-23 17:17 ` Takashi Yano
2020-07-27 17:10 ` Thomas Wolff
2020-07-17 12:52 ` Ken Brown
2020-07-18 5:07 ` Takashi Yano
2020-07-18 5:30 ` Takashi Yano
2020-07-20 8:06 ` Corinna Vinschen
2020-07-21 18:17 ` Takashi Yano
2020-07-22 8:45 ` Takashi Yano
2020-07-22 11:49 ` Corinna Vinschen
2020-07-22 12:13 ` Ken Brown
2020-07-23 0:33 ` Takashi Yano
2020-07-24 5:38 ` Takashi Yano
2020-07-24 11:22 ` Takashi Yano
2020-08-02 12:01 ` Corinna Vinschen
2020-08-03 2:05 ` Takashi Yano
2020-08-03 10:50 ` Corinna Vinschen
2020-08-03 2:11 ` Takashi Yano
2020-08-03 12:23 ` Takashi Yano
2020-08-11 11:12 ` Takashi Yano
2020-08-13 9:58 ` Takashi Yano
2020-08-17 11:57 ` Takashi Yano
2020-08-19 11:39 ` Takashi Yano
2020-08-19 13:41 ` Corinna Vinschen
2020-08-19 15:43 ` Thomas Wolff
2020-08-19 20:47 ` Mark Geisert
2020-08-20 8:02 ` Takashi Yano
2020-08-31 12:49 ` Johannes Schindelin
2020-08-31 14:14 ` Takashi Yano
[not found] ` <20200831231253.332c66fdddb33ceed5f61db6@nifty.ne.jp>
2020-08-31 14:22 ` Johannes Schindelin
2020-08-31 14:53 ` Takashi Yano
2020-08-31 15:56 ` Johannes Schindelin
2020-08-31 16:12 ` Thomas Wolff
2020-08-31 17:39 ` Thomas Wolff
2020-08-31 19:17 ` Johannes Schindelin
2020-08-31 19:37 ` Corinna Vinschen
2020-09-01 4:46 ` Johannes Schindelin
2020-09-01 9:23 ` Takashi Yano
2020-09-01 6:32 ` Johannes Schindelin
2020-09-01 22:33 ` Takashi Yano
2020-09-02 6:13 ` Johannes Schindelin
2020-09-01 9:42 ` Takashi Yano
2020-08-31 21:07 ` Thomas Wolff
2020-08-31 23:23 ` Takashi Yano
2020-09-01 5:00 ` Johannes Schindelin
2020-09-01 8:56 ` Thomas Wolff
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200529004024.0c2ac3c68b588bda987e0837@nifty.ne.jp \
--to=takashi.yano@nifty.ne.jp \
--cc=cygwin-developers@cygwin.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).