[PATCH v2] Cygwin: pty: Disable clear screen for ssh sessions with -t option.

Takashi Yano takashi.yano@nifty.ne.jp
Fri Oct 18 23:52:00 GMT 2019


---
 winsup/cygwin/fhandler_tty.cc | 67 ++++++++++++++++++++++-------------
 winsup/cygwin/tty.cc          |  1 +
 winsup/cygwin/tty.h           |  1 +
 3 files changed, 44 insertions(+), 25 deletions(-)

diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index da6119dfb..d82757e97 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -1296,6 +1296,30 @@ detach:
   restore_reattach_pcon ();
 }
 
+/* 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. */
+static bool
+is_running_as_service (void)
+{
+  DWORD dwSize = 0;
+  PTOKEN_GROUPS pGroupInfo;
+  tmp_pathbuf tp;
+  pGroupInfo = (PTOKEN_GROUPS) tp.w_get ();
+  NtQueryInformationToken (hProcToken, TokenGroups, pGroupInfo,
+					2 * NT_MAX_PATH, &dwSize);
+  for (DWORD i=0; i<pGroupInfo->GroupCount; i++)
+    if (RtlEqualSid (well_known_service_sid, pGroupInfo->Groups[i].Sid))
+      return true;
+  for (DWORD i=0; i<pGroupInfo->GroupCount; i++)
+    if (RtlEqualSid (mandatory_system_integrity_sid, pGroupInfo->Groups[i].Sid))
+      return true;
+  return false;
+}
+
 ssize_t __stdcall
 fhandler_pty_slave::write (const void *ptr, size_t len)
 {
@@ -1305,6 +1329,18 @@ fhandler_pty_slave::write (const void *ptr, size_t len)
   if (bg <= bg_eof)
     return (ssize_t) bg;
 
+  if (get_ttyp ()->need_clear_screen_on_write)
+    {
+      if (is_running_as_service ())
+	{
+	  /* FIXME: Clearing sequence may not be "^[[H^[[J"
+	     depending on the terminal type. */
+	  DWORD n;
+	  WriteFile (get_output_handle_cyg (), "\033[H\033[J", 6, &n, NULL);
+	}
+      get_ttyp ()->need_clear_screen_on_write = false;
+    }
+
   termios_printf ("pty%d, write(%p, %lu)", get_minor (), ptr, len);
 
   push_process_state process_state (PID_TTYOU);
@@ -2668,7 +2704,12 @@ fhandler_pty_slave::fixup_after_attach (bool native_maybe, int fd_set)
 	  if (get_ttyp ()->num_pcon_attached_slaves == 0
 	      && !ALWAYS_USE_PCON)
 	    /* Assume this is the first process using this pty slave. */
-	    get_ttyp ()->need_clear_screen = true;
+	    {
+	      if (is_running_as_service ())
+		get_ttyp ()->need_clear_screen_on_write = true;
+	      else
+		get_ttyp ()->need_clear_screen = true;
+	    }
 
 	  get_ttyp ()->num_pcon_attached_slaves ++;
 	}
@@ -3088,30 +3129,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. */
-static bool
-is_running_as_service (void)
-{
-  DWORD dwSize = 0;
-  PTOKEN_GROUPS pGroupInfo;
-  tmp_pathbuf tp;
-  pGroupInfo = (PTOKEN_GROUPS) tp.w_get ();
-  NtQueryInformationToken (hProcToken, TokenGroups, pGroupInfo,
-					2 * NT_MAX_PATH, &dwSize);
-  for (DWORD i=0; i<pGroupInfo->GroupCount; i++)
-    if (RtlEqualSid (well_known_service_sid, pGroupInfo->Groups[i].Sid))
-      return true;
-  for (DWORD i=0; i<pGroupInfo->GroupCount; i++)
-    if (RtlEqualSid (well_known_interactive_sid, pGroupInfo->Groups[i].Sid))
-      return false;
-  return true;
-}
-
 bool
 fhandler_pty_master::setup_pseudoconsole ()
 {
diff --git a/winsup/cygwin/tty.cc b/winsup/cygwin/tty.cc
index 460153cdb..1595d0278 100644
--- a/winsup/cygwin/tty.cc
+++ b/winsup/cygwin/tty.cc
@@ -245,6 +245,7 @@ tty::init ()
   num_pcon_attached_slaves = 0;
   term_code_page = 0;
   need_clear_screen = false;
+  need_clear_screen_on_write = false;
 }
 
 HANDLE
diff --git a/winsup/cygwin/tty.h b/winsup/cygwin/tty.h
index 927d7afd9..c7aeef85b 100644
--- a/winsup/cygwin/tty.h
+++ b/winsup/cygwin/tty.h
@@ -106,6 +106,7 @@ private:
   int num_pcon_attached_slaves;
   UINT term_code_page;
   bool need_clear_screen;
+  bool need_clear_screen_on_write;
 
 public:
   HANDLE from_master () const { return _from_master; }
-- 
2.21.0



More information about the Cygwin-patches mailing list