Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/dtable.cc32
-rw-r--r--winsup/cygwin/fhandler.h53
-rw-r--r--winsup/cygwin/fhandler_console.cc43
-rw-r--r--winsup/cygwin/fhandler_tty.cc1750
-rw-r--r--winsup/cygwin/fork.cc30
-rw-r--r--winsup/cygwin/select.cc5
-rw-r--r--winsup/cygwin/smallprint.cc2
-rw-r--r--winsup/cygwin/spawn.cc105
-rw-r--r--winsup/cygwin/strace.cc2
-rw-r--r--winsup/cygwin/tty.cc20
-rw-r--r--winsup/cygwin/tty.h13
-rw-r--r--winsup/cygwin/winsup.h3
12 files changed, 339 insertions, 1719 deletions
diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc
index e9e005b08..6a91e33bc 100644
--- a/winsup/cygwin/dtable.cc
+++ b/winsup/cygwin/dtable.cc
@@ -147,38 +147,6 @@ dtable::get_debugger_info ()
void
dtable::stdio_init ()
{
- for (int i = 0; i < 3; i ++)
- {
- const int chk_order[] = {1, 0, 2};
- int fd = chk_order[i];
- fhandler_base *fh = cygheap->fdtab[fd];
- if (fh && fh->get_major () == DEV_PTYS_MAJOR)
- {
- fhandler_pty_slave *ptys = (fhandler_pty_slave *) fh;
- if (ptys->get_pseudo_console ())
- {
- bool attached = !!fhandler_console::get_console_process_id
- (ptys->get_helper_process_id (), true);
- if (attached)
- break;
- else
- {
- /* Not attached to pseudo console in fork() or spawn()
- by some reason. This happens if the executable is
- a windows GUI binary, such as mintty. */
- FreeConsole ();
- if (AttachConsole (ptys->get_helper_process_id ()))
- {
- ptys->fixup_after_attach (false, fd);
- break;
- }
- }
- }
- }
- else if (fh && fh->get_major () == DEV_CONS_MAJOR)
- break;
- }
-
if (myself->cygstarted || ISSTATE (myself, PID_CYGPARENT))
{
tty_min *t = cygwin_shared->tty.get_cttyp ();
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index a577ca542..9fd95c098 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -326,16 +326,16 @@ class fhandler_base
virtual size_t &raixput () { return ra.raixput; };
virtual size_t &rabuflen () { return ra.rabuflen; };
- virtual bool get_readahead_valid () { return raixget () < ralen (); }
+ bool get_readahead_valid () { return raixget () < ralen (); }
int puts_readahead (const char *s, size_t len = (size_t) -1);
- virtual int put_readahead (char value);
+ int put_readahead (char value);
int get_readahead ();
int peek_readahead (int queryput = 0);
void set_readahead_valid (int val, int ch = -1);
- virtual int get_readahead_into_buffer (char *buf, size_t buflen);
+ int get_readahead_into_buffer (char *buf, size_t buflen);
bool has_acls () const { return pc.has_acls (); }
@@ -1905,7 +1905,7 @@ class fhandler_termios: public fhandler_base
int ioctl (int, void *);
tty_min *_tc;
tty *get_ttyp () {return (tty *) tc ();}
- virtual int eat_readahead (int n);
+ int eat_readahead (int n);
public:
tty_min*& tc () {return _tc;}
@@ -2184,7 +2184,6 @@ private:
static bool need_invisible ();
static void free_console ();
static const char *get_nonascii_key (INPUT_RECORD& input_rec, char *);
- static DWORD get_console_process_id (DWORD pid, bool match);
fhandler_console (void *) {}
@@ -2264,19 +2263,7 @@ class fhandler_pty_common: public fhandler_termios
return fh;
}
- bool attach_pcon_in_fork (void)
- {
- return get_ttyp ()->attach_pcon_in_fork;
- }
- DWORD get_helper_process_id (void)
- {
- return get_ttyp ()->helper_process_id;
- }
- HPCON get_pseudo_console (void)
- {
- return get_ttyp ()->h_pseudo_console;
- }
- bool to_be_read_from_pcon (void);
+ void resize_pseudo_console (struct winsize *);
protected:
BOOL process_opost_output (HANDLE h,
@@ -2287,23 +2274,15 @@ class fhandler_pty_slave: public fhandler_pty_common
{
HANDLE inuse; // used to indicate that a tty is in use
HANDLE output_handle_cyg, io_handle_cyg;
- DWORD pid_restore;
- int fd;
/* Helper functions for fchmod and fchown. */
bool fch_open_handles (bool chown);
int fch_set_sd (security_descriptor &sd, bool chown);
void fch_close_handles ();
- bool try_reattach_pcon ();
- void restore_reattach_pcon ();
- inline void free_attached_console ();
-
public:
/* Constructor */
fhandler_pty_slave (int);
- /* Destructor */
- ~fhandler_pty_slave ();
void set_output_handle_cyg (HANDLE h) { output_handle_cyg = h; }
HANDLE& get_output_handle_cyg () { return output_handle_cyg; }
@@ -2315,9 +2294,6 @@ class fhandler_pty_slave: public fhandler_pty_common
ssize_t __stdcall write (const void *ptr, size_t len);
void __reg3 read (void *ptr, size_t& len);
int init (HANDLE, DWORD, mode_t);
- int eat_readahead (int n);
- int get_readahead_into_buffer (char *buf, size_t buflen);
- bool get_readahead_valid (void);
int tcsetattr (int a, const struct termios *t);
int tcgetattr (struct termios *t);
@@ -2354,20 +2330,12 @@ class fhandler_pty_slave: public fhandler_pty_common
copyto (fh);
return fh;
}
- void set_switch_to_pcon (int fd);
+ bool setup_pseudoconsole (STARTUPINFOEXW *si, bool nopcon);
+ void close_pseudoconsole (void);
+ void set_switch_to_pcon (void);
void reset_switch_to_pcon (void);
- void push_to_pcon_screenbuffer (const char *ptr, size_t len, bool is_echo);
void mask_switch_to_pcon_in (bool mask);
- void fixup_after_attach (bool native_maybe, int fd);
- bool is_line_input (void)
- {
- return get_ttyp ()->ti.c_lflag & ICANON;
- }
void setup_locale (void);
- void set_freeconsole_on_close (bool val);
- void trigger_redraw_screen (void);
- void pull_pcon_input (void);
- void update_pcon_input_state (bool need_lock);
};
#define __ptsname(buf, unit) __small_sprintf ((buf), "/dev/pty%d", (unit))
@@ -2392,7 +2360,6 @@ public:
int process_slave_output (char *buf, size_t len, int pktmode_on);
void doecho (const void *str, DWORD len);
int accept_input ();
- int put_readahead (char value);
int open (int flags, mode_t mode = 0);
void open_setup (int flags);
ssize_t __stdcall write (const void *ptr, size_t len);
@@ -2431,9 +2398,7 @@ public:
copyto (fh);
return fh;
}
-
- bool setup_pseudoconsole (void);
- void transfer_input_to_pcon (void);
+ bool to_be_read_from_pcon (void);
};
class fhandler_dev_null: public fhandler_base
diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc
index 52741ce8b..02a5996a1 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -1206,18 +1206,6 @@ fhandler_console::close ()
if (con_ra.rabuf)
free (con_ra.rabuf);
- /* If already attached to pseudo console, don't call free_console () */
- cygheap_fdenum cfd (false);
- while (cfd.next () >= 0)
- if (cfd->get_major () == DEV_PTYM_MAJOR ||
- cfd->get_major () == DEV_PTYS_MAJOR)
- {
- fhandler_pty_common *t =
- (fhandler_pty_common *) (fhandler_base *) cfd;
- if (get_console_process_id (t->get_helper_process_id (), true))
- return 0;
- }
-
if (!have_execed)
free_console ();
return 0;
@@ -3612,37 +3600,6 @@ fhandler_console::need_invisible ()
}
DWORD
-fhandler_console::get_console_process_id (DWORD pid, bool match)
-{
- DWORD tmp;
- DWORD num, num_req;
- num = 1;
- num_req = GetConsoleProcessList (&tmp, 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;
- for (DWORD i=0; i<num; i++)
- if ((match && list[i] == pid) || (!match && list[i] != pid))
- /* Last one is the oldest. */
- /* https://github.com/microsoft/terminal/issues/95 */
- tmp = list[i];
- HeapFree (GetProcessHeap (), 0, list);
- return tmp;
-}
-
-DWORD
fhandler_console::__acquire_input_mutex (const char *fn, int ln, DWORD ms)
{
#ifdef DEBUGGING
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 6294e2c20..0865c1fac 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -25,7 +25,6 @@ details. */
#include "child_info.h"
#include <asm/socket.h>
#include "cygwait.h"
-#include "tls_pbuf.h"
#include "registry.h"
#ifndef PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE
@@ -33,7 +32,6 @@ details. */
#endif /* PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE */
extern "C" int sscanf (const char *, const char *, ...);
-extern "C" int ttyname_r (int, char*, size_t);
extern "C" {
HRESULT WINAPI CreatePseudoConsole (COORD, HANDLE, HANDLE, DWORD, HPCON *);
@@ -60,20 +58,10 @@ struct pipe_reply {
DWORD error;
};
-static int pcon_attached_to = -1;
static bool isHybrid;
-static bool do_not_reset_switch_to_pcon;
-static bool freeconsole_on_close = true;
-static tty *last_ttyp = NULL;
-
-void
-clear_pcon_attached_to (void)
-{
- pcon_attached_to = -1;
-}
static void
-set_switch_to_pcon (void)
+set_switch_to_pcon (HANDLE h)
{
cygheap_fdenum cfd (false);
int fd;
@@ -82,292 +70,32 @@ set_switch_to_pcon (void)
{
fhandler_base *fh = cfd;
fhandler_pty_slave *ptys = (fhandler_pty_slave *) fh;
- if (ptys->get_pseudo_console ())
- {
- ptys->set_switch_to_pcon (fd);
- ptys->trigger_redraw_screen ();
- DWORD mode =
- ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT;
- SetConsoleMode (ptys->get_handle (), mode);
- }
+ if (h == ptys->get_handle ())
+ ptys->set_switch_to_pcon ();
return;
}
- /* No pty slave opened */
- if (last_ttyp) /* Make system_printf() work after closing pty slave */
- last_ttyp->set_switch_to_pcon_out (true);
-}
-
-static void
-force_attach_to_pcon (HANDLE h)
-{
- bool attach_done = false;
- for (int n = 0; n < 2; n ++)
- {
- /* First time, attach to the pty whose handle value is match.
- Second time, try to attach to any pty. */
- cygheap_fdenum cfd (false);
- while (cfd.next () >= 0)
- if (cfd->get_major () == DEV_PTYS_MAJOR)
- {
- fhandler_base *fh = cfd;
- fhandler_pty_slave *ptys = (fhandler_pty_slave *) fh;
- if (!ptys->get_pseudo_console ())
- continue;
- if (n != 0
- || h == ptys->get_handle ()
- || h == ptys->get_output_handle ())
- {
- if (fhandler_console::get_console_process_id
- (ptys->get_helper_process_id (), true))
- attach_done = true;
- else
- {
- FreeConsole ();
- if (AttachConsole (ptys->get_helper_process_id ()))
- {
- pcon_attached_to = ptys->get_minor ();
- attach_done = true;
- }
- else
- pcon_attached_to = -1;
- }
- break;
- }
- }
- else if (cfd->get_major () == DEV_CONS_MAJOR)
- {
- fhandler_base *fh = cfd;
- fhandler_console *cons = (fhandler_console *) fh;
- if (n != 0
- || h == cons->get_handle ()
- || h == cons->get_output_handle ())
- {
- /* If the process is running on a console,
- the parent process should be attached
- to the same console. */
- DWORD attach_wpid;
- if (myself->ppid == 1)
- attach_wpid = ATTACH_PARENT_PROCESS;
- else
- {
- pinfo p (myself->ppid);
- attach_wpid = p->dwProcessId;
- }
- FreeConsole ();
- if (AttachConsole (attach_wpid))
- {
- pcon_attached_to = -1;
- attach_done = true;
- }
- else
- pcon_attached_to = -1;
- break;
- }
- }
- if (attach_done)
- break;
- }
-}
-
-void
-set_ishybrid_and_switch_to_pcon (HANDLE h)
-{
- if (GetFileType (h) == FILE_TYPE_CHAR)
- {
- force_attach_to_pcon (h);
- DWORD dummy;
- if (!isHybrid && (GetConsoleMode (h, &dummy)
- || GetLastError () != ERROR_INVALID_HANDLE))
- {
- isHybrid = true;
- set_switch_to_pcon ();
- }
- }
-}
-
-inline void
-fhandler_pty_slave::free_attached_console ()
-{
- bool attached = get_ttyp () ?
- fhandler_console::get_console_process_id (get_helper_process_id (), true)
- : (get_minor () == pcon_attached_to);
- if (freeconsole_on_close && attached)
- {
- FreeConsole ();
- pcon_attached_to = -1;
- }
}
#define DEF_HOOK(name) static __typeof__ (name) *name##_Orig
-DEF_HOOK (WriteFile);
-DEF_HOOK (WriteConsoleA);
-DEF_HOOK (WriteConsoleW);
-DEF_HOOK (ReadFile);
-DEF_HOOK (ReadConsoleA);
-DEF_HOOK (ReadConsoleW);
-DEF_HOOK (WriteConsoleOutputA);
-DEF_HOOK (WriteConsoleOutputW);
-DEF_HOOK (WriteConsoleOutputCharacterA);
-DEF_HOOK (WriteConsoleOutputCharacterW);
-DEF_HOOK (WriteConsoleOutputAttribute);
-DEF_HOOK (SetConsoleCursorPosition);
-DEF_HOOK (SetConsoleTextAttribute);
-DEF_HOOK (WriteConsoleInputA);
-DEF_HOOK (WriteConsoleInputW);
-DEF_HOOK (ReadConsoleInputA);
-DEF_HOOK (ReadConsoleInputW);
-DEF_HOOK (PeekConsoleInputA);
-DEF_HOOK (PeekConsoleInputW);
/* CreateProcess() is hooked for GDB etc. */
DEF_HOOK (CreateProcessA);
DEF_HOOK (CreateProcessW);
static BOOL WINAPI
-WriteFile_Hooked
- (HANDLE h, LPCVOID p, DWORD l, LPDWORD n, LPOVERLAPPED o)
-{
- set_ishybrid_and_switch_to_pcon (h);
- return WriteFile_Orig (h, p, l, n, o);
-}
-static BOOL WINAPI
-WriteConsoleA_Hooked
- (HANDLE h, LPCVOID p, DWORD l, LPDWORD n, LPVOID o)
-{
- set_ishybrid_and_switch_to_pcon (h);
- return WriteConsoleA_Orig (h, p, l, n, o);
-}
-static BOOL WINAPI
-WriteConsoleW_Hooked
- (HANDLE h, LPCVOID p, DWORD l, LPDWORD n, LPVOID o)
-{
- set_ishybrid_and_switch_to_pcon (h);
- return WriteConsoleW_Orig (h, p, l, n, o);
-}
-static BOOL WINAPI
-ReadFile_Hooked
- (HANDLE h, LPVOID p, DWORD l, LPDWORD n, LPOVERLAPPED o)
-{
- set_ishybrid_and_switch_to_pcon (h);
- return ReadFile_Orig (h, p, l, n, o);
-}
-static BOOL WINAPI
-ReadConsoleA_Hooked
- (HANDLE h, LPVOID p, DWORD l, LPDWORD n, LPVOID o)
-{
- set_ishybrid_and_switch_to_pcon (h);
- return ReadConsoleA_Orig (h, p, l, n, o);
-}
-static BOOL WINAPI
-ReadConsoleW_Hooked
- (HANDLE h, LPVOID p, DWORD l, LPDWORD n, LPVOID o)
-{
- set_ishybrid_and_switch_to_pcon (h);
- return ReadConsoleW_Orig (h, p, l, n, o);
-}
-static BOOL WINAPI
-WriteConsoleOutputA_Hooked
- (HANDLE h, CONST CHAR_INFO *p, COORD s, COORD c, PSMALL_RECT r)
-{
- set_ishybrid_and_switch_to_pcon (h);
- return WriteConsoleOutputA_Orig (h, p, s, c, r);
-}
-static BOOL WINAPI
-WriteConsoleOutputW_Hooked
- (HANDLE h, CONST CHAR_INFO *p, COORD s, COORD c, PSMALL_RECT r)
-{
- set_ishybrid_and_switch_to_pcon (h);
- return WriteConsoleOutputW_Orig (h, p, s, c, r);
-}
-static BOOL WINAPI
-WriteConsoleOutputCharacterA_Hooked
- (HANDLE h, LPCSTR p, DWORD l, COORD c, LPDWORD n)
-{
- set_ishybrid_and_switch_to_pcon (h);
- return WriteConsoleOutputCharacterA_Orig (h, p, l, c, n);
-}
-static BOOL WINAPI
-WriteConsoleOutputCharacterW_Hooked
- (HANDLE h, LPCWSTR p, DWORD l, COORD c, LPDWORD n)
-{
- set_ishybrid_and_switch_to_pcon (h);
- return WriteConsoleOutputCharacterW_Orig (h, p, l, c, n);
-}
-static BOOL WINAPI
-WriteConsoleOutputAttribute_Hooked
- (HANDLE h, CONST WORD *a, DWORD l, COORD c, LPDWORD n)
-{
- set_ishybrid_and_switch_to_pcon (h);
- return WriteConsoleOutputAttribute_Orig (h, a, l, c, n);
-}
-static BOOL WINAPI
-SetConsoleCursorPosition_Hooked
- (HANDLE h, COORD c)
-{
- set_ishybrid_and_switch_to_pcon (h);
- return SetConsoleCursorPosition_Orig (h, c);
-}
-static BOOL WINAPI
-SetConsoleTextAttribute_Hooked
- (HANDLE h, WORD a)
-{
- set_ishybrid_and_switch_to_pcon (h);
- return SetConsoleTextAttribute_Orig (h, a);
-}
-static BOOL WINAPI
-WriteConsoleInputA_Hooked
- (HANDLE h, CONST INPUT_RECORD *r, DWORD l, LPDWORD n)
-{
- set_ishybrid_and_switch_to_pcon (h);
- return WriteConsoleInputA_Orig (h, r, l, n);
-}
-static BOOL WINAPI
-WriteConsoleInputW_Hooked
- (HANDLE h, CONST INPUT_RECORD *r, DWORD l, LPDWORD n)
-{
- set_ishybrid_and_switch_to_pcon (h);
- return WriteConsoleInputW_Orig (h, r, l, n);
-}
-static BOOL WINAPI
-ReadConsoleInputA_Hooked
- (HANDLE h, PINPUT_RECORD r, DWORD l, LPDWORD n)
-{
- set_ishybrid_and_switch_to_pcon (h);
- return ReadConsoleInputA_Orig (h, r, l, n);
-}
-static BOOL WINAPI
-ReadConsoleInputW_Hooked
- (HANDLE h, PINPUT_RECORD r, DWORD l, LPDWORD n)
-{
- set_ishybrid_and_switch_to_pcon (h);
- return ReadConsoleInputW_Orig (h, r, l, n);
-}
-static BOOL WINAPI
-PeekConsoleInputA_Hooked
- (HANDLE h, PINPUT_RECORD r, DWORD l, LPDWORD n)
-{
- set_ishybrid_and_switch_to_pcon (h);
- return PeekConsoleInputA_Orig (h, r, l, n);
-}
-static BOOL WINAPI
-PeekConsoleInputW_Hooked
- (HANDLE h, PINPUT_RECORD r, DWORD l, LPDWORD n)
-{
- set_ishybrid_and_switch_to_pcon (h);
- return PeekConsoleInputW_Orig (h, r, l, n);
-}
-/* CreateProcess() is hooked for GDB etc. */
-static BOOL WINAPI
CreateProcessA_Hooked
(LPCSTR n, LPSTR c, LPSECURITY_ATTRIBUTES pa, LPSECURITY_ATTRIBUTES ta,
BOOL inh, DWORD f, LPVOID e, LPCSTR d,
LPSTARTUPINFOA si, LPPROCESS_INFORMATION pi)
{
HANDLE h;
- if (si->dwFlags & STARTF_USESTDHANDLES)
- h = si->hStdOutput;
- else
- h = GetStdHandle (STD_OUTPUT_HANDLE);
- set_ishybrid_and_switch_to_pcon (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);
}
static BOOL WINAPI
@@ -377,11 +105,14 @@ CreateProcessW_Hooked
LPSTARTUPINFOW si, LPPROCESS_INFORMATION pi)
{
HANDLE h;
- if (si->dwFlags & STARTF_USESTDHANDLES)
- h = si->hStdOutput;
- else
- h = GetStdHandle (STD_OUTPUT_HANDLE);
- set_ishybrid_and_switch_to_pcon (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);
}
@@ -464,10 +195,6 @@ fhandler_pty_master::flush_to_slave ()
{
if (get_readahead_valid () && !(get_ttyp ()->ti.c_lflag & ICANON))
accept_input ();
- WaitForSingleObject (input_mutex, INFINITE);
- if (!get_ttyp ()->pcon_in_empty && !(get_ttyp ()->ti.c_lflag & ICANON))
- SetEvent (input_available_event);
- ReleaseMutex (input_mutex);
}
DWORD
@@ -533,14 +260,6 @@ fhandler_pty_master::doecho (const void *str, DWORD len)
}
int
-fhandler_pty_master::put_readahead (char value)
-{
- if (to_be_read_from_pcon ())
- return 1;
- return fhandler_base::put_readahead (value);
-}
-
-int
fhandler_pty_master::accept_input ()
{
DWORD bytes_left;
@@ -551,9 +270,11 @@ fhandler_pty_master::accept_input ()
char *p = rabuf () + raixget ();
bytes_left = eat_readahead (-1);
+ HANDLE write_to = get_output_handle ();
if (to_be_read_from_pcon ())
- ; /* Do nothing */
- else if (!bytes_left)
+ write_to = to_slave;
+
+ if (!bytes_left)
{
termios_printf ("sending EOF to slave");
get_ttyp ()->read_retval = 0;
@@ -564,10 +285,10 @@ fhandler_pty_master::accept_input ()
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;
}
@@ -725,52 +446,12 @@ out:
fhandler_pty_slave::fhandler_pty_slave (int unit)
: fhandler_pty_common (), inuse (NULL), output_handle_cyg (NULL),
- io_handle_cyg (NULL), pid_restore (0), fd (-1)
+ io_handle_cyg (NULL)
{
if (unit >= 0)
dev ().parse (DEV_PTYS_MAJOR, unit);
}
-fhandler_pty_slave::~fhandler_pty_slave ()
-{
- if (!get_ttyp ())
- {
- /* Why comes here? Who clears _tc? */
- free_attached_console ();
- return;
- }
- if (get_pseudo_console ())
- {
- int used = 0;
- int attached = 0;
- cygheap_fdenum cfd (false);
- while (cfd.next () >= 0)
- {
- if (cfd->get_major () == DEV_PTYS_MAJOR ||
- 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 tty is opened and the process
- is attached to console corresponding to tty. This is
- needed to make GNU screen and tmux work in Windows 10
- 1903. */
- if (attached == 0)
- {
- pcon_attached_to = -1;
- last_ttyp = get_ttyp ();
- }
- if (used == 0)
- {
- init_console_handler (false);
- free_attached_console ();
- }
- }
-}
-
int
fhandler_pty_slave::open (int flags, mode_t)
{
@@ -833,8 +514,8 @@ fhandler_pty_slave::open (int flags, mode_t)
release_output_mutex ();
}
- if (!get_ttyp ()->from_master () || !get_ttyp ()->from_master_cyg () ||
- !get_ttyp ()->to_master () || !get_ttyp ()->to_master_cyg ())
+ if (!get_ttyp ()->from_master () || !get_ttyp ()->from_master_cyg ()
+ || !get_ttyp ()->to_master () || !get_ttyp ()->to_master_cyg ())
{
errmsg = "pty handles have been closed";
set_errno (EACCES);
@@ -923,8 +604,8 @@ fhandler_pty_slave::open (int flags, mode_t)
from_master_cyg_local = repl.from_master_cyg;
to_master_local = repl.to_master;
to_master_cyg_local = repl.to_master_cyg;
- if (!from_master_local || !from_master_cyg_local ||
- !to_master_local || !to_master_cyg_local)
+ if (!from_master_local || !from_master_cyg_local
+ || !to_master_local || !to_master_cyg_local)
{
SetLastError (repl.error);
errmsg = "error duplicating pipes, %E";
@@ -950,24 +631,7 @@ fhandler_pty_slave::open (int flags, mode_t)
set_output_handle (to_master_local);
set_output_handle_cyg (to_master_cyg_local);
- if (!get_pseudo_console ())
- {
- 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
- (get_helper_process_id (), true))
- /* Attached to pcon of this pty */
- {
- pcon_attached_to = get_minor ();
- init_console_handler (true);
- }
+ fhandler_console::need_invisible ();
set_open_status ();
return 1;
@@ -1021,8 +685,7 @@ fhandler_pty_slave::close ()
if (!ForceCloseHandle (get_handle_cyg ()))
termios_printf ("CloseHandle (get_handle_cyg ()<%p>), %E",
get_handle_cyg ());
- if (!get_pseudo_console () &&
- (unsigned) myself->ctty == FHDEV (DEV_PTYS_MAJOR, get_minor ()))
+ if ((unsigned) myself->ctty == FHDEV (DEV_PTYS_MAJOR, get_minor ()))
fhandler_console::free_console (); /* assumes that we are the last pty closer */
fhandler_pty_common::close ();
if (!ForceCloseHandle (output_mutex))
@@ -1070,423 +733,31 @@ fhandler_pty_slave::init (HANDLE h, DWORD a, mode_t)
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 (get_ttyp()->attach_pcon_in_fork)
- return false;
- 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 (get_helper_process_id ()))
- {
- system_printf ("pty%d: AttachConsole(helper=%d) failed. 0x%08lx",
- get_minor (), get_helper_process_id (), 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;
-}
-
-/* This function requests transfering the input data from the input
- pipe for cygwin apps to the other input pipe for native apps. */
-void
-fhandler_pty_slave::pull_pcon_input (void)
-{
- get_ttyp ()->req_transfer_input_to_pcon = true;
- while (get_ttyp ()->req_transfer_input_to_pcon)
- Sleep (1);
-}
-
-void
-fhandler_pty_slave::update_pcon_input_state (bool need_lock)
-{
- if (need_lock)
- WaitForSingleObject (input_mutex, INFINITE);
- /* Flush input buffer if it is requested by master.
- This happens if ^C is pressed in pseudo console side. */
- if (get_ttyp ()->req_flush_pcon_input)
- {
- FlushConsoleInputBuffer (get_handle ());
- get_ttyp ()->req_flush_pcon_input = false;
- }
- /* Peek console input buffer and update state. */
- INPUT_RECORD inp[INREC_SIZE];
- DWORD n;
- BOOL (WINAPI *PeekFunc)
- (HANDLE, PINPUT_RECORD, DWORD, LPDWORD);
- PeekFunc =
- PeekConsoleInputA_Orig ? : PeekConsoleInput;
- PeekFunc (get_handle (), inp, INREC_SIZE, &n);
- bool saw_accept = false;
- bool pipe_empty = true;
- while (n-- > 0)
- if (inp[n].EventType == KEY_EVENT && inp[n].Event.KeyEvent.bKeyDown &&
- inp[n].Event.KeyEvent.uChar.AsciiChar)
- {
- pipe_empty = false;
- char c = inp[n].Event.KeyEvent.uChar.AsciiChar;
- const char sigs[] = {
- (char) get_ttyp ()->ti.c_cc[VINTR],
- (char) get_ttyp ()->ti.c_cc[VQUIT],
- (char) get_ttyp ()->ti.c_cc[VSUSP],
- };
- const char eols[] = {
- (char) get_ttyp ()->ti.c_cc[VEOF],
- (char) get_ttyp ()->ti.c_cc[VEOL],
- (char) get_ttyp ()->ti.c_cc[VEOL2],
- '\n',
- '\r'
- };
- if (is_line_input () && c && memchr (eols, c, sizeof (eols)))
- saw_accept = true;
- if ((get_ttyp ()->ti.c_lflag & ISIG)
- && c && memchr (sigs, c, sizeof (sigs)))
- saw_accept = true;
- }
- get_ttyp ()->pcon_in_empty = pipe_empty && !(ralen () > raixget ());
- if (!get_readahead_valid () &&
- (pipe_empty || (is_line_input () && !saw_accept)) &&
- get_ttyp ()->read_retval == 1 && bytes_available (n) && n == 0)
- ResetEvent (input_available_event);
- if (need_lock)
- ReleaseMutex (input_mutex);
-}
-
-int
-fhandler_pty_slave::eat_readahead (int n)
-{
- int oralen = ralen ();
- if (n < 0)
- n = ralen () - raixget ();
- if (n > 0 && ralen () > raixget ())
- {
- const char eols[] = {
- (char) get_ttyp ()->ti.c_cc[VEOF],
- (char) get_ttyp ()->ti.c_cc[VEOL],
- (char) get_ttyp ()->ti.c_cc[VEOL2],
- '\n'
- };
- while (n > 0 && ralen () > raixget ())
- {
- if (is_line_input () && rabuf ()[ralen ()-1]
- && memchr (eols, rabuf ()[ralen ()-1], sizeof (eols)))
- break;
- -- n;
- -- ralen ();
- }
-
- /* If IUTF8 is set, the terminal is in UTF-8 mode. If so, we erase
- a complete UTF-8 multibyte sequence on VERASE/VWERASE. Otherwise,
- if we only erase a single byte, invalid unicode chars are left in
- the input. */
- if (get_ttyp ()->ti.c_iflag & IUTF8)
- while (ralen () > raixget () &&
- ((unsigned char) rabuf ()[ralen ()] & 0xc0) == 0x80)
- --ralen ();
- }
- oralen = oralen - ralen ();
- if (raixget () >= ralen ())
- raixget () = raixput () = ralen () = 0;
- else if (raixput () > ralen ())
- raixput () = ralen ();
-
- return oralen;
-}
-
-int
-fhandler_pty_slave::get_readahead_into_buffer (char *buf, size_t buflen)
-{
- int ch;
- int copied_chars = 0;
-
- while (buflen)
- if ((ch = get_readahead ()) < 0)
- break;
- else
- {
- const char eols[] = {
- (char) get_ttyp ()->ti.c_cc[VEOF],
- (char) get_ttyp ()->ti.c_cc[VEOL],
- (char) get_ttyp ()->ti.c_cc[VEOL2],
- '\n'
- };
- buf[copied_chars++] = (unsigned char)(ch & 0xff);
- buflen--;
- if (is_line_input () && ch && memchr (eols, ch & 0xff, sizeof (eols)))
- break;
- }
-
- return copied_chars;
-}
-
-bool
-fhandler_pty_slave::get_readahead_valid (void)
-{
- if (is_line_input ())
- {
- const char eols[] = {
- (char) get_ttyp ()->ti.c_cc[VEOF],
- (char) get_ttyp ()->ti.c_cc[VEOL],
- (char) get_ttyp ()->ti.c_cc[VEOL2],
- '\n'
- };
- for (size_t i=raixget (); i<ralen (); i++)
- if (rabuf ()[i] && memchr (eols, rabuf ()[i], sizeof (eols)))
- return true;
- return false;
- }
- else
- return ralen () > raixget ();
-}
-
void
-fhandler_pty_slave::set_switch_to_pcon (int fd_set)
+fhandler_pty_slave::set_switch_to_pcon (void)
{
- if (fd < 0)
- fd = fd_set;
- acquire_output_mutex (INFINITE);
- if (fd == 0 && !get_ttyp ()->switch_to_pcon_in)
+ if (!get_ttyp ()->switch_to_pcon_in)
{
- pull_pcon_input ();
- if (get_ttyp ()->pcon_pid == 0 ||
- !pinfo (get_ttyp ()->pcon_pid))
+ 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;
- if (isHybrid && !get_ttyp ()->switch_to_pcon_out)
- {
- get_ttyp ()->wait_pcon_fwd ();
- get_ttyp ()->switch_to_pcon_out = true;
- }
}
- else if ((fd == 1 || fd == 2) && !get_ttyp ()->switch_to_pcon_out)
- {
- get_ttyp ()->wait_pcon_fwd ();
- if (get_ttyp ()->pcon_pid == 0 ||
- !pinfo (get_ttyp ()->pcon_pid))
- get_ttyp ()->pcon_pid = myself->pid;
- get_ttyp ()->switch_to_pcon_out = true;
- if (isHybrid)
- get_ttyp ()->switch_to_pcon_in = true;
- }
- release_output_mutex ();
}
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))
+ 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;
- if (do_not_reset_switch_to_pcon)
- return;
- acquire_output_mutex (INFINITE);
- if (get_ttyp ()->switch_to_pcon_out)
- /* Wait for pty_master_fwd_thread() */
- get_ttyp ()->wait_pcon_fwd ();
get_ttyp ()->pcon_pid = 0;
get_ttyp ()->switch_to_pcon_in = false;
- get_ttyp ()->switch_to_pcon_out = false;
- release_output_mutex ();
- init_console_handler (true);
-}
-
-void
-fhandler_pty_slave::push_to_pcon_screenbuffer (const char *ptr, size_t len,
- bool is_echo)
-{
- bool attached =
- !!fhandler_console::get_console_process_id (get_helper_process_id (), true);
- if (!attached && pcon_attached_to == get_minor ())
- {
- for (DWORD t0 = GetTickCount (); GetTickCount () - t0 < 100; )
- {
- Sleep (1);
- attached = fhandler_console::get_console_process_id
- (get_helper_process_id (), true);
- 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;
- size_t nlen;
- DWORD origCP;
- origCP = GetConsoleOutputCP ();
- SetConsoleOutputCP (get_ttyp ()->term_code_page);
- /* Just copy */
- buf = (char *) HeapAlloc (GetProcessHeap (), 0, len);
- memcpy (buf, (char *)ptr, len);
- nlen = len;
- char *p0, *p1;
- p0 = p1 = buf;
- /* Remove alternate screen buffer drawing */
- while (p0 && p1)
- {
- if (!get_ttyp ()->screen_alternated)
- {
- /* Check switching to alternate screen buffer */
- p0 = (char *) memmem (p1, nlen - (p1-buf), "\033[?1049h", 8);
- if (p0)
- {
- //p0 += 8;
- get_ttyp ()->screen_alternated = true;
- if (get_ttyp ()->switch_to_pcon_out)
- do_not_reset_switch_to_pcon = true;
- }
- }
- if (get_ttyp ()->screen_alternated)
- {
- /* Check switching to main screen buffer */
- p1 = (char *) memmem (p0, nlen - (p0-buf), "\033[?1049l", 8);
- if (p1)
- {
- p1 += 8;
- get_ttyp ()->screen_alternated = false;
- do_not_reset_switch_to_pcon = false;
- memmove (p0, p1, buf+nlen - p1);
- nlen -= p1 - p0;
- }
- else
- nlen = p0 - buf;
- }
- }
- if (!nlen) /* Nothing to be synchronized */
- goto cleanup;
- if (get_ttyp ()->switch_to_pcon_out && !is_echo)
- goto cleanup;
- /* 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. */
- while ((p0 = (char *) memmem (buf, nlen, "\033[6n", 4)))
- {
- memmove (p0, p0+4, nlen - (p0+4 - buf));
- nlen -= 4;
- }
- /* Remove ESC sequence to report terminal identity. */
- while ((p0 = (char *) memmem (buf, nlen, "\033[0c", 4)))
- {
- memmove (p0, p0+4, nlen - (p0+4 - buf));
- nlen -= 4;
- }
-
- /* If the ESC sequence ESC[?3h or ESC[?3l which clears console screen
- buffer is pushed, set need_redraw_screen to trigger redraw screen. */
- p0 = buf;
- while ((p0 = (char *) memmem (p0, nlen - (p0 - buf), "\033[?", 3)))
- {
- p0 += 3;
- bool exist_arg_3 = false;
- while (p0 < buf + nlen && (isdigit (*p0) || *p0 == ';'))
- {
- int arg = 0;
- while (p0 < buf + nlen && isdigit (*p0))
- arg = arg * 10 + (*p0 ++) - '0';
- if (arg == 3)
- exist_arg_3 = true;
- if (p0 < buf + nlen && *p0 == ';')
- p0 ++;
- }
- if (p0 < buf + nlen && exist_arg_3 && (*p0 == 'h' || *p0 == 'l'))
- get_ttyp ()->need_redraw_screen = true;
- p0 ++;
- if (p0 >= buf + nlen)
- break;
- }
-
- int retry_count;
- retry_count = 0;
- DWORD dwMode, flags;
- flags = ENABLE_VIRTUAL_TERMINAL_PROCESSING;
- while (!GetConsoleMode (get_output_handle (), &dwMode))
- {
- termios_printf ("GetConsoleMode failed, %E");
- int errno_save = errno;
- /* Re-open handles */
- this->open (0, 0);
- /* Fix pseudo console window size */
- this->ioctl (TIOCSWINSZ, &get_ttyp ()->winsize);
- if (errno != errno_save)
- set_errno (errno_save);
- if (++retry_count > 3)
- goto cleanup;
- }
- if (!(get_ttyp ()->ti.c_oflag & OPOST) ||
- !(get_ttyp ()->ti.c_oflag & ONLCR))
- flags |= DISABLE_NEWLINE_AUTO_RETURN;
- SetConsoleMode (get_output_handle (), dwMode | flags);
- char *p;
- p = buf;
- DWORD wLen, written;
- written = 0;
- BOOL (WINAPI *WriteFunc)
- (HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED);
- WriteFunc = WriteFile_Orig ? WriteFile_Orig : WriteFile;
- while (written < nlen)
- {
- if (!WriteFunc (get_output_handle (), p, nlen - written, &wLen, NULL))
- {
- termios_printf ("WriteFile failed, %E");
- break;
- }
- else
- {
- written += wLen;
- p += wLen;
- }
- }
- /* Detach from pseudo console and resume. */
- flags = ENABLE_VIRTUAL_TERMINAL_PROCESSING;
- SetConsoleMode (get_output_handle (), dwMode | flags);
-cleanup:
- SetConsoleOutputCP (origCP);
- HeapFree (GetProcessHeap (), 0, buf);
-detach:
- restore_reattach_pcon ();
+ get_ttyp ()->h_pseudo_console = NULL;
+ get_ttyp ()->pcon_start = false;
}
ssize_t __stdcall
@@ -1505,44 +776,7 @@ fhandler_pty_slave::write (const void *ptr, size_t len)
reset_switch_to_pcon ();
acquire_output_mutex (INFINITE);
- bool output_to_pcon = get_ttyp ()->switch_to_pcon_out;
- release_output_mutex ();
-
- UINT target_code_page = output_to_pcon ?
- GetConsoleOutputCP () : get_ttyp ()->term_code_page;
- ssize_t nlen;
- char *buf = convert_mb_str (target_code_page, (size_t *) &nlen,
- get_ttyp ()->term_code_page, (const char *) ptr, len);
-
- /* If not attached to this pseudo console, try to attach temporarily. */
- pid_restore = 0;
- bool fallback = false;
- if (output_to_pcon && pcon_attached_to != get_minor ())
- if (!try_reattach_pcon ())
- fallback = true;
-
- if (output_to_pcon && !fallback &&
- (memmem (buf, nlen, "\033[6n", 4) || memmem (buf, nlen, "\033[0c", 4)))
- {
- get_ttyp ()->pcon_in_empty = false;
- if (!is_line_input ())
- SetEvent (input_available_event);
- }
-
- DWORD dwMode, flags;
- flags = ENABLE_VIRTUAL_TERMINAL_PROCESSING;
- if (!(get_ttyp ()->ti.c_oflag & OPOST) ||
- !(get_ttyp ()->ti.c_oflag & ONLCR))
- flags |= DISABLE_NEWLINE_AUTO_RETURN;
- if (output_to_pcon && !fallback)
- {
- GetConsoleMode (get_output_handle (), &dwMode);
- SetConsoleMode (get_output_handle (), dwMode | flags);
- }
- HANDLE to = (output_to_pcon && !fallback) ?
- get_output_handle () : get_output_handle_cyg ();
- acquire_output_mutex (INFINITE);
- if (!process_opost_output (to, buf, nlen, false))
+ if (!process_opost_output (get_output_handle_cyg (), ptr, towrite, false))
{
DWORD err = GetLastError ();
termios_printf ("WriteFile failed, %E");
@@ -1557,20 +791,6 @@ fhandler_pty_slave::write (const void *ptr, size_t len)
towrite = -1;
}
release_output_mutex ();
- mb_str_free (buf);
- flags = ENABLE_VIRTUAL_TERMINAL_PROCESSING;
- if (output_to_pcon && !fallback)
- SetConsoleMode (get_output_handle (), dwMode | flags);
-
- restore_reattach_pcon ();
-
- /* Push slave output to pseudo console screen buffer */
- if (get_pseudo_console ())
- {
- acquire_output_mutex (INFINITE);
- push_to_pcon_screenbuffer ((char *)ptr, len, false);
- release_output_mutex ();
- }
return towrite;
}
@@ -1582,16 +802,15 @@ fhandler_pty_slave::mask_switch_to_pcon_in (bool mask)
}
bool
-fhandler_pty_common::to_be_read_from_pcon (void)
+fhandler_pty_master::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_start
+ || (get_ttyp ()->switch_to_pcon_in && !get_ttyp ()->mask_switch_to_pcon_in);
}
void __reg3
fhandler_pty_slave::read (void *ptr, size_t& len)
{
- char *ptr0 = (char *)ptr;
ssize_t totalread = 0;
int vmin = 0;
int vtime = 0; /* Initialized to prevent -Wuninitialized warning */
@@ -1616,8 +835,6 @@ fhandler_pty_slave::read (void *ptr, size_t& len)
mask_switch_to_pcon_in (true);
reset_switch_to_pcon ();
}
- if (to_be_read_from_pcon ())
- update_pcon_input_state (true);
if (is_nonblocking () || !ptr) /* Indicating tcflush(). */
time_to_wait = 0;
@@ -1717,84 +934,7 @@ fhandler_pty_slave::read (void *ptr, size_t& len)
}
goto out;
}
- if (ptr && to_be_read_from_pcon ())
- {
- if (get_readahead_valid ())
- {
- ReleaseMutex (input_mutex);
- totalread = get_readahead_into_buffer ((char *) ptr, len);
- }
- else
- {
- if (!try_reattach_pcon ())
- {
- restore_reattach_pcon ();
- goto do_read_cyg;
- }
-
- DWORD dwMode;
- GetConsoleMode (get_handle (), &dwMode);
- DWORD flags = ENABLE_VIRTUAL_TERMINAL_INPUT;
- if (dwMode != flags)
- SetConsoleMode (get_handle (), flags);
- /* Read get_handle() instad of get_handle_cyg() */
- BOOL (WINAPI *ReadFunc)
- (HANDLE, LPVOID, DWORD, LPDWORD, LPVOID);
- ReadFunc = ReadConsoleA_Orig ? ReadConsoleA_Orig : ReadConsoleA;
- DWORD rlen;
- readlen = MIN (len, sizeof (buf));
- if (!ReadFunc (get_handle (), buf, readlen, &rlen, NULL))
- {
- termios_printf ("read failed, %E");
- SetConsoleMode (get_handle (), dwMode);
- restore_reattach_pcon ();
- ReleaseMutex (input_mutex);
- set_errno (EIO);
- totalread = -1;
- goto out;
- }
- SetConsoleMode (get_handle (), dwMode);
- restore_reattach_pcon ();
- ReleaseMutex (input_mutex);
-
- ssize_t nlen;
- char *nbuf = convert_mb_str (get_ttyp ()->term_code_page,
- (size_t *) &nlen, GetConsoleCP (), buf, rlen);
-
- ssize_t ret;
- line_edit_status res =
- line_edit (nbuf, nlen, get_ttyp ()->ti, &ret);
-
- mb_str_free (nbuf);
-
- if (res == line_edit_input_done || res == line_edit_ok)
- totalread = get_readahead_into_buffer ((char *) ptr, len);
- else if (res > line_edit_signalled)
- {
- set_sig_errno (EINTR);
- totalread = -1;
- }
- else
- {
- update_pcon_input_state (true);
- continue;
- }
- }
- update_pcon_input_state (true);
- mask_switch_to_pcon_in (false);
- goto out;
- }
- if (!ptr && len == UINT_MAX && !get_ttyp ()->pcon_in_empty)
- {
- FlushConsoleInputBuffer (get_handle ());
- get_ttyp ()->pcon_in_empty = true;
- DWORD n;
- if (bytes_available (n) && n == 0)
- ResetEvent (input_available_event);
- }
-
-do_read_cyg:
if (!bytes_available (bytes_in_pipe))
{
ReleaseMutex (input_mutex);
@@ -1911,16 +1051,6 @@ do_read_cyg:
out:
termios_printf ("%d = read(%p, %lu)", totalread, ptr, len);
len = (size_t) totalread;
- /* Push slave read as echo to pseudo console screen buffer. */
- if (get_pseudo_console () && ptr0 && totalread > 0 &&
- (get_ttyp ()->ti.c_lflag & ECHO))
- {
- acquire_output_mutex (INFINITE);
- push_to_pcon_screenbuffer (ptr0, len, true);
- if (get_ttyp ()->switch_to_pcon_out)
- trigger_redraw_screen ();
- release_output_mutex ();
- }
mask_switch_to_pcon_in (false);
}
@@ -2061,38 +1191,11 @@ fhandler_pty_slave::ioctl (unsigned int cmd, void *arg)
get_ttyp ()->winsize = get_ttyp ()->arg.winsize;
break;
case TIOCSWINSZ:
- if (get_pseudo_console ())
- {
- /* 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 cleanup;
-
- COORD size;
- size.X = ((struct winsize *) arg)->ws_col;
- size.Y = ((struct winsize *) arg)->ws_row;
- CONSOLE_SCREEN_BUFFER_INFO csbi;
- if (GetConsoleScreenBufferInfo (get_output_handle (), &csbi))
- if (size.X == csbi.srWindow.Right - csbi.srWindow.Left + 1 &&
- size.Y == csbi.srWindow.Bottom - csbi.srWindow.Top + 1)
- goto cleanup;
- if (!SetConsoleScreenBufferSize (get_output_handle (), size))
- goto cleanup;
- SMALL_RECT rect;
- rect.Left = 0;
- rect.Top = 0;
- rect.Right = size.X-1;
- rect.Bottom = size.Y-1;
- SetConsoleWindowInfo (get_output_handle (), TRUE, &rect);
-cleanup:
- restore_reattach_pcon ();
- }
-
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)
+ resize_pseudo_console ((struct winsize *) arg);
get_ttyp ()->arg.winsize = *(struct winsize *) arg;
get_ttyp ()->winsize = *(struct winsize *) arg;
get_ttyp ()->kill_pgrp (SIGWINCH);
@@ -2379,6 +1482,27 @@ fhandler_pty_common::close ()
}
void
+fhandler_pty_common::resize_pseudo_console (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 ()
{
report_tty_counts (this, "closing master", "");
@@ -2393,7 +1517,6 @@ fhandler_pty_master::close ()
{
OBJECT_BASIC_INFORMATION obi;
NTSTATUS status;
- pid_t master_pid_tmp = get_ttyp ()->master_pid;
termios_printf ("closing from_master(%p)/from_master_cyg(%p)/to_master(%p)/to_master_cyg(%p) since we own them(%u)",
from_master, from_master_cyg,
@@ -2438,30 +1561,6 @@ fhandler_pty_master::close ()
else if (obi.HandleCount == 1)
{
termios_printf ("Closing last master of pty%d", get_minor ());
- /* Close Pseudo Console */
- if (get_pseudo_console ())
- {
- /* Terminate helper process */
- SetEvent (get_ttyp ()->h_helper_goodbye);
- WaitForSingleObject (get_ttyp ()->h_helper_process, INFINITE);
- CloseHandle (get_ttyp ()->h_helper_goodbye);
- CloseHandle (get_ttyp ()->h_helper_process);
- /* FIXME: Pseudo console can be accessed via its handle
- only in the process which created it. What else can we do? */
- if (master_pid_tmp == myself->pid)
- {
- /* ClosePseudoConsole() seems to have a bug that one
- internal handle remains opened. This causes handle leak.
- This is a workaround for this problem. */
- HPCON_INTERNAL *hp = (HPCON_INTERNAL *) get_pseudo_console ();
- HANDLE tmp = hp->hConHostProcess;
- /* Release pseudo console */
- ClosePseudoConsole (get_pseudo_console ());
- CloseHandle (tmp);
- }
- get_ttyp ()->switch_to_pcon_in = false;
- get_ttyp ()->switch_to_pcon_out = false;
- }
if (get_ttyp ()->getsid () > 0)
kill (get_ttyp ()->getsid (), SIGHUP);
SetEvent (input_available_event);
@@ -2469,9 +1568,8 @@ fhandler_pty_master::close ()
if (!ForceCloseHandle (from_master))
termios_printf ("error closing from_master %p, %E", from_master);
- if (from_master_cyg != from_master) /* Avoid double close. */
- if (!ForceCloseHandle (from_master_cyg))
- termios_printf ("error closing from_master_cyg %p, %E", from_master_cyg);
+ if (!ForceCloseHandle (from_master_cyg))
+ termios_printf ("error closing from_master_cyg %p, %E", from_master_cyg);
if (!ForceCloseHandle (to_master))
termios_printf ("error closing to_master %p, %E", to_master);
from_master = to_master = NULL;
@@ -2513,7 +1611,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 ())
+ if (to_be_read_from_pcon () && get_ttyp ()->h_pseudo_console)
{
size_t nlen;
char *buf = convert_mb_str
@@ -2521,40 +1619,50 @@ fhandler_pty_master::write (const void *ptr, size_t len)
WaitForSingleObject (input_mutex, INFINITE);
- if (memchr (buf, '\003', nlen)) /* ^C intr key in pcon */
- get_ttyp ()->req_flush_pcon_input = true;
-
DWORD wLen;
- WriteFile (to_slave, buf, nlen, &wLen, NULL);
- get_ttyp ()->pcon_in_empty = false;
-
- ReleaseMutex (input_mutex);
- /* 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)
+ if (get_ttyp ()->pcon_start)
{
- tc ()->ti.c_lflag &= ~ECHO;
- ti.c_lflag &= ~ECHO;
- }
- ti.c_lflag &= ~ISIG;
- line_edit (buf, nlen, ti, &ret);
- if (is_echo)
- tc ()->ti.c_lflag |= ECHO;
- get_ttyp ()->read_retval = 1;
-
- const char sigs[] = {
- (char) ti.c_cc[VINTR],
- (char) ti.c_cc[VQUIT],
- (char) ti.c_cc[VSUSP],
- };
- if (tc ()->ti.c_lflag & ISIG)
- for (size_t i=0; i<sizeof (sigs); i++)
- if (sigs[i] && memchr (buf, sigs[i], nlen))
+ /* Pseudo condole support 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 ()->pcon_start = false;
+ }
+ else
{
- eat_readahead (-1);
- SetEvent (input_available_event);
+ 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 ()->pcon_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 ()->pcon_start = false;
+ }
+ ReleaseMutex (input_mutex);
+ mb_str_free (buf);
+ return len;
}
+ }
+
+ WriteFile (to_slave, buf, nlen, &wLen, NULL);
+
+ ReleaseMutex (input_mutex);
mb_str_free (buf);
return len;
@@ -2630,15 +1738,8 @@ fhandler_pty_master::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)
{
- /* FIXME: Pseudo console can be accessed via its handle
- only in the process which created it. What else can we do? */
- if (get_pseudo_console () && get_ttyp ()->master_pid == myself->pid)
- {
- COORD size;
- size.X = ((struct winsize *) arg)->ws_col;
- size.Y = ((struct winsize *) arg)->ws_row;
- ResizePseudoConsole (get_pseudo_console (), size);
- }
+ if (get_ttyp ()->h_pseudo_console && get_ttyp ()->pcon_pid)
+ resize_pseudo_console ((struct winsize *) arg);
get_ttyp ()->winsize = *(struct winsize *) arg;
get_ttyp ()->kill_pgrp (SIGWINCH);
}
@@ -2763,7 +1864,7 @@ get_locale_from_env (char *locale)
strcpy (locale, env);
}
-static LCID
+static void
get_langinfo (char *locale_out, char *charset_out)
{
/* Get locale from environment */
@@ -2776,11 +1877,6 @@ get_langinfo (char *locale_out, char *charset_out)
if (!locale)
locale = "C";
- char tmp_locale[ENCODING_LEN + 1];
- char *ret = __set_locale_from_locale_alias (locale, tmp_locale);
- if (ret)
- locale = tmp_locale;
-
const char *charset;
struct lc_ctype_T *lc_ctype = (struct lc_ctype_T *) loc.lc_cat[LC_CTYPE].ptr;
if (!lc_ctype)
@@ -2830,23 +1926,9 @@ get_langinfo (char *locale_out, char *charset_out)
charset = "CP932";
}
- wchar_t lc[ENCODING_LEN + 1];
- wchar_t *p;
- mbstowcs (lc, locale, ENCODING_LEN);
- p = wcschr (lc, L'.');
- if (p)
- *p = L'\0';
- p = wcschr (lc, L'_');
- if (p)
- *p = L'-';
- LCID lcid = LocaleNameToLCID (lc, 0);
- if (!lcid && !strcmp (charset, "ASCII"))
- return 0;
-
/* Set results */
strcpy (locale_out, new_locale);
strcpy (charset_out, charset);
- return lcid;
}
void
@@ -2857,21 +1939,7 @@ fhandler_pty_slave::setup_locale (void)
char locale[ENCODING_LEN + 1] = "C";
char charset[ENCODING_LEN + 1] = "ASCII";
- LCID lcid = get_langinfo (locale, charset);
-
- /* Set console code page form locale */
- if (get_pseudo_console ())
- {
- UINT code_page;
- if (lcid == 0 || lcid == (LCID) -1)
- code_page = 20127; /* ASCII */
- else if (!GetLocaleInfo (lcid,
- LOCALE_IDEFAULTCODEPAGE | LOCALE_RETURN_NUMBER,
- (char *) &code_page, sizeof (code_page)))
- code_page = 20127; /* ASCII */
- SetConsoleCP (code_page);
- SetConsoleOutputCP (code_page);
- }
+ get_langinfo (locale, charset);
/* Set terminal code page from locale */
/* This code is borrowed from mintty: charset.c */
@@ -2881,9 +1949,9 @@ fhandler_pty_slave::setup_locale (void)
charset_u[i] = toupper (charset[i]);
unsigned int iso;
UINT cp = 20127; /* Default for fallback */
- if (sscanf (charset_u, "ISO-8859-%u", &iso) == 1 ||
- sscanf (charset_u, "ISO8859-%u", &iso) == 1 ||
- sscanf (charset_u, "ISO8859%u", &iso) == 1)
+ if (sscanf (charset_u, "ISO-8859-%u", &iso) == 1
+ || sscanf (charset_u, "ISO8859-%u", &iso) == 1
+ || sscanf (charset_u, "ISO8859%u", &iso) == 1)
{
if (iso && iso <= 16 && iso !=12)
get_ttyp ()->term_code_page = 28590 + iso;
@@ -2900,89 +1968,8 @@ fhandler_pty_slave::setup_locale (void)
}
void
-fhandler_pty_slave::set_freeconsole_on_close (bool val)
-{
- freeconsole_on_close = val;
-}
-
-void
-fhandler_pty_slave::trigger_redraw_screen (void)
-{
- /* Forcibly redraw screen based on console screen buffer. */
- /* The following code triggers redrawing the screen. */
- CONSOLE_SCREEN_BUFFER_INFO sbi;
- GetConsoleScreenBufferInfo (get_output_handle (), &sbi);
- SMALL_RECT rect = {0, 0,
- (SHORT) (sbi.dwSize.X -1), (SHORT) (sbi.dwSize.Y - 1)};
- COORD dest = {0, 0};
- CHAR_INFO fill = {' ', 0};
- ScrollConsoleScreenBuffer (get_output_handle (), &rect, NULL, dest, &fill);
- get_ttyp ()->need_redraw_screen = false;
-}
-
-void
-fhandler_pty_slave::fixup_after_attach (bool native_maybe, int fd_set)
-{
- if (fd < 0)
- fd = fd_set;
- if (get_pseudo_console ())
- {
- if (fhandler_console::get_console_process_id (get_helper_process_id (),
- true))
- if (pcon_attached_to != get_minor ())
- {
- pcon_attached_to = get_minor ();
- init_console_handler (true);
- }
-
-#if 0 /* This is for debug only. */
- isHybrid = true;
- get_ttyp ()->switch_to_pcon_in = true;
- get_ttyp ()->switch_to_pcon_out = true;
-#endif
-
- if (pcon_attached_to == get_minor () && native_maybe)
- {
- if (fd == 0)
- {
- pull_pcon_input ();
- DWORD mode =
- ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT;
- SetConsoleMode (get_handle (), mode);
- if (get_ttyp ()->pcon_pid == 0 ||
- !pinfo (get_ttyp ()->pcon_pid))
- get_ttyp ()->pcon_pid = myself->pid;
- get_ttyp ()->switch_to_pcon_in = true;
- }
- else if (fd == 1 || fd == 2)
- {
- DWORD mode = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT;
- SetConsoleMode (get_output_handle (), mode);
- acquire_output_mutex (INFINITE);
- if (!get_ttyp ()->switch_to_pcon_out)
- get_ttyp ()->wait_pcon_fwd ();
- if (get_ttyp ()->pcon_pid == 0 ||
- !pinfo (get_ttyp ()->pcon_pid))
- get_ttyp ()->pcon_pid = myself->pid;
- get_ttyp ()->switch_to_pcon_out = true;
- release_output_mutex ();
-
- if (get_ttyp ()->need_redraw_screen)
- trigger_redraw_screen ();
- }
- init_console_handler (false);
- }
- else if (fd == 0 && native_maybe)
- /* Read from unattached pseudo console cause freeze,
- therefore, fallback to legacy pty. */
- set_handle (get_handle_cyg ());
- }
-}
-
-void
fhandler_pty_slave::fixup_after_fork (HANDLE parent)
{
- fixup_after_attach (false, -1);
// fork_fixup (parent, inuse, "inuse");
// fhandler_pty_common::fixup_after_fork (parent);
report_tty_counts (this, "inherited", "");
@@ -2995,70 +1982,21 @@ fhandler_pty_slave::fixup_after_exec ()
if (!close_on_exec ())
fixup_after_fork (NULL); /* No parent handle required. */
- else if (get_pseudo_console ())
- {
- int used = 0;
- int attached = 0;
- cygheap_fdenum cfd (false);
- while (cfd.next () >= 0)
- {
- if (cfd->get_major () == DEV_PTYS_MAJOR ||
- 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 tty is opened and the process
- is attached to console corresponding to tty. This is
- needed to make GNU screen and tmux work in Windows 10
- 1903. */
- if (attached == 1 && get_minor () == pcon_attached_to)
- pcon_attached_to = -1;
- if (used == 1 /* About to close this tty */)
- {
- init_console_handler (false);
- free_attached_console ();
- }
- }
/* Set locale */
setup_locale ();
/* Hook Console API */
- if (get_pseudo_console ())
- {
#define DO_HOOK(module, name) \
- if (!name##_Orig) \
- { \
- void *api = hook_api (module, #name, (void *) name##_Hooked); \
- name##_Orig = (__typeof__ (name) *) api; \
- /*if (api) system_printf (#name " hooked.");*/ \
- }
- DO_HOOK (NULL, WriteFile);
- DO_HOOK (NULL, WriteConsoleA);
- DO_HOOK (NULL, WriteConsoleW);
- DO_HOOK (NULL, ReadFile);
- DO_HOOK (NULL, ReadConsoleA);
- DO_HOOK (NULL, ReadConsoleW);
- DO_HOOK (NULL, WriteConsoleOutputA);
- DO_HOOK (NULL, WriteConsoleOutputW);
- DO_HOOK (NULL, WriteConsoleOutputCharacterA);
- DO_HOOK (NULL, WriteConsoleOutputCharacterW);
- DO_HOOK (NULL, WriteConsoleOutputAttribute);
- DO_HOOK (NULL, SetConsoleCursorPosition);
- DO_HOOK (NULL, SetConsoleTextAttribute);
- DO_HOOK (NULL, WriteConsoleInputA);
- DO_HOOK (NULL, WriteConsoleInputW);
- DO_HOOK (NULL, ReadConsoleInputA);
- DO_HOOK (NULL, ReadConsoleInputW);
- DO_HOOK (NULL, PeekConsoleInputA);
- DO_HOOK (NULL, PeekConsoleInputW);
- /* CreateProcess() is hooked for GDB etc. */
- DO_HOOK (NULL, CreateProcessA);
- DO_HOOK (NULL, CreateProcessW);
+ if (!name##_Orig) \
+ { \
+ void *api = hook_api (module, #name, (void *) name##_Hooked); \
+ name##_Orig = (__typeof__ (name) *) api; \
+ /*if (api) system_printf (#name " hooked.");*/ \
}
+ /* 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
@@ -3206,27 +2144,6 @@ reply:
return 0;
}
-void
-fhandler_pty_master::transfer_input_to_pcon (void)
-{
- WaitForSingleObject (input_mutex, INFINITE);
- DWORD n;
- size_t transfered = 0;
- while (::bytes_available (n, from_master_cyg) && n)
- {
- char buf[1024];
- ReadFile (from_master_cyg, buf, sizeof (buf), &n, 0);
- char *p = buf;
- while ((p = (char *) memchr (p, '\n', n - (p - buf))))
- *p = '\r';
- if (WriteFile (to_slave, buf, n, &n, 0))
- transfered += n;
- }
- if (transfered)
- get_ttyp ()->pcon_in_empty = false;
- ReleaseMutex (input_mutex);
-}
-
static DWORD WINAPI
pty_master_thread (VOID *arg)
{
@@ -3242,23 +2159,7 @@ fhandler_pty_master::pty_master_fwd_thread ()
termios_printf ("Started.");
for (;;)
{
- if (get_pseudo_console ())
- {
- get_ttyp ()->pcon_last_time = GetTickCount ();
- while (::bytes_available (rlen, from_slave) && rlen == 0)
- {
- /* Forcibly transfer input if it is requested by slave.
- This happens when input data should be transfered
- from the input pipe for cygwin apps to the input pipe
- for native apps. */
- if (get_ttyp ()->req_transfer_input_to_pcon)
- {
- transfer_input_to_pcon ();
- get_ttyp ()->req_transfer_input_to_pcon = false;
- }
- Sleep (1);
- }
- }
+ get_ttyp ()->pcon_last_time = GetTickCount ();
if (!ReadFile (from_slave, outbuf, sizeof outbuf, &rlen, NULL))
{
termios_printf ("ReadFile for forwarding failed, %E");
@@ -3266,14 +2167,9 @@ fhandler_pty_master::pty_master_fwd_thread ()
}
ssize_t wlen = rlen;
char *ptr = outbuf;
- if (get_pseudo_console ())
+ if (get_ttyp ()->h_pseudo_console)
{
- /* Avoid duplicating slave output which is already sent to
- to_master_cyg */
- if (!get_ttyp ()->switch_to_pcon_out)
- continue;
-
- /* Avoid setting window title to "cygwin-console-helper.exe" */
+ /* Remove CSI > Pm m */
int state = 0;
int start_at = 0;
for (DWORD i=0; i<rlen; i++)
@@ -3283,43 +2179,8 @@ fhandler_pty_master::pty_master_fwd_thread ()
state = 1;
continue;
}
- else if ((state == 1 && outbuf[i] == ']') ||
- (state == 2 && outbuf[i] == '0') ||
- (state == 3 && outbuf[i] == ';'))
- {
- state ++;
- continue;
- }
- else if (state == 4 && outbuf[i] == '\a')
- {
- const char *helper_str = "\\bin\\cygwin-console-helper.exe";
- if (memmem (&outbuf[start_at], i + 1 - start_at,
- helper_str, strlen (helper_str)))
- {
- memmove (&outbuf[start_at], &outbuf[i+1], rlen-i-1);
- rlen = wlen = start_at + rlen - i - 1;
- }
- state = 0;
- continue;
- }
- else if (outbuf[i] == '\a')
- {
- state = 0;
- continue;
- }
-
- /* Remove CSI > Pm m */
- state = 0;
- start_at = 0;
- for (DWORD i=0; i<rlen; i++)
- if (outbuf[i] == '\033')
- {
- start_at = i;
- state = 1;
- continue;
- }
- else if ((state == 1 && outbuf[i] == '[') ||
- (state == 2 && outbuf[i] == '>'))
+ else if ((state == 1 && outbuf[i] == '[')
+ || (state == 2 && outbuf[i] == '>'))
{
state ++;
continue;
@@ -3388,201 +2249,6 @@ pty_master_fwd_thread (VOID *arg)
return ((fhandler_pty_master *) arg)->pty_master_fwd_thread ();
}
-/* If master process is running as service, attaching to
- pseudo console should be done in fork. If attaching
- is done in spawn for inetd or sshd, it fails because
- the helper process is running as privileged user while
- slave process is not. This function is used to determine
- if the process is running as a srvice or not. */
-inline static bool
-is_running_as_service (void)
-{
- return check_token_membership (well_known_service_sid)
- || cygheap->user.saved_sid () == well_known_system_sid;
-}
-
-bool
-fhandler_pty_master::setup_pseudoconsole ()
-{
- 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;
- }
-
- /* Pseudo console supprot is realized using a tricky technic.
- PTY need the pseudo console handles, however, they cannot
- be retrieved by normal procedure. Therefore, run a helper
- process in a pseudo console and get them from the helper.
- Slave process will attach to the pseudo console in the
- helper process using AttachConsole(). */
- COORD size = {
- (SHORT) get_ttyp ()->winsize.ws_col,
- (SHORT) get_ttyp ()->winsize.ws_row
- };
- CreatePipe (&from_master, &to_slave, &sec_none, 0);
- SetLastError (ERROR_SUCCESS);
- HRESULT res = CreatePseudoConsole (size, from_master, to_master,
- 0, &get_ttyp ()->h_pseudo_console);
- if (res != S_OK || GetLastError () == ERROR_PROC_NOT_FOUND)
- {
- if (res != S_OK)
- system_printf ("CreatePseudoConsole() failed. %08x\n",
- GetLastError ());
- goto fallback;
- }
-
- /* If master process is running as service, attaching to
- pseudo console should be done in fork. If attaching
- is done in spawn for inetd or sshd, it fails because
- the helper process is running as privileged user while
- slave process is not. */
- if (is_running_as_service ())
- get_ttyp ()->attach_pcon_in_fork = true;
-
- STARTUPINFOEXW si_helper;
- HANDLE hello, goodbye;
- HANDLE hr, hw;
- PROCESS_INFORMATION pi_helper;
- HANDLE hpConIn, hpConOut;
- {
- SIZE_T bytesRequired;
- InitializeProcThreadAttributeList (NULL, 2, 0, &bytesRequired);
- ZeroMemory (&si_helper, sizeof (si_helper));
- si_helper.StartupInfo.cb = sizeof (STARTUPINFOEXW);
- si_helper.lpAttributeList = (PPROC_THREAD_ATTRIBUTE_LIST)
- HeapAlloc (GetProcessHeap (), 0, bytesRequired);
- if (si_helper.lpAttributeList == NULL)
- goto cleanup_pseudo_console;
- if (!InitializeProcThreadAttributeList (si_helper.lpAttributeList,
- 2, 0, &bytesRequired))
- goto cleanup_heap;
- if (!UpdateProcThreadAttribute (si_helper.lpAttributeList,
- 0,
- PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE,
- get_ttyp ()->h_pseudo_console,
- sizeof (get_ttyp ()->h_pseudo_console),
- NULL, NULL))
- goto cleanup_heap;
- /* Create events for start/stop helper process. */
- hello = CreateEvent (&sec_none, true, false, NULL);
- goodbye = CreateEvent (&sec_none, true, false, NULL);
- /* Create a pipe for receiving pseudo console handles */
- CreatePipe (&hr, &hw, &sec_none, 0);
- /* Inherit only handles which are needed by helper. */
- HANDLE handles_to_inherit[] = {hello, goodbye, hw};
- if (!UpdateProcThreadAttribute (si_helper.lpAttributeList,
- 0,
- PROC_THREAD_ATTRIBUTE_HANDLE_LIST,
- handles_to_inherit,
- sizeof (handles_to_inherit),
- NULL, NULL))
- goto cleanup_event_and_pipes;
- /* Create helper process */
- WCHAR cmd[MAX_PATH];
- path_conv helper ("/bin/cygwin-console-helper.exe");
- size_t len = helper.get_wide_win32_path_len ();
- helper.get_wide_win32_path (cmd);
- __small_swprintf (cmd + len, L" %p %p %p", hello, goodbye, hw);
- si_helper.StartupInfo.dwFlags = STARTF_USESTDHANDLES;
- si_helper.StartupInfo.hStdInput = NULL;
- si_helper.StartupInfo.hStdOutput = NULL;
- si_helper.StartupInfo.hStdError = NULL;
- if (!CreateProcessW (NULL, cmd, &sec_none, &sec_none,
- TRUE, EXTENDED_STARTUPINFO_PRESENT,
- NULL, NULL, &si_helper.StartupInfo, &pi_helper))
- goto cleanup_event_and_pipes;
- for (;;)
- {
- DWORD wait_result = WaitForSingleObject (hello, 500);
- if (wait_result == WAIT_OBJECT_0)
- break;
- if (wait_result != WAIT_TIMEOUT)
- goto cleanup_helper_process;
- DWORD exit_code;
- if (!GetExitCodeProcess(pi_helper.hProcess, &exit_code))
- goto cleanup_helper_process;
- if (exit_code == STILL_ACTIVE)
- continue;
- if (exit_code != 0 ||
- WaitForSingleObject (hello, 500) != WAIT_OBJECT_0)
- goto cleanup_helper_process;
- break;
- }
- CloseHandle (hello);
- CloseHandle (pi_helper.hThread);
- /* Retrieve pseudo console handles */
- DWORD rLen;
- char buf[64];
- if (!ReadFile (hr, buf, sizeof (buf), &rLen, NULL))
- goto cleanup_helper_process;
- buf[rLen] = '\0';
- sscanf (buf, "StdHandles=%p,%p", &hpConIn, &hpConOut);
- if (!DuplicateHandle (pi_helper.hProcess, hpConIn,
- GetCurrentProcess (), &hpConIn, 0,
- TRUE, DUPLICATE_SAME_ACCESS))
- goto cleanup_helper_process;
- if (!DuplicateHandle (pi_helper.hProcess, hpConOut,
- GetCurrentProcess (), &hpConOut, 0,
- TRUE, DUPLICATE_SAME_ACCESS))
- goto cleanup_pcon_in;
- CloseHandle (hr);
- CloseHandle (hw);
- /* Clean up */
- DeleteProcThreadAttributeList (si_helper.lpAttributeList);
- HeapFree (GetProcessHeap (), 0, si_helper.lpAttributeList);
- }
- /* Setting information of stuffs regarding pseudo console */
- get_ttyp ()->h_helper_goodbye = goodbye;
- get_ttyp ()->h_helper_process = pi_helper.hProcess;
- get_ttyp ()->helper_process_id = pi_helper.dwProcessId;
- CloseHandle (from_master);
- CloseHandle (to_master);
- from_master = hpConIn;
- to_master = hpConOut;
- ResizePseudoConsole (get_ttyp ()->h_pseudo_console, size);
- return true;
-
-cleanup_pcon_in:
- CloseHandle (hpConIn);
-cleanup_helper_process:
- SetEvent (goodbye);
- WaitForSingleObject (pi_helper.hProcess, INFINITE);
- CloseHandle (pi_helper.hProcess);
- goto skip_close_hello;
-cleanup_event_and_pipes:
- CloseHandle (hello);
-skip_close_hello:
- CloseHandle (goodbye);
- CloseHandle (hr);
- CloseHandle (hw);
-cleanup_heap:
- HeapFree (GetProcessHeap (), 0, si_helper.lpAttributeList);
-cleanup_pseudo_console:
- {
- HPCON_INTERNAL *hp = (HPCON_INTERNAL *) get_ttyp ()->h_pseudo_console;
- HANDLE tmp = hp->hConHostProcess;
- ClosePseudoConsole (get_pseudo_console ());
- CloseHandle (tmp);
- }
-fallback:
- CloseHandle (from_master);
- CloseHandle (to_slave);
- from_master = from_master_cyg;
- to_slave = NULL;
- get_ttyp ()->h_pseudo_console = NULL;
- return false;
-}
-
bool
fhandler_pty_master::setup ()
{
@@ -3595,11 +2261,6 @@ fhandler_pty_master::setup ()
if (unit < 0)
return false;
- /* from_master should be used for pseudo console.
- Just copy from_master_cyg here for the case that
- pseudo console is not available. */
- from_master = from_master_cyg;
-
ProtectHandle1 (get_output_handle (), to_pty);
tty& t = *cygwin_shared->tty[unit];
@@ -3698,15 +2359,21 @@ fhandler_pty_master::setup ()
goto err;
}
- t.winsize.ws_col = 80;
- t.winsize.ws_row = 25;
-
- setup_pseudoconsole ();
+ __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);
t.set_to_master (to_master);
t.set_to_master_cyg (to_master_cyg);
+ t.winsize.ws_col = 80;
+ t.winsize.ws_row = 25;
t.master_pid = myself->pid;
dev ().parse (DEV_PTYM_MAJOR, unit);
@@ -3719,6 +2386,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);
@@ -3778,9 +2446,6 @@ fhandler_pty_common::process_opost_output (HANDLE h, const void *ptr, ssize_t& l
{
ssize_t towrite = len;
BOOL res = TRUE;
- BOOL (WINAPI *WriteFunc)
- (HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED);
- WriteFunc = WriteFile_Orig ? WriteFile_Orig : WriteFile;
while (towrite)
{
if (!is_echo)
@@ -3803,7 +2468,7 @@ fhandler_pty_common::process_opost_output (HANDLE h, const void *ptr, ssize_t& l
if (!(get_ttyp ()->ti.c_oflag & OPOST)) // raw output mode
{
DWORD n = MIN (OUT_BUFFER_SIZE, towrite);
- res = WriteFunc (h, ptr, n, &n, NULL);
+ res = WriteFile (h, ptr, n, &n, NULL);
if (!res)
break;
ptr = (char *) ptr + n;
@@ -3853,7 +2518,7 @@ fhandler_pty_common::process_opost_output (HANDLE h, const void *ptr, ssize_t& l
break;
}
}
- res = WriteFunc (h, outbuf, n, &n, NULL);
+ res = WriteFile (h, outbuf, n, &n, NULL);
if (!res)
break;
ptr = (char *) ptr + rc;
@@ -3863,3 +2528,134 @@ fhandler_pty_common::process_opost_output (HANDLE h, const void *ptr, ssize_t& l
len -= towrite;
return res;
}
+
+bool
+fhandler_pty_slave::setup_pseudoconsole (STARTUPINFOEXW *si, bool nopcon)
+{
+
+ /* Setting switch_to_pcon_in is necessary even if
+ pseudo console will not be activated. */
+ fhandler_base *fh = ::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 (nopcon)
+ return false;
+ if (get_ttyp ()->pcon_pid && get_ttyp ()->pcon_pid != myself->pid
+ && !!pinfo (get_ttyp ()->pcon_pid))
+ 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
+ };
+ const DWORD inherit_cursor = 1;
+ SetLastError (ERROR_SUCCESS);
+ HRESULT res = CreatePseudoConsole (size, get_handle (), get_output_handle (),
+ inherit_cursor,
+ &get_ttyp ()->h_pseudo_console);
+ 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_console,
+ sizeof (get_ttyp ()->h_pseudo_console),
+ NULL, NULL))
+ goto cleanup_heap;
+ si->StartupInfo.dwFlags = STARTF_USESTDHANDLES;
+ si->StartupInfo.hStdInput = NULL;
+ si->StartupInfo.hStdOutput = NULL;
+ si->StartupInfo.hStdError = NULL;
+
+ {
+ fhandler_base *fh0 = ::cygheap->fdtab[0];
+ if (fh0 && fh0->get_device () != get_device ())
+ si->StartupInfo.hStdInput = fh0->get_handle ();
+ fhandler_base *fh1 = ::cygheap->fdtab[1];
+ if (fh1 && fh1->get_device () != get_device ())
+ si->StartupInfo.hStdOutput = fh1->get_output_handle ();
+ fhandler_base *fh2 = ::cygheap->fdtab[2];
+ if (fh2 && fh2->get_device () != get_device ())
+ si->StartupInfo.hStdError = fh2->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_console && get_ttyp ()->pcon_pid == myself->pid)
+ {
+ HPCON_INTERNAL *hp = (HPCON_INTERNAL *) get_ttyp ()->h_pseudo_console;
+ get_ttyp ()->h_pcon_write_pipe = hp->hWritePipe;
+ }
+ get_ttyp ()->pcon_start = true;
+ return true;
+
+cleanup_heap:
+ HeapFree (GetProcessHeap (), 0, si->lpAttributeList);
+cleanup_pseudo_console:
+ if (get_ttyp ()->h_pseudo_console)
+ {
+ HPCON_INTERNAL *hp = (HPCON_INTERNAL *) get_ttyp ()->h_pseudo_console;
+ HANDLE tmp = hp->hConHostProcess;
+ ClosePseudoConsole (get_ttyp ()->h_pseudo_console);
+ CloseHandle (tmp);
+ }
+fallback:
+ get_ttyp ()->h_pseudo_console = NULL;
+ return false;
+}
+
+void
+fhandler_pty_slave::close_pseudoconsole (void)
+{
+ if (get_ttyp ()->h_pseudo_console)
+ {
+ get_ttyp ()->wait_pcon_fwd ();
+ HPCON_INTERNAL *hp = (HPCON_INTERNAL *) get_ttyp ()->h_pseudo_console;
+ HANDLE tmp = hp->hConHostProcess;
+ ClosePseudoConsole (get_ttyp ()->h_pseudo_console);
+ CloseHandle (tmp);
+ get_ttyp ()->h_pseudo_console = NULL;
+ get_ttyp ()->switch_to_pcon_in = false;
+ get_ttyp ()->pcon_pid = 0;
+ get_ttyp ()->pcon_start = false;
+ }
+}
diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc
index 7c07b062e..38172ca1e 100644
--- a/winsup/cygwin/fork.cc
+++ b/winsup/cygwin/fork.cc
@@ -134,36 +134,6 @@ child_info::prefork (bool detached)
int __stdcall
frok::child (volatile char * volatile here)
{
- cygheap_fdenum cfd (false);
- while (cfd.next () >= 0)
- if (cfd->get_major () == DEV_PTYM_MAJOR)
- {
- fhandler_base *fh = cfd;
- fhandler_pty_master *ptym = (fhandler_pty_master *) fh;
- if (ptym->get_pseudo_console ())
- {
- debug_printf ("found a PTY master %d: helper_PID=%d",
- ptym->get_minor (), ptym->get_helper_process_id ());
- if (fhandler_console::get_console_process_id (
- ptym->get_helper_process_id (), true))
- /* Already attached */
- break;
- else
- {
- if (ptym->attach_pcon_in_fork ())
- {
- FreeConsole ();
- if (!AttachConsole (ptym->get_helper_process_id ()))
- /* Error */;
- else
- break;
- }
- }
- }
- }
- extern void clear_pcon_attached_to (void); /* fhandler_tty.cc */
- clear_pcon_attached_to ();
-
HANDLE& hParent = ch.parent;
sync_with_parent ("after longjmp", true);
diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc
index 4a8f3b2ec..9f1a8a57a 100644
--- a/winsup/cygwin/select.cc
+++ b/winsup/cygwin/select.cc
@@ -1215,8 +1215,7 @@ verify_tty_slave (select_record *me, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds)
{
fhandler_pty_slave *ptys = (fhandler_pty_slave *) me->fh;
- if (me->read_selected && !ptys->to_be_read_from_pcon () &&
- IsEventSignalled (ptys->input_available_event))
+ if (me->read_selected && IsEventSignalled (ptys->input_available_event))
me->read_ready = true;
return set_bits (me, readfds, writefds, exceptfds);
}
@@ -1229,8 +1228,6 @@ peek_pty_slave (select_record *s, bool from_select)
fhandler_pty_slave *ptys = (fhandler_pty_slave *) fh;
ptys->reset_switch_to_pcon ();
- if (ptys->to_be_read_from_pcon ())
- ptys->update_pcon_input_state (true);
if (s->read_selected)
{
diff --git a/winsup/cygwin/smallprint.cc b/winsup/cygwin/smallprint.cc
index 9cfb41987..4a14ee3cf 100644
--- a/winsup/cygwin/smallprint.cc
+++ b/winsup/cygwin/smallprint.cc
@@ -405,7 +405,6 @@ small_printf (const char *fmt, ...)
count = __small_vsprintf (buf, fmt, ap);
va_end (ap);
- set_ishybrid_and_switch_to_pcon (GetStdHandle (STD_ERROR_HANDLE));
WriteFile (GetStdHandle (STD_ERROR_HANDLE), buf, count, &done, NULL);
FlushFileBuffers (GetStdHandle (STD_ERROR_HANDLE));
}
@@ -432,7 +431,6 @@ console_printf (const char *fmt, ...)
count = __small_vsprintf (buf, fmt, ap);
va_end (ap);
- set_ishybrid_and_switch_to_pcon (console_handle);
WriteFile (console_handle, buf, count, &done, NULL);
FlushFileBuffers (console_handle);
}
diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc
index af177c0f1..8308bccf3 100644
--- a/winsup/cygwin/spawn.cc
+++ b/winsup/cygwin/spawn.cc
@@ -177,7 +177,7 @@ find_exec (const char *name, path_conv& buf, const char *search,
/* Utility for child_info_spawn::worker. */
static HANDLE
-handle (int fd, bool writing, bool iscygwin)
+handle (int fd, bool writing)
{
HANDLE h;
cygheap_fdget cfd (fd);
@@ -188,17 +188,30 @@ handle (int fd, bool writing, bool iscygwin)
h = INVALID_HANDLE_VALUE;
else if (!writing)
h = cfd->get_handle ();
- else if (cfd->get_major () == DEV_PTYS_MAJOR && iscygwin)
- {
- fhandler_pty_slave *ptys = (fhandler_pty_slave *)(fhandler_base *) cfd;
- h = ptys->get_output_handle_cyg ();
- }
else
h = cfd->get_output_handle ();
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)
{
@@ -266,8 +279,6 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
{
bool rc;
int res = -1;
- DWORD pid_restore = 0;
- bool attach_to_console = false;
pid_t ctty_pgid = 0;
/* Search for CTTY and retrieve its PGID */
@@ -587,9 +598,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
PROCESS_QUERY_LIMITED_INFORMATION))
sa = &sec_none_nih;
- /* 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};
@@ -598,29 +607,11 @@ 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->get_pseudo_console ())
- {
- DWORD helper_process_id = ptys->get_helper_process_id ();
- debug_printf ("found a PTY slave %d: helper_PID=%d",
- fh->get_minor (), helper_process_id);
- if (fhandler_console::get_console_process_id
- (helper_process_id, true))
- /* Already attached */
- attach_to_console = true;
- else if (!attach_to_console)
- {
- FreeConsole ();
- if (AttachConsole (helper_process_id))
- attach_to_console = true;
- }
- ptys->fixup_after_attach (!iscygwin (), fd);
- if (mode == _P_OVERLAY)
- ptys->set_freeconsole_on_close (iscygwin ());
- }
+ if (ptys_primary == NULL)
+ ptys_primary = ptys;
}
else if (fh && fh->get_major () == DEV_CONS_MAJOR)
{
- attach_to_console = true;
fhandler_console *cons = (fhandler_console *) fh;
if (wincap.has_con_24bit_colors () && !iscygwin ())
if (fd == 1 || fd == 2)
@@ -642,17 +633,28 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
/* Set up needed handles for stdio */
si.dwFlags = STARTF_USESTDHANDLES;
- si.hStdInput = handle ((in__stdin < 0 ? 0 : in__stdin), false,
- iscygwin ());
- si.hStdOutput = handle ((in__stdout < 0 ? 1 : in__stdout), true,
- iscygwin ());
- si.hStdError = handle (2, true, iscygwin ());
+ si.hStdInput = handle ((in__stdin < 0 ? 0 : in__stdin), false);
+ si.hStdOutput = handle ((in__stdout < 0 ? 1 : in__stdout), true);
+ si.hStdError = handle (2, true);
si.cb = sizeof (si);
if (!iscygwin ())
init_console_handler (myself->ctty > 0);
+ bool enable_pcon = 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_pseudoconsole (&si_pcon,
+ mode != _P_OVERLAY && mode != _P_WAIT))
+ {
+ c_flags |= EXTENDED_STARTUPINFO_PRESENT;
+ si_tmp = &si_pcon.StartupInfo;
+ enable_pcon = true;
+ }
+
loop:
/* When ruid != euid we create the new process under the current original
account and impersonate in child, this way maintaining the different
@@ -681,7 +683,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
c_flags,
envblock, /* environment */
NULL,
- &si,
+ si_tmp,
&pi);
}
else
@@ -735,7 +737,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
c_flags,
envblock, /* environment */
NULL,
- &si,
+ si_tmp,
&pi);
if (hwst)
{
@@ -748,6 +750,11 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
CloseDesktop (hdsk);
}
}
+ if (enable_pcon)
+ {
+ DeleteProcThreadAttributeList (si_pcon.lpAttributeList);
+ HeapFree (GetProcessHeap (), 0, si_pcon.lpAttributeList);
+ }
if (mode != _P_OVERLAY)
SetHandleInformation (my_wr_proc_pipe, HANDLE_FLAG_INHERIT,
@@ -920,6 +927,11 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
}
if (sem)
__posix_spawn_sem_release (sem, 0);
+ if (enable_pcon)
+ {
+ WaitForSingleObject (pi.hProcess, INFINITE);
+ ptys_primary->close_pseudoconsole ();
+ }
myself.exit (EXITCODE_NOSET);
break;
case _P_WAIT:
@@ -927,6 +939,8 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
system_call.arm ();
if (waitpid (cygpid, &res, 0) != cygpid)
res = -1;
+ if (enable_pcon)
+ ptys_primary->close_pseudoconsole ();
break;
case _P_DETACH:
res = 0; /* Lost all memory of this child. */
@@ -953,21 +967,6 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
if (envblock)
free (envblock);
- if (attach_to_console && pid_restore)
- {
- FreeConsole ();
- AttachConsole (pid_restore);
- cygheap_fdenum cfd (false);
- int fd;
- while ((fd = cfd.next ()) >= 0)
- if (cfd->get_major () == DEV_PTYS_MAJOR)
- {
- fhandler_pty_slave *ptys =
- (fhandler_pty_slave *) (fhandler_base *) cfd;
- ptys->fixup_after_attach (false, fd);
- }
- }
-
return (int) res;
}
diff --git a/winsup/cygwin/strace.cc b/winsup/cygwin/strace.cc
index f0aef3a36..35f8a59ae 100644
--- a/winsup/cygwin/strace.cc
+++ b/winsup/cygwin/strace.cc
@@ -264,7 +264,6 @@ strace::vprntf (unsigned category, const char *func, const char *fmt, va_list ap
if (category & _STRACE_SYSTEM)
{
DWORD done;
- set_ishybrid_and_switch_to_pcon (GetStdHandle (STD_ERROR_HANDLE));
WriteFile (GetStdHandle (STD_ERROR_HANDLE), buf, len, &done, 0);
FlushFileBuffers (GetStdHandle (STD_ERROR_HANDLE));
/* Make sure that the message shows up on the screen, too, since this is
@@ -276,7 +275,6 @@ strace::vprntf (unsigned category, const char *func, const char *fmt, va_list ap
&sec_none, OPEN_EXISTING, 0, 0);
if (h != INVALID_HANDLE_VALUE)
{
- set_ishybrid_and_switch_to_pcon (h);
WriteFile (h, buf, len, &done, 0);
CloseHandle (h);
}
diff --git a/winsup/cygwin/tty.cc b/winsup/cygwin/tty.cc
index 4cb68f776..d60f27545 100644
--- a/winsup/cygwin/tty.cc
+++ b/winsup/cygwin/tty.cc
@@ -234,20 +234,14 @@ tty::init ()
was_opened = false;
master_pid = 0;
is_console = false;
- attach_pcon_in_fork = false;
- h_pseudo_console = NULL;
column = 0;
+ h_pseudo_console = NULL;
switch_to_pcon_in = false;
- switch_to_pcon_out = false;
- screen_alternated = false;
mask_switch_to_pcon_in = false;
pcon_pid = 0;
term_code_page = 0;
- need_redraw_screen = true;
pcon_last_time = 0;
- pcon_in_empty = true;
- req_transfer_input_to_pcon = false;
- req_flush_pcon_input = false;
+ pcon_start = false;
}
HANDLE
@@ -294,16 +288,6 @@ tty_min::ttyname ()
}
void
-tty::set_switch_to_pcon_out (bool v)
-{
- if (switch_to_pcon_out != v)
- {
- wait_pcon_fwd ();
- switch_to_pcon_out = v;
- }
-}
-
-void
tty::wait_pcon_fwd (void)
{
/* The forwarding in pseudo console sometimes stops for
diff --git a/winsup/cygwin/tty.h b/winsup/cygwin/tty.h
index 920e32b16..c491d3891 100644
--- a/winsup/cygwin/tty.h
+++ b/winsup/cygwin/tty.h
@@ -94,21 +94,13 @@ private:
HANDLE _to_master;
HANDLE _to_master_cyg;
HPCON h_pseudo_console;
- HANDLE h_helper_process;
- DWORD helper_process_id;
- HANDLE h_helper_goodbye;
- bool attach_pcon_in_fork;
+ bool pcon_start;
bool switch_to_pcon_in;
- bool switch_to_pcon_out;
- bool screen_alternated;
bool mask_switch_to_pcon_in;
pid_t pcon_pid;
UINT term_code_page;
- bool need_redraw_screen;
DWORD pcon_last_time;
- bool pcon_in_empty;
- bool req_transfer_input_to_pcon;
- bool req_flush_pcon_input;
+ HANDLE h_pcon_write_pipe;
public:
HANDLE from_master () const { return _from_master; }
@@ -138,7 +130,6 @@ public:
void set_master_ctl_closed () {master_pid = -1;}
static void __stdcall create_master (int);
static void __stdcall init_session ();
- void set_switch_to_pcon_out (bool v);
void wait_pcon_fwd (void);
friend class fhandler_pty_common;
friend class fhandler_pty_master;
diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h
index 9bfa1a7a6..79844cb87 100644
--- a/winsup/cygwin/winsup.h
+++ b/winsup/cygwin/winsup.h
@@ -224,9 +224,6 @@ void init_console_handler (bool);
extern bool wsock_started;
-/* PTY related */
-void set_ishybrid_and_switch_to_pcon (HANDLE h);
-
/* Printf type functions */
extern "C" void vapi_fatal (const char *, va_list ap) __attribute__ ((noreturn));
extern "C" void api_fatal (const char *, ...) __attribute__ ((noreturn));