diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index c3999350e..10717e399 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,12 @@ +2015-06-08 Corinna Vinschen + + * 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 * pinfo.cc (_pinfo::commune_request): Don't try to send commune diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index 4bebbbc99..f7fd9f00c 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 6fdccf0f0..f9bddb568 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 +