Cygwin: pty: Fix state management for pseudo console support.
- Pseudo console support introduced by commit
169d65a577
has some bugs which
cause mismatch between state variables and real pseudo console
state regarding console attaching and r/w pipe switching. This
patch fixes this issue by redesigning the state management.
This commit is contained in:
parent
ffbb9b4971
commit
583102e7c9
|
@ -147,18 +147,16 @@ dtable::get_debugger_info ()
|
||||||
void
|
void
|
||||||
dtable::stdio_init ()
|
dtable::stdio_init ()
|
||||||
{
|
{
|
||||||
bool need_fixup_handle = false;
|
int chk_order[] = {1, 0, 2};
|
||||||
fhandler_pty_slave *ptys = NULL;
|
for (int i = 0; i < 3; i ++)
|
||||||
bool is_pty[3] = {false, false, false};
|
|
||||||
for (int fd = 0; fd < 3; fd ++)
|
|
||||||
{
|
{
|
||||||
|
int fd = chk_order[i];
|
||||||
fhandler_base *fh = cygheap->fdtab[fd];
|
fhandler_base *fh = cygheap->fdtab[fd];
|
||||||
if (fh && fh->get_major () == DEV_PTYS_MAJOR)
|
if (fh && fh->get_major () == DEV_PTYS_MAJOR)
|
||||||
{
|
{
|
||||||
ptys = (fhandler_pty_slave *) fh;
|
fhandler_pty_slave *ptys = (fhandler_pty_slave *) fh;
|
||||||
if (ptys->getPseudoConsole ())
|
if (ptys->getPseudoConsole ())
|
||||||
{
|
{
|
||||||
is_pty[fd] = true;
|
|
||||||
bool attached = !!fhandler_console::get_console_process_id
|
bool attached = !!fhandler_console::get_console_process_id
|
||||||
(ptys->getHelperProcessId (), true);
|
(ptys->getHelperProcessId (), true);
|
||||||
if (!attached)
|
if (!attached)
|
||||||
|
@ -167,15 +165,12 @@ dtable::stdio_init ()
|
||||||
by some reason. This happens if the executable is
|
by some reason. This happens if the executable is
|
||||||
a windows GUI binary, such as mintty. */
|
a windows GUI binary, such as mintty. */
|
||||||
FreeConsole ();
|
FreeConsole ();
|
||||||
AttachConsole (ptys->getHelperProcessId ());
|
if (AttachConsole (ptys->getHelperProcessId ()))
|
||||||
need_fixup_handle = true;
|
break;
|
||||||
}
|
}
|
||||||
ptys->reset_switch_to_pcon ();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (need_fixup_handle)
|
|
||||||
goto fixup_handle;
|
|
||||||
|
|
||||||
if (myself->cygstarted || ISSTATE (myself, PID_CYGPARENT))
|
if (myself->cygstarted || ISSTATE (myself, PID_CYGPARENT))
|
||||||
{
|
{
|
||||||
|
@ -185,27 +180,6 @@ dtable::stdio_init ()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fixup_handle:
|
|
||||||
if (need_fixup_handle)
|
|
||||||
{
|
|
||||||
HANDLE h;
|
|
||||||
h = CreateFile ("CONIN$", GENERIC_READ, FILE_SHARE_READ,
|
|
||||||
NULL, OPEN_EXISTING, 0, 0);
|
|
||||||
if (is_pty[0])
|
|
||||||
{
|
|
||||||
SetStdHandle (STD_INPUT_HANDLE, h);
|
|
||||||
ptys->set_handle (h);
|
|
||||||
}
|
|
||||||
h = CreateFile ("CONOUT$", GENERIC_WRITE, FILE_SHARE_WRITE,
|
|
||||||
NULL, OPEN_EXISTING, 0, 0);
|
|
||||||
if (is_pty[1])
|
|
||||||
SetStdHandle (STD_OUTPUT_HANDLE, h);
|
|
||||||
if (is_pty[2])
|
|
||||||
SetStdHandle (STD_ERROR_HANDLE, h);
|
|
||||||
if (is_pty[1] || is_pty[2])
|
|
||||||
ptys->set_output_handle (h);
|
|
||||||
}
|
|
||||||
|
|
||||||
HANDLE in = GetStdHandle (STD_INPUT_HANDLE);
|
HANDLE in = GetStdHandle (STD_INPUT_HANDLE);
|
||||||
HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE);
|
HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE);
|
||||||
HANDLE err = GetStdHandle (STD_ERROR_HANDLE);
|
HANDLE err = GetStdHandle (STD_ERROR_HANDLE);
|
||||||
|
|
|
@ -2106,19 +2106,22 @@ class fhandler_pty_common: public fhandler_termios
|
||||||
protected:
|
protected:
|
||||||
BOOL process_opost_output (HANDLE h,
|
BOOL process_opost_output (HANDLE h,
|
||||||
const void *ptr, ssize_t& len, bool is_echo);
|
const void *ptr, ssize_t& len, bool is_echo);
|
||||||
bool check_switch_to_pcon (void);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class fhandler_pty_slave: public fhandler_pty_common
|
class fhandler_pty_slave: public fhandler_pty_common
|
||||||
{
|
{
|
||||||
HANDLE inuse; // used to indicate that a tty is in use
|
HANDLE inuse; // used to indicate that a tty is in use
|
||||||
HANDLE output_handle_cyg, io_handle_cyg;
|
HANDLE output_handle_cyg, io_handle_cyg;
|
||||||
|
DWORD pid_restore;
|
||||||
|
|
||||||
/* Helper functions for fchmod and fchown. */
|
/* Helper functions for fchmod and fchown. */
|
||||||
bool fch_open_handles (bool chown);
|
bool fch_open_handles (bool chown);
|
||||||
int fch_set_sd (security_descriptor &sd, bool chown);
|
int fch_set_sd (security_descriptor &sd, bool chown);
|
||||||
void fch_close_handles ();
|
void fch_close_handles ();
|
||||||
|
|
||||||
|
bool try_reattach_pcon ();
|
||||||
|
void restore_reattach_pcon ();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/* Constructor */
|
/* Constructor */
|
||||||
fhandler_pty_slave (int);
|
fhandler_pty_slave (int);
|
||||||
|
@ -2172,7 +2175,6 @@ class fhandler_pty_slave: public fhandler_pty_common
|
||||||
void set_switch_to_pcon (void);
|
void set_switch_to_pcon (void);
|
||||||
void reset_switch_to_pcon (void);
|
void reset_switch_to_pcon (void);
|
||||||
void push_to_pcon_screenbuffer (const char *ptr, size_t len);
|
void push_to_pcon_screenbuffer (const char *ptr, size_t len);
|
||||||
bool has_master_opened (void);
|
|
||||||
void mask_switch_to_pcon (bool mask)
|
void mask_switch_to_pcon (bool mask)
|
||||||
{
|
{
|
||||||
get_ttyp ()->mask_switch_to_pcon = mask;
|
get_ttyp ()->mask_switch_to_pcon = mask;
|
||||||
|
|
|
@ -3136,16 +3136,29 @@ DWORD
|
||||||
fhandler_console::get_console_process_id (DWORD pid, bool match)
|
fhandler_console::get_console_process_id (DWORD pid, bool match)
|
||||||
{
|
{
|
||||||
DWORD tmp;
|
DWORD tmp;
|
||||||
int num = GetConsoleProcessList (&tmp, 1);
|
DWORD num, num_req;
|
||||||
DWORD *list = (DWORD *)
|
num = 1;
|
||||||
HeapAlloc (GetProcessHeap (), 0, num * sizeof (DWORD));
|
num_req = GetConsoleProcessList (&tmp, num);
|
||||||
num = GetConsoleProcessList (list, num);
|
DWORD *list;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
list = (DWORD *)
|
||||||
|
HeapAlloc (GetProcessHeap (), 0, num_req * sizeof (DWORD));
|
||||||
|
num = num_req;
|
||||||
|
num_req = GetConsoleProcessList (list, num);
|
||||||
|
if (num_req > num)
|
||||||
|
HeapFree (GetProcessHeap (), 0, list);
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
num = num_req;
|
||||||
|
|
||||||
tmp = 0;
|
tmp = 0;
|
||||||
for (int i=0; i<num; i++)
|
for (DWORD i=0; i<num; i++)
|
||||||
if ((match && list[i] == pid) || (!match && list[i] != pid))
|
if ((match && list[i] == pid) || (!match && list[i] != pid))
|
||||||
{
|
{
|
||||||
tmp = list[i];
|
tmp = list[i];
|
||||||
//break;
|
break;
|
||||||
}
|
}
|
||||||
HeapFree (GetProcessHeap (), 0, list);
|
HeapFree (GetProcessHeap (), 0, list);
|
||||||
return tmp;
|
return tmp;
|
||||||
|
|
|
@ -71,7 +71,7 @@ struct pipe_reply {
|
||||||
DWORD error;
|
DWORD error;
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool pcon_attached[NTTYS];
|
static int pcon_attached_to = -1;
|
||||||
static bool isHybrid;
|
static bool isHybrid;
|
||||||
|
|
||||||
#if USE_API_HOOK
|
#if USE_API_HOOK
|
||||||
|
@ -85,7 +85,6 @@ set_switch_to_pcon (void)
|
||||||
fhandler_base *fh = cfd;
|
fhandler_base *fh = cfd;
|
||||||
fhandler_pty_slave *ptys = (fhandler_pty_slave *) fh;
|
fhandler_pty_slave *ptys = (fhandler_pty_slave *) fh;
|
||||||
ptys->set_switch_to_pcon ();
|
ptys->set_switch_to_pcon ();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,25 +338,6 @@ fhandler_pty_common::__release_output_mutex (const char *fn, int ln)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool switch_to_pcon_prev;
|
|
||||||
|
|
||||||
bool
|
|
||||||
fhandler_pty_common::check_switch_to_pcon (void)
|
|
||||||
{
|
|
||||||
bool switch_to_pcon_now = get_ttyp ()->switch_to_pcon;
|
|
||||||
if (!isHybrid && !switch_to_pcon_prev && switch_to_pcon_now)
|
|
||||||
{
|
|
||||||
Sleep (40);
|
|
||||||
/* Check again */
|
|
||||||
switch_to_pcon_now = get_ttyp ()->switch_to_pcon;
|
|
||||||
if (switch_to_pcon_now)
|
|
||||||
switch_to_pcon_prev = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
switch_to_pcon_prev = switch_to_pcon_now;
|
|
||||||
return switch_to_pcon_prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Process pty input. */
|
/* Process pty input. */
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -553,7 +533,7 @@ out:
|
||||||
|
|
||||||
fhandler_pty_slave::fhandler_pty_slave (int unit)
|
fhandler_pty_slave::fhandler_pty_slave (int unit)
|
||||||
: fhandler_pty_common (), inuse (NULL), output_handle_cyg (NULL),
|
: fhandler_pty_common (), inuse (NULL), output_handle_cyg (NULL),
|
||||||
io_handle_cyg (NULL)
|
io_handle_cyg (NULL), pid_restore (0)
|
||||||
{
|
{
|
||||||
if (unit >= 0)
|
if (unit >= 0)
|
||||||
dev ().parse (DEV_PTYS_MAJOR, unit);
|
dev ().parse (DEV_PTYS_MAJOR, unit);
|
||||||
|
@ -562,32 +542,33 @@ fhandler_pty_slave::fhandler_pty_slave (int unit)
|
||||||
fhandler_pty_slave::~fhandler_pty_slave ()
|
fhandler_pty_slave::~fhandler_pty_slave ()
|
||||||
{
|
{
|
||||||
if (!get_ttyp ())
|
if (!get_ttyp ())
|
||||||
{
|
/* Why comes here? Who clears _tc? */
|
||||||
/* Why it comes here? */
|
return;
|
||||||
init_console_handler (false);
|
if (getPseudoConsole ())
|
||||||
FreeConsole ();
|
|
||||||
pcon_attached[get_minor ()] = false;
|
|
||||||
}
|
|
||||||
else if (getPseudoConsole ())
|
|
||||||
{
|
{
|
||||||
int used = 0;
|
int used = 0;
|
||||||
|
int attached = 0;
|
||||||
cygheap_fdenum cfd (false);
|
cygheap_fdenum cfd (false);
|
||||||
while (cfd.next () >= 0)
|
while (cfd.next () >= 0)
|
||||||
if (cfd->get_major () == DEV_PTYS_MAJOR &&
|
{
|
||||||
cfd->get_minor () == get_minor ())
|
if (cfd->get_major () == DEV_PTYS_MAJOR ||
|
||||||
used ++;
|
cfd->get_major () == DEV_CONS_MAJOR)
|
||||||
|
used ++;
|
||||||
|
if (cfd->get_major () == DEV_PTYS_MAJOR &&
|
||||||
|
cfd->get_minor () == pcon_attached_to)
|
||||||
|
attached ++;
|
||||||
|
}
|
||||||
|
|
||||||
/* Call FreeConsole() if no pty slave on this pty is
|
/* Call FreeConsole() if no tty is opened and the process
|
||||||
opened and the process is attached to the pseudo
|
is attached to console corresponding to tty. This is
|
||||||
console corresponding to this pty. This is needed
|
needed to make GNU screen and tmux work in Windows 10
|
||||||
to make GNU screen and tmux work in Windows 10 1903. */
|
1903. */
|
||||||
if (used == 0 &&
|
if (attached == 0)
|
||||||
fhandler_console::get_console_process_id (getHelperProcessId (),
|
pcon_attached_to = -1;
|
||||||
true))
|
if (used == 0)
|
||||||
{
|
{
|
||||||
init_console_handler (false);
|
init_console_handler (false);
|
||||||
FreeConsole ();
|
FreeConsole ();
|
||||||
pcon_attached[get_minor ()] = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -771,7 +752,27 @@ fhandler_pty_slave::open (int flags, mode_t)
|
||||||
set_output_handle (to_master_local);
|
set_output_handle (to_master_local);
|
||||||
set_output_handle_cyg (to_master_cyg_local);
|
set_output_handle_cyg (to_master_cyg_local);
|
||||||
|
|
||||||
fhandler_console::need_invisible ();
|
if (!getPseudoConsole ())
|
||||||
|
{
|
||||||
|
fhandler_console::need_invisible ();
|
||||||
|
pcon_attached_to = -1;
|
||||||
|
}
|
||||||
|
else if (!fhandler_console::get_console_process_id
|
||||||
|
(GetCurrentProcessId (), true))
|
||||||
|
{
|
||||||
|
fhandler_console::need_invisible ();
|
||||||
|
pcon_attached_to = -1;
|
||||||
|
}
|
||||||
|
else if (fhandler_console::get_console_process_id
|
||||||
|
(getHelperProcessId (), true))
|
||||||
|
/* Attached to pcon of this pty */
|
||||||
|
{
|
||||||
|
pcon_attached_to = get_minor ();
|
||||||
|
init_console_handler (true);
|
||||||
|
}
|
||||||
|
else if (pcon_attached_to < 0)
|
||||||
|
fhandler_console::need_invisible ();
|
||||||
|
|
||||||
set_open_status ();
|
set_open_status ();
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
@ -824,12 +825,13 @@ fhandler_pty_slave::close ()
|
||||||
if (!ForceCloseHandle (get_handle_cyg ()))
|
if (!ForceCloseHandle (get_handle_cyg ()))
|
||||||
termios_printf ("CloseHandle (get_handle_cyg ()<%p>), %E",
|
termios_printf ("CloseHandle (get_handle_cyg ()<%p>), %E",
|
||||||
get_handle_cyg ());
|
get_handle_cyg ());
|
||||||
if ((unsigned) myself->ctty == FHDEV (DEV_PTYS_MAJOR, get_minor ()))
|
if (!getPseudoConsole () &&
|
||||||
|
(unsigned) myself->ctty == FHDEV (DEV_PTYS_MAJOR, get_minor ()))
|
||||||
fhandler_console::free_console (); /* assumes that we are the last pty closer */
|
fhandler_console::free_console (); /* assumes that we are the last pty closer */
|
||||||
fhandler_pty_common::close ();
|
fhandler_pty_common::close ();
|
||||||
if (!ForceCloseHandle (output_mutex))
|
if (!ForceCloseHandle (output_mutex))
|
||||||
termios_printf ("CloseHandle (output_mutex<%p>), %E", output_mutex);
|
termios_printf ("CloseHandle (output_mutex<%p>), %E", output_mutex);
|
||||||
if (pcon_attached[get_minor ()])
|
if (pcon_attached_to == get_minor ())
|
||||||
get_ttyp ()->num_pcon_attached_slaves --;
|
get_ttyp ()->num_pcon_attached_slaves --;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -874,14 +876,53 @@ fhandler_pty_slave::init (HANDLE h, DWORD a, mode_t)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
fhandler_pty_slave::try_reattach_pcon (void)
|
||||||
|
{
|
||||||
|
pid_restore = 0;
|
||||||
|
|
||||||
|
/* Do not detach from the console because re-attaching will
|
||||||
|
fail if helper process is running as service account. */
|
||||||
|
if (pcon_attached_to >= 0 &&
|
||||||
|
cygwin_shared->tty[pcon_attached_to]->attach_pcon_in_fork)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
pid_restore =
|
||||||
|
fhandler_console::get_console_process_id (GetCurrentProcessId (),
|
||||||
|
false);
|
||||||
|
/* If pid_restore is not set, give up. */
|
||||||
|
if (!pid_restore)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
FreeConsole ();
|
||||||
|
if (!AttachConsole (getHelperProcessId ()))
|
||||||
|
{
|
||||||
|
system_printf ("pty%d: AttachConsole(helper=%d) failed. 0x%08lx",
|
||||||
|
get_minor (), getHelperProcessId (), GetLastError ());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fhandler_pty_slave::restore_reattach_pcon (void)
|
||||||
|
{
|
||||||
|
if (pid_restore)
|
||||||
|
{
|
||||||
|
FreeConsole ();
|
||||||
|
if (!AttachConsole (pid_restore))
|
||||||
|
{
|
||||||
|
system_printf ("pty%d: AttachConsole(restore=%d) failed. 0x%08lx",
|
||||||
|
get_minor (), pid_restore, GetLastError ());
|
||||||
|
pcon_attached_to = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pid_restore = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fhandler_pty_slave::set_switch_to_pcon (void)
|
fhandler_pty_slave::set_switch_to_pcon (void)
|
||||||
{
|
{
|
||||||
if (!pcon_attached[get_minor ()])
|
|
||||||
{
|
|
||||||
isHybrid = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!isHybrid)
|
if (!isHybrid)
|
||||||
{
|
{
|
||||||
reset_switch_to_pcon ();
|
reset_switch_to_pcon ();
|
||||||
|
@ -889,6 +930,16 @@ fhandler_pty_slave::set_switch_to_pcon (void)
|
||||||
}
|
}
|
||||||
if (!get_ttyp ()->switch_to_pcon)
|
if (!get_ttyp ()->switch_to_pcon)
|
||||||
{
|
{
|
||||||
|
pid_restore = 0;
|
||||||
|
if (pcon_attached_to != get_minor ())
|
||||||
|
if (!try_reattach_pcon ())
|
||||||
|
goto skip_console_setting;
|
||||||
|
FlushConsoleInputBuffer (get_handle ());
|
||||||
|
DWORD mode;
|
||||||
|
GetConsoleMode (get_handle (), &mode);
|
||||||
|
SetConsoleMode (get_handle (), mode | ENABLE_ECHO_INPUT);
|
||||||
|
skip_console_setting:
|
||||||
|
restore_reattach_pcon ();
|
||||||
Sleep (20);
|
Sleep (20);
|
||||||
if (get_ttyp ()->pcon_pid == 0 ||
|
if (get_ttyp ()->pcon_pid == 0 ||
|
||||||
kill (get_ttyp ()->pcon_pid, 0) != 0)
|
kill (get_ttyp ()->pcon_pid, 0) != 0)
|
||||||
|
@ -904,7 +955,7 @@ fhandler_pty_slave::reset_switch_to_pcon (void)
|
||||||
return;
|
return;
|
||||||
if (isHybrid)
|
if (isHybrid)
|
||||||
{
|
{
|
||||||
set_switch_to_pcon ();
|
this->set_switch_to_pcon ();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (get_ttyp ()->pcon_pid &&
|
if (get_ttyp ()->pcon_pid &&
|
||||||
|
@ -918,7 +969,7 @@ fhandler_pty_slave::reset_switch_to_pcon (void)
|
||||||
DWORD mode;
|
DWORD mode;
|
||||||
GetConsoleMode (get_handle (), &mode);
|
GetConsoleMode (get_handle (), &mode);
|
||||||
SetConsoleMode (get_handle (), mode & ~ENABLE_ECHO_INPUT);
|
SetConsoleMode (get_handle (), mode & ~ENABLE_ECHO_INPUT);
|
||||||
Sleep (60); /* Wait for pty_master_fwd_thread() */
|
Sleep (20); /* Wait for pty_master_fwd_thread() */
|
||||||
}
|
}
|
||||||
get_ttyp ()->pcon_pid = 0;
|
get_ttyp ()->pcon_pid = 0;
|
||||||
get_ttyp ()->switch_to_pcon = false;
|
get_ttyp ()->switch_to_pcon = false;
|
||||||
|
@ -927,43 +978,31 @@ fhandler_pty_slave::reset_switch_to_pcon (void)
|
||||||
void
|
void
|
||||||
fhandler_pty_slave::push_to_pcon_screenbuffer (const char *ptr, size_t len)
|
fhandler_pty_slave::push_to_pcon_screenbuffer (const char *ptr, size_t len)
|
||||||
{
|
{
|
||||||
DWORD pidRestore = 0;
|
bool attached =
|
||||||
if (!fhandler_console::get_console_process_id (getHelperProcessId (), true))
|
!!fhandler_console::get_console_process_id (getHelperProcessId (), true);
|
||||||
if (pcon_attached[get_minor ()])
|
if (!attached && pcon_attached_to == get_minor ())
|
||||||
{
|
|
||||||
Sleep (20);
|
|
||||||
/* Check again */
|
|
||||||
if (!fhandler_console::get_console_process_id
|
|
||||||
(getHelperProcessId (), true))
|
|
||||||
{
|
|
||||||
system_printf ("pty%d: pcon_attach mismatch?????? (%p)",
|
|
||||||
get_minor (), this);
|
|
||||||
//pcon_attached[get_minor ()] = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* If not attached pseudo console yet, try to attach temporally. */
|
|
||||||
if (!pcon_attached[get_minor ()])
|
|
||||||
{
|
{
|
||||||
if (has_master_opened ())
|
for (DWORD t0 = GetTickCount (); GetTickCount () - t0 < 100; )
|
||||||
return;
|
|
||||||
|
|
||||||
pidRestore =
|
|
||||||
fhandler_console::get_console_process_id (GetCurrentProcessId (),
|
|
||||||
false);
|
|
||||||
/* If pidRestore is not set, give up to push. */
|
|
||||||
if (!pidRestore)
|
|
||||||
return;
|
|
||||||
|
|
||||||
FreeConsole ();
|
|
||||||
if (!AttachConsole (getHelperProcessId ()))
|
|
||||||
{
|
{
|
||||||
system_printf ("pty%d: AttachConsole(%d) failed. (%p) %08lx",
|
Sleep (1);
|
||||||
get_minor (), getHelperProcessId (),
|
attached = fhandler_console::get_console_process_id
|
||||||
this, GetLastError ());
|
(getHelperProcessId (), true);
|
||||||
goto detach;
|
if (attached)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!attached)
|
||||||
|
{
|
||||||
|
system_printf ("pty%d: pcon_attach_to mismatch??????", get_minor ());
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If not attached to this pseudo console, try to attach temporarily. */
|
||||||
|
pid_restore = 0;
|
||||||
|
if (pcon_attached_to != get_minor ())
|
||||||
|
if (!try_reattach_pcon ())
|
||||||
|
goto detach;
|
||||||
|
|
||||||
char *buf;
|
char *buf;
|
||||||
size_t nlen;
|
size_t nlen;
|
||||||
DWORD origCP;
|
DWORD origCP;
|
||||||
|
@ -1005,7 +1044,7 @@ fhandler_pty_slave::push_to_pcon_screenbuffer (const char *ptr, size_t len)
|
||||||
}
|
}
|
||||||
if (!nlen) /* Nothing to be synchronized */
|
if (!nlen) /* Nothing to be synchronized */
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
if (check_switch_to_pcon ())
|
if (get_ttyp ()->switch_to_pcon)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
/* Remove ESC sequence which returns results to console
|
/* Remove ESC sequence which returns results to console
|
||||||
input buffer. Without this, cursor position report
|
input buffer. Without this, cursor position report
|
||||||
|
@ -1060,27 +1099,7 @@ cleanup:
|
||||||
SetConsoleOutputCP (origCP);
|
SetConsoleOutputCP (origCP);
|
||||||
HeapFree (GetProcessHeap (), 0, buf);
|
HeapFree (GetProcessHeap (), 0, buf);
|
||||||
detach:
|
detach:
|
||||||
if (!pcon_attached[get_minor ()])
|
restore_reattach_pcon ();
|
||||||
{
|
|
||||||
FreeConsole ();
|
|
||||||
if (!AttachConsole (pidRestore))
|
|
||||||
{
|
|
||||||
system_printf ("pty%d: AttachConsole(%d) failed. (%p) %08lx",
|
|
||||||
get_minor (), pidRestore, this, GetLastError ());
|
|
||||||
pcon_attached[get_minor ()] = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
fhandler_pty_slave::has_master_opened (void)
|
|
||||||
{
|
|
||||||
cygheap_fdenum cfd (false);
|
|
||||||
while (cfd.next () >= 0)
|
|
||||||
if (cfd->get_major () == DEV_PTYM_MAJOR &&
|
|
||||||
cfd->get_minor () == get_minor ())
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t __stdcall
|
ssize_t __stdcall
|
||||||
|
@ -1100,7 +1119,7 @@ fhandler_pty_slave::write (const void *ptr, size_t len)
|
||||||
|
|
||||||
char *buf;
|
char *buf;
|
||||||
ssize_t nlen;
|
ssize_t nlen;
|
||||||
UINT targetCodePage = (check_switch_to_pcon ()) ?
|
UINT targetCodePage = get_ttyp ()->switch_to_pcon ?
|
||||||
GetConsoleOutputCP () : get_ttyp ()->TermCodePage;
|
GetConsoleOutputCP () : get_ttyp ()->TermCodePage;
|
||||||
if (targetCodePage != get_ttyp ()->TermCodePage)
|
if (targetCodePage != get_ttyp ()->TermCodePage)
|
||||||
{
|
{
|
||||||
|
@ -1127,18 +1146,25 @@ fhandler_pty_slave::write (const void *ptr, size_t len)
|
||||||
nlen = len;
|
nlen = len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If not attached to this pseudo console, try to attach temporarily. */
|
||||||
|
pid_restore = 0;
|
||||||
|
bool fallback = false;
|
||||||
|
if (get_ttyp ()->switch_to_pcon && pcon_attached_to != get_minor ())
|
||||||
|
if (!try_reattach_pcon ())
|
||||||
|
fallback = true;
|
||||||
|
|
||||||
DWORD dwMode, flags;
|
DWORD dwMode, flags;
|
||||||
flags = ENABLE_VIRTUAL_TERMINAL_PROCESSING;
|
flags = ENABLE_VIRTUAL_TERMINAL_PROCESSING;
|
||||||
if (!(get_ttyp ()->ti.c_oflag & OPOST) ||
|
if (!(get_ttyp ()->ti.c_oflag & OPOST) ||
|
||||||
!(get_ttyp ()->ti.c_oflag & ONLCR))
|
!(get_ttyp ()->ti.c_oflag & ONLCR))
|
||||||
flags |= DISABLE_NEWLINE_AUTO_RETURN;
|
flags |= DISABLE_NEWLINE_AUTO_RETURN;
|
||||||
if (check_switch_to_pcon ())
|
if (get_ttyp ()->switch_to_pcon && !fallback)
|
||||||
{
|
{
|
||||||
GetConsoleMode (get_output_handle (), &dwMode);
|
GetConsoleMode (get_output_handle (), &dwMode);
|
||||||
SetConsoleMode (get_output_handle (), dwMode | flags);
|
SetConsoleMode (get_output_handle (), dwMode | flags);
|
||||||
}
|
}
|
||||||
HANDLE to =
|
HANDLE to = (get_ttyp ()->switch_to_pcon && !fallback) ?
|
||||||
check_switch_to_pcon () ? get_output_handle () : get_output_handle_cyg ();
|
get_output_handle () : get_output_handle_cyg ();
|
||||||
acquire_output_mutex (INFINITE);
|
acquire_output_mutex (INFINITE);
|
||||||
if (!process_opost_output (to, buf, nlen, false))
|
if (!process_opost_output (to, buf, nlen, false))
|
||||||
{
|
{
|
||||||
|
@ -1157,8 +1183,10 @@ fhandler_pty_slave::write (const void *ptr, size_t len)
|
||||||
release_output_mutex ();
|
release_output_mutex ();
|
||||||
HeapFree (GetProcessHeap (), 0, buf);
|
HeapFree (GetProcessHeap (), 0, buf);
|
||||||
flags = ENABLE_VIRTUAL_TERMINAL_PROCESSING;
|
flags = ENABLE_VIRTUAL_TERMINAL_PROCESSING;
|
||||||
if (check_switch_to_pcon ())
|
if (get_ttyp ()->switch_to_pcon && !fallback)
|
||||||
SetConsoleMode (get_output_handle (), dwMode | flags);
|
SetConsoleMode (get_output_handle (), dwMode);
|
||||||
|
|
||||||
|
restore_reattach_pcon ();
|
||||||
|
|
||||||
/* Push slave output to pseudo console screen buffer */
|
/* Push slave output to pseudo console screen buffer */
|
||||||
if (getPseudoConsole ())
|
if (getPseudoConsole ())
|
||||||
|
@ -1299,9 +1327,15 @@ fhandler_pty_slave::read (void *ptr, size_t& len)
|
||||||
}
|
}
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (check_switch_to_pcon () &&
|
if (get_ttyp ()->switch_to_pcon &&
|
||||||
!get_ttyp ()->mask_switch_to_pcon)
|
(!get_ttyp ()->mask_switch_to_pcon || ALWAYS_USE_PCON))
|
||||||
{
|
{
|
||||||
|
if (!try_reattach_pcon ())
|
||||||
|
{
|
||||||
|
restore_reattach_pcon ();
|
||||||
|
goto do_read_cyg;
|
||||||
|
}
|
||||||
|
|
||||||
DWORD dwMode;
|
DWORD dwMode;
|
||||||
GetConsoleMode (get_handle (), &dwMode);
|
GetConsoleMode (get_handle (), &dwMode);
|
||||||
DWORD flags = ENABLE_VIRTUAL_TERMINAL_INPUT;
|
DWORD flags = ENABLE_VIRTUAL_TERMINAL_INPUT;
|
||||||
|
@ -1344,8 +1378,13 @@ fhandler_pty_slave::read (void *ptr, size_t& len)
|
||||||
ResetEvent (input_available_event);
|
ResetEvent (input_available_event);
|
||||||
ReleaseMutex (input_mutex);
|
ReleaseMutex (input_mutex);
|
||||||
len = rlen;
|
len = rlen;
|
||||||
|
|
||||||
|
restore_reattach_pcon ();
|
||||||
|
mask_switch_to_pcon (false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
do_read_cyg:
|
||||||
if (!bytes_available (bytes_in_pipe))
|
if (!bytes_available (bytes_in_pipe))
|
||||||
{
|
{
|
||||||
ReleaseMutex (input_mutex);
|
ReleaseMutex (input_mutex);
|
||||||
|
@ -1611,31 +1650,13 @@ fhandler_pty_slave::ioctl (unsigned int cmd, void *arg)
|
||||||
case TIOCSWINSZ:
|
case TIOCSWINSZ:
|
||||||
if (getPseudoConsole ())
|
if (getPseudoConsole ())
|
||||||
{
|
{
|
||||||
/* If not attached pseudo console yet, try to attach
|
/* If not attached to this pseudo console,
|
||||||
temporally. */
|
try to attach temporarily. */
|
||||||
DWORD pidRestore = 0;
|
pid_restore = 0;
|
||||||
if (!pcon_attached[get_minor ()])
|
if (pcon_attached_to != get_minor ())
|
||||||
{
|
if (!try_reattach_pcon ())
|
||||||
if (has_master_opened () && get_ttyp ()->attach_pcon_in_fork)
|
goto cleanup;
|
||||||
goto resize_cyg;
|
|
||||||
|
|
||||||
pidRestore = fhandler_console::get_console_process_id
|
|
||||||
(GetCurrentProcessId (), false);
|
|
||||||
|
|
||||||
/* This happens at mintty startup if fhandler_console::
|
|
||||||
need_invisible() is called in stdio_init() in dtable.cc */
|
|
||||||
if (!pidRestore) /* Give up to resize pseudo console */
|
|
||||||
goto resize_cyg;
|
|
||||||
|
|
||||||
FreeConsole ();
|
|
||||||
if (!AttachConsole (getHelperProcessId ()))
|
|
||||||
{
|
|
||||||
system_printf ("pty%d: AttachConsole(%d) failed. (%p) %08lx",
|
|
||||||
get_minor(), getHelperProcessId (),
|
|
||||||
this, GetLastError ());
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
COORD size;
|
COORD size;
|
||||||
size.X = ((struct winsize *) arg)->ws_col;
|
size.X = ((struct winsize *) arg)->ws_col;
|
||||||
size.Y = ((struct winsize *) arg)->ws_row;
|
size.Y = ((struct winsize *) arg)->ws_row;
|
||||||
|
@ -1653,20 +1674,9 @@ fhandler_pty_slave::ioctl (unsigned int cmd, void *arg)
|
||||||
rect.Bottom = size.Y-1;
|
rect.Bottom = size.Y-1;
|
||||||
SetConsoleWindowInfo (get_output_handle (), TRUE, &rect);
|
SetConsoleWindowInfo (get_output_handle (), TRUE, &rect);
|
||||||
cleanup:
|
cleanup:
|
||||||
/* Detach from pseudo console and resume. */
|
restore_reattach_pcon ();
|
||||||
if (pidRestore)
|
|
||||||
{
|
|
||||||
FreeConsole ();
|
|
||||||
if (!AttachConsole (pidRestore))
|
|
||||||
{
|
|
||||||
system_printf ("pty%d: AttachConsole(%d) failed. (%p) %08lx",
|
|
||||||
get_minor (), pidRestore,
|
|
||||||
this, GetLastError ());
|
|
||||||
pcon_attached[get_minor ()] = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
resize_cyg:
|
|
||||||
if (get_ttyp ()->winsize.ws_row != ((struct winsize *) arg)->ws_row
|
if (get_ttyp ()->winsize.ws_row != ((struct winsize *) arg)->ws_row
|
||||||
|| get_ttyp ()->winsize.ws_col != ((struct winsize *) arg)->ws_col)
|
|| get_ttyp ()->winsize.ws_col != ((struct winsize *) arg)->ws_col)
|
||||||
{
|
{
|
||||||
|
@ -2042,7 +2052,6 @@ fhandler_pty_master::close ()
|
||||||
ClosePseudoConsole = (VOID (WINAPI *) (HPCON)) func;
|
ClosePseudoConsole = (VOID (WINAPI *) (HPCON)) func;
|
||||||
ClosePseudoConsole (getPseudoConsole ());
|
ClosePseudoConsole (getPseudoConsole ());
|
||||||
}
|
}
|
||||||
get_ttyp ()->hPseudoConsole = NULL;
|
|
||||||
get_ttyp ()->switch_to_pcon = false;
|
get_ttyp ()->switch_to_pcon = false;
|
||||||
}
|
}
|
||||||
if (get_ttyp ()->getsid () > 0)
|
if (get_ttyp ()->getsid () > 0)
|
||||||
|
@ -2096,8 +2105,8 @@ fhandler_pty_master::write (const void *ptr, size_t len)
|
||||||
|
|
||||||
/* Write terminal input to to_slave pipe instead of output_handle
|
/* Write terminal input to to_slave pipe instead of output_handle
|
||||||
if current application is native console application. */
|
if current application is native console application. */
|
||||||
if (check_switch_to_pcon () &&
|
if (get_ttyp ()->switch_to_pcon &&
|
||||||
!get_ttyp ()->mask_switch_to_pcon)
|
(!get_ttyp ()->mask_switch_to_pcon || ALWAYS_USE_PCON))
|
||||||
{
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
size_t nlen;
|
size_t nlen;
|
||||||
|
@ -2702,8 +2711,9 @@ fhandler_pty_slave::fixup_after_attach (bool native_maybe)
|
||||||
if (fhandler_console::get_console_process_id (getHelperProcessId (),
|
if (fhandler_console::get_console_process_id (getHelperProcessId (),
|
||||||
true))
|
true))
|
||||||
{
|
{
|
||||||
if (!pcon_attached[get_minor ()])
|
if (pcon_attached_to != get_minor ())
|
||||||
{
|
{
|
||||||
|
pcon_attached_to = get_minor ();
|
||||||
init_console_handler (true);
|
init_console_handler (true);
|
||||||
#if USE_OWN_NLS_FUNC
|
#if USE_OWN_NLS_FUNC
|
||||||
char locale[ENCODING_LEN + 1] = "C";
|
char locale[ENCODING_LEN + 1] = "C";
|
||||||
|
@ -2786,19 +2796,20 @@ fhandler_pty_slave::fixup_after_attach (bool native_maybe)
|
||||||
WriteFile (get_output_handle_cyg (),
|
WriteFile (get_output_handle_cyg (),
|
||||||
"\033[H\033[J", 6, &n, NULL);
|
"\033[H\033[J", 6, &n, NULL);
|
||||||
|
|
||||||
pcon_attached[get_minor ()] = true;
|
|
||||||
get_ttyp ()->num_pcon_attached_slaves ++;
|
get_ttyp ()->num_pcon_attached_slaves ++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
pcon_attached[get_minor ()] = false;
|
|
||||||
}
|
}
|
||||||
if (pcon_attached[get_minor ()] && native_maybe)
|
if (pcon_attached_to == get_minor () && (native_maybe || ALWAYS_USE_PCON))
|
||||||
{
|
{
|
||||||
FlushConsoleInputBuffer (get_handle ());
|
FlushConsoleInputBuffer (get_handle ());
|
||||||
DWORD mode;
|
DWORD mode;
|
||||||
GetConsoleMode (get_handle (), &mode);
|
GetConsoleMode (get_handle (), &mode);
|
||||||
SetConsoleMode (get_handle (), mode | ENABLE_ECHO_INPUT);
|
SetConsoleMode (get_handle (),
|
||||||
|
(mode & ~ENABLE_VIRTUAL_TERMINAL_INPUT) |
|
||||||
|
ENABLE_ECHO_INPUT |
|
||||||
|
ENABLE_LINE_INPUT |
|
||||||
|
ENABLE_PROCESSED_INPUT);
|
||||||
Sleep (20);
|
Sleep (20);
|
||||||
if (get_ttyp ()->pcon_pid == 0 ||
|
if (get_ttyp ()->pcon_pid == 0 ||
|
||||||
kill (get_ttyp ()->pcon_pid, 0) != 0)
|
kill (get_ttyp ()->pcon_pid, 0) != 0)
|
||||||
|
@ -2826,23 +2837,28 @@ fhandler_pty_slave::fixup_after_exec ()
|
||||||
else if (getPseudoConsole ())
|
else if (getPseudoConsole ())
|
||||||
{
|
{
|
||||||
int used = 0;
|
int used = 0;
|
||||||
|
int attached = 0;
|
||||||
cygheap_fdenum cfd (false);
|
cygheap_fdenum cfd (false);
|
||||||
while (cfd.next () >= 0)
|
while (cfd.next () >= 0)
|
||||||
if (cfd->get_major () == DEV_PTYS_MAJOR &&
|
{
|
||||||
cfd->get_minor () == get_minor ())
|
if (cfd->get_major () == DEV_PTYS_MAJOR ||
|
||||||
used ++;
|
cfd->get_major () == DEV_CONS_MAJOR)
|
||||||
|
used ++;
|
||||||
|
if (cfd->get_major () == DEV_PTYS_MAJOR &&
|
||||||
|
cfd->get_minor () == pcon_attached_to)
|
||||||
|
attached ++;
|
||||||
|
}
|
||||||
|
|
||||||
/* Call FreeConsole() if no pty slave on this pty is
|
/* Call FreeConsole() if no tty is opened and the process
|
||||||
opened and the process is attached to the pseudo
|
is attached to console corresponding to tty. This is
|
||||||
console corresponding to this pty. This is needed
|
needed to make GNU screen and tmux work in Windows 10
|
||||||
to make GNU screen and tmux work in Windows 10 1903. */
|
1903. */
|
||||||
if (used == 1 /* About to close this one */ &&
|
if (attached == 1 && get_minor () == pcon_attached_to)
|
||||||
fhandler_console::get_console_process_id (getHelperProcessId (),
|
pcon_attached_to = -1;
|
||||||
true))
|
if (used == 1 /* About to close this tty */)
|
||||||
{
|
{
|
||||||
init_console_handler (false);
|
init_console_handler (false);
|
||||||
FreeConsole ();
|
FreeConsole ();
|
||||||
pcon_attached[get_minor ()] = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3049,7 +3065,7 @@ fhandler_pty_master::pty_master_fwd_thread ()
|
||||||
{
|
{
|
||||||
/* Avoid duplicating slave output which is already sent to
|
/* Avoid duplicating slave output which is already sent to
|
||||||
to_master_cyg */
|
to_master_cyg */
|
||||||
if (!check_switch_to_pcon ())
|
if (!get_ttyp ()->switch_to_pcon)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Avoid setting window title to "cygwin-console-helper.exe" */
|
/* Avoid setting window title to "cygwin-console-helper.exe" */
|
||||||
|
@ -3064,25 +3080,42 @@ fhandler_pty_master::pty_master_fwd_thread ()
|
||||||
}
|
}
|
||||||
else if ((state == 1 && outbuf[i] == ']') ||
|
else if ((state == 1 && outbuf[i] == ']') ||
|
||||||
(state == 2 && outbuf[i] == '0') ||
|
(state == 2 && outbuf[i] == '0') ||
|
||||||
(state == 3 && outbuf[i] == ';') ||
|
(state == 3 && outbuf[i] == ';'))
|
||||||
(state == 4 && outbuf[i] == '\0'))
|
|
||||||
{
|
{
|
||||||
state ++;
|
state ++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (state == 5 && outbuf[i] == '\a')
|
else if (state == 4 && outbuf[i] == '\a')
|
||||||
{
|
{
|
||||||
memmove (&outbuf[start_at], &outbuf[i+1], rlen-i-1);
|
memmove (&outbuf[start_at], &outbuf[i+1], rlen-i-1);
|
||||||
state = 0;
|
state = 0;
|
||||||
rlen = wlen = start_at + rlen - i - 1;
|
rlen = wlen = start_at + rlen - i - 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (state != 4 || outbuf[i] == '\a')
|
else if (outbuf[i] == '\a')
|
||||||
{
|
{
|
||||||
state = 0;
|
state = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Remove ESC sequence which returns results to console
|
||||||
|
input buffer. Without this, cursor position report
|
||||||
|
is put into the input buffer as a garbage. */
|
||||||
|
/* Remove ESC sequence to report cursor position. */
|
||||||
|
char *p0;
|
||||||
|
while ((p0 = (char *) memmem (outbuf, rlen, "\033[6n", 4)))
|
||||||
|
{
|
||||||
|
memmove (p0, p0+4, rlen - (p0+4 - outbuf));
|
||||||
|
rlen -= 4;
|
||||||
|
}
|
||||||
|
/* Remove ESC sequence to report terminal identity. */
|
||||||
|
while ((p0 = (char *) memmem (outbuf, rlen, "\033[0c", 4)))
|
||||||
|
{
|
||||||
|
memmove (p0, p0+4, rlen - (p0+4 - outbuf));
|
||||||
|
rlen -= 4;
|
||||||
|
}
|
||||||
|
wlen = rlen;
|
||||||
|
|
||||||
char *buf;
|
char *buf;
|
||||||
size_t nlen;
|
size_t nlen;
|
||||||
if (get_ttyp ()->TermCodePage != CP_UTF8)
|
if (get_ttyp ()->TermCodePage != CP_UTF8)
|
||||||
|
|
|
@ -140,20 +140,24 @@ frok::child (volatile char * volatile here)
|
||||||
{
|
{
|
||||||
fhandler_base *fh = cfd;
|
fhandler_base *fh = cfd;
|
||||||
fhandler_pty_master *ptym = (fhandler_pty_master *) fh;
|
fhandler_pty_master *ptym = (fhandler_pty_master *) fh;
|
||||||
if (ptym->getPseudoConsole () &&
|
if (ptym->getPseudoConsole ())
|
||||||
!fhandler_console::get_console_process_id (
|
|
||||||
ptym->getHelperProcessId (), true))
|
|
||||||
|
|
||||||
{
|
{
|
||||||
debug_printf ("found a PTY master %d: helper_PID=%d",
|
debug_printf ("found a PTY master %d: helper_PID=%d",
|
||||||
ptym->get_minor (), ptym->getHelperProcessId ());
|
ptym->get_minor (), ptym->getHelperProcessId ());
|
||||||
if (ptym->attach_pcon_in_fork ())
|
if (fhandler_console::get_console_process_id (
|
||||||
|
ptym->getHelperProcessId (), true))
|
||||||
|
/* Already attached */
|
||||||
|
break;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
FreeConsole ();
|
if (ptym->attach_pcon_in_fork ())
|
||||||
if (!AttachConsole (ptym->getHelperProcessId ()))
|
{
|
||||||
/* Error */;
|
FreeConsole ();
|
||||||
else
|
if (!AttachConsole (ptym->getHelperProcessId ()))
|
||||||
break;
|
/* Error */;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -578,53 +578,62 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
|
||||||
pidRestore = fhandler_console::get_console_process_id
|
pidRestore = fhandler_console::get_console_process_id
|
||||||
(GetCurrentProcessId (), false);
|
(GetCurrentProcessId (), false);
|
||||||
fhandler_pty_slave *ptys = NULL;
|
fhandler_pty_slave *ptys = NULL;
|
||||||
for (int fd = 0; fd < 3; fd ++)
|
int chk_order[] = {1, 0, 2};
|
||||||
|
for (int i = 0; i < 3; i ++)
|
||||||
{
|
{
|
||||||
|
int fd = chk_order[i];
|
||||||
fhandler_base *fh = ::cygheap->fdtab[fd];
|
fhandler_base *fh = ::cygheap->fdtab[fd];
|
||||||
if (fh && fh->get_major () == DEV_PTYS_MAJOR)
|
if (fh && fh->get_major () == DEV_PTYS_MAJOR)
|
||||||
{
|
{
|
||||||
ptys = (fhandler_pty_slave *) fh;
|
ptys = (fhandler_pty_slave *) fh;
|
||||||
if (ptys->getPseudoConsole () &&
|
if (ptys->getPseudoConsole ())
|
||||||
!fhandler_console::get_console_process_id (
|
|
||||||
ptys->getHelperProcessId (), true))
|
|
||||||
{
|
{
|
||||||
DWORD dwHelperProcessId = ptys->getHelperProcessId ();
|
DWORD dwHelperProcessId = ptys->getHelperProcessId ();
|
||||||
debug_printf ("found a PTY slave %d: helper_PID=%d",
|
debug_printf ("found a PTY slave %d: helper_PID=%d",
|
||||||
fh->get_minor (), dwHelperProcessId);
|
fh->get_minor (), dwHelperProcessId);
|
||||||
FreeConsole ();
|
if (fhandler_console::get_console_process_id
|
||||||
if (!AttachConsole (dwHelperProcessId))
|
(dwHelperProcessId, true))
|
||||||
{
|
{
|
||||||
/* Fallback */
|
/* Already attached */
|
||||||
DWORD target[3] = {
|
attach_to_pcon = true;
|
||||||
STD_INPUT_HANDLE,
|
break;
|
||||||
STD_OUTPUT_HANDLE,
|
|
||||||
STD_ERROR_HANDLE
|
|
||||||
};
|
|
||||||
if (fd == 0)
|
|
||||||
{
|
|
||||||
ptys->set_handle (ptys->get_handle_cyg ());
|
|
||||||
SetStdHandle (target[fd],
|
|
||||||
ptys->get_handle ());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ptys->set_output_handle (
|
|
||||||
ptys->get_output_handle_cyg ());
|
|
||||||
SetStdHandle (target[fd],
|
|
||||||
ptys->get_output_handle ());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
init_console_handler (true);
|
FreeConsole ();
|
||||||
attach_to_pcon = true;
|
if (AttachConsole (dwHelperProcessId))
|
||||||
break;
|
{
|
||||||
|
attach_to_pcon = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Fallback */
|
||||||
|
DWORD target[3] = {
|
||||||
|
STD_INPUT_HANDLE,
|
||||||
|
STD_OUTPUT_HANDLE,
|
||||||
|
STD_ERROR_HANDLE
|
||||||
|
};
|
||||||
|
if (fd == 0)
|
||||||
|
{
|
||||||
|
ptys->set_handle (ptys->get_handle_cyg ());
|
||||||
|
SetStdHandle (target[fd],
|
||||||
|
ptys->get_handle ());
|
||||||
|
}
|
||||||
|
else if (fd < 3)
|
||||||
|
{
|
||||||
|
ptys->set_output_handle (
|
||||||
|
ptys->get_output_handle_cyg ());
|
||||||
|
SetStdHandle (target[fd],
|
||||||
|
ptys->get_output_handle ());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ptys)
|
if (ptys)
|
||||||
ptys->fixup_after_attach (true);
|
ptys->fixup_after_attach (!iscygwin ());
|
||||||
|
|
||||||
loop:
|
loop:
|
||||||
/* When ruid != euid we create the new process under the current original
|
/* When ruid != euid we create the new process under the current original
|
||||||
|
|
Loading…
Reference in New Issue