[newlib-cygwin] Evaluate /proc/$PID/{root, cwd, cmdline} for native processes

Corinna Vinschen corinna@sourceware.org
Mon Jun 8 19:48:00 GMT 2015


https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=575ec00a43ae3bbc84d5dab1233c3f95fdad18d0

commit 575ec00a43ae3bbc84d5dab1233c3f95fdad18d0
Author: Corinna Vinschen <corinna@vinschen.de>
Date:   Mon Jun 8 21:48:13 2015 +0200

    Evaluate /proc/$PID/{root,cwd,cmdline} for native processes
    
    	* pinfo.cc (_pinfo::root): Fake default root for native processes.
    	(open_commune_proc_parms): New helper function to access process
    	parameter block.
    	(_pinfo::cwd): Fetch missing cwd for native processes from processes
    	parameter block.
    	(_pinfo::cmdline): Ditto for command line.
    
    Signed-off-by: Corinna Vinschen <corinna@vinschen.de>

Diff:
---
 winsup/cygwin/ChangeLog     |  9 +++++
 winsup/cygwin/pinfo.cc      | 84 +++++++++++++++++++++++++++++++++++++++++++--
 winsup/cygwin/release/2.0.4 |  4 +++
 3 files changed, 94 insertions(+), 3 deletions(-)

diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index c399935..10717e3 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,14 @@
 2015-06-08  Corinna Vinschen  <corinna@vinschen.de>
 
+	* pinfo.cc (_pinfo::root): Fake default root for native processes.
+	(open_commune_proc_parms): New helper function to access process
+	parameter block.
+	(_pinfo::cwd): Fetch missing cwd for native processes from processes
+	parameter block.
+	(_pinfo::cmdline): Ditto for command line.
+
+2015-06-08  Corinna Vinschen  <corinna@vinschen.de>
+
 	* pinfo.cc (_pinfo::commune_request): Don't try to send commune
 	requests to non-Cygwin processes.
 
diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc
index 4bebbbc..f7fd9f0 100644
--- a/winsup/cygwin/pinfo.cc
+++ b/winsup/cygwin/pinfo.cc
@@ -850,7 +850,7 @@ _pinfo::root (size_t& n)
   char *s;
   if (!this || !pid)
     return NULL;
-  if (pid != myself->pid)
+  if (pid != myself->pid && !ISSTATE (this, PID_NOTCYGWIN))
     {
       commune_result cr = commune_request (PICOM_ROOT);
       s = cr.s;
@@ -867,13 +867,60 @@ _pinfo::root (size_t& n)
   return s;
 }
 
+static HANDLE
+open_commune_proc_parms (DWORD pid, PRTL_USER_PROCESS_PARAMETERS prupp)
+{
+  HANDLE proc;
+  NTSTATUS status;
+  PROCESS_BASIC_INFORMATION pbi;
+  PEB lpeb;
+
+  proc = OpenProcess (PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
+  if (!proc)
+    return NULL;
+  status = NtQueryInformationProcess (proc, ProcessBasicInformation,
+				      &pbi, sizeof pbi, NULL);
+  if (NT_SUCCESS (status)
+      && ReadProcessMemory (proc, pbi.PebBaseAddress, &lpeb, sizeof lpeb, NULL)
+      && ReadProcessMemory (proc, lpeb.ProcessParameters, prupp, sizeof *prupp,
+			    NULL))
+	return proc;
+  NtClose (proc);
+  return NULL;
+}
+
 char *
 _pinfo::cwd (size_t& n)
 {
   char *s;
   if (!this || !pid)
     return NULL;
-  if (pid != myself->pid)
+  if (ISSTATE (this, PID_NOTCYGWIN))
+    {
+      RTL_USER_PROCESS_PARAMETERS rupp;
+      HANDLE proc = open_commune_proc_parms (dwProcessId, &rupp);
+
+      n = 0;
+      if (!proc)
+	return NULL;
+
+      tmp_pathbuf tp;
+      PWCHAR cwd = tp.w_get ();
+
+      if (ReadProcessMemory (proc, rupp.CurrentDirectoryName.Buffer,
+			     cwd, rupp.CurrentDirectoryName.Length,
+			     NULL))
+	{
+	  /* Drop trailing backslash, add trailing \0 in passing. */
+	  cwd[rupp.CurrentDirectoryName.Length / sizeof (WCHAR) - 1]
+	  = L'\0';
+	  s = (char *) cmalloc_abort (HEAP_COMMUNE, NT_MAX_PATH);
+	  mount_table->conv_to_posix_path (cwd, s, 0);
+	  n = strlen (s) + 1;
+	}
+      NtClose (proc);
+    }
+  else if (pid != myself->pid)
     {
       commune_result cr = commune_request (PICOM_CWD);
       s = cr.s;
@@ -894,7 +941,38 @@ _pinfo::cmdline (size_t& n)
   char *s;
   if (!this || !pid)
     return NULL;
-  if (pid != myself->pid)
+  if (ISSTATE (this, PID_NOTCYGWIN))
+    {
+      RTL_USER_PROCESS_PARAMETERS rupp;
+      HANDLE proc = open_commune_proc_parms (dwProcessId, &rupp);
+
+      n = 0;
+      if (!proc)
+	return NULL;
+
+      tmp_pathbuf tp;
+      PWCHAR cmdline = tp.w_get ();
+
+      if (ReadProcessMemory (proc, rupp.CommandLine.Buffer, cmdline,
+			     rupp.CommandLine.Length, NULL))
+	{
+	  /* Add trailing \0. */
+	  cmdline[rupp.CommandLine.Length / sizeof (WCHAR)]
+	  = L'\0';
+	  n = sys_wcstombs_alloc (&s, HEAP_COMMUNE, cmdline,
+				  rupp.CommandLine.Length
+				  / sizeof (WCHAR));
+	  /* Quotes & Spaces post-processing. */
+	  bool in_quote = false;
+	  for (char *c = s; *c; ++c)
+	    if (*c == '"')
+	      in_quote = !in_quote;
+	    else if (*c == ' ' && !in_quote)
+	     *c = '\0';
+	}
+      NtClose (proc);
+    }
+  else if (pid != myself->pid)
     {
       commune_result cr = commune_request (PICOM_CMDLINE);
       s = cr.s;
diff --git a/winsup/cygwin/release/2.0.4 b/winsup/cygwin/release/2.0.4
index 6fdccf0..f9bddb5 100644
--- a/winsup/cygwin/release/2.0.4
+++ b/winsup/cygwin/release/2.0.4
@@ -12,3 +12,7 @@ Bug Fixes
 
 - Fix installing newly added bind mounts with `mount -a'.
   Addresses: https://cygwin.com/ml/cygwin/2015-06/msg00150.html
+
+- Add missing evaluation of /proc/$PID/{root,cwd,cmdline} for native processes.
+  Addresses: https://cygwin.com/ml/cygwin/2015-06/msg00173.html
+



More information about the Cygwin-cvs mailing list