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

commit 575ec00a43ae3bbc84d5dab1233c3f95fdad18d0
Author: Corinna Vinschen <cori...@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 <cori...@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  <cori...@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  <cori...@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
+

Reply via email to