https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=3a3934252c2cb390b3970edb4898f452ea2f641a
commit 3a3934252c2cb390b3970edb4898f452ea2f641a Author: Corinna Vinschen <cori...@vinschen.de> Date: Sat Feb 2 20:01:41 2019 +0100 Cygwin: spawn: create and maintain winpid symlinks - If the execve'ed process is a non-Cygwin process, we have to create the matching winpid symlink and remove the old one ourselves. - If we spawn a child, the winpid symlink has to be maintained by the child process, otherwise it disappears if the parent process exits. Signed-off-by: Corinna Vinschen <cori...@vinschen.de> Diff: --- winsup/cygwin/pinfo.h | 1 + winsup/cygwin/spawn.cc | 30 +++++++++++++++++++++++++----- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/winsup/cygwin/pinfo.h b/winsup/cygwin/pinfo.h index 38a34f3..8cf1bba 100644 --- a/winsup/cygwin/pinfo.h +++ b/winsup/cygwin/pinfo.h @@ -204,6 +204,7 @@ public: } #endif HANDLE shared_handle () {return h;} + HANDLE shared_winpid_handle () {return winpid_hdl;} void set_acl (); friend class _pinfo; friend class winpids; diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index 58e2696..d969c66 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -725,6 +725,16 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, myself->dwProcessId = pi.dwProcessId; strace.execing = 1; myself.hProcess = hExeced = pi.hProcess; + if (!real_path.iscygexec ()) + { + /* If the child process is not a Cygwin process, we have to + create a new winpid symlink and drop the old one on + behalf of the child process not being able to do this + by itself. */ + HANDLE old_winpid_hdl = myself.shared_winpid_handle (); + myself.create_winpid_symlink (); + NtClose (old_winpid_hdl); + } real_path.get_wide_win32_path (myself->progname); // FIXME: race? sigproc_printf ("new process name %W", myself->progname); if (!iscygwin ()) @@ -748,13 +758,23 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, child.hProcess = pi.hProcess; real_path.get_wide_win32_path (child->progname); - /* FIXME: This introduces an unreferenced, open handle into the child. - The purpose is to keep the pid shared memory open so that all of - the fields filled out by child.remember do not disappear and so - there is not a brief period during which the pid is not available. - However, we should try to find another way to do this eventually. */ + /* This introduces an unreferenced, open handle into the child. + The purpose is to keep the pid shared memory open so that all + of the fields filled out by child.remember do not disappear + and so there is not a brief period during which the pid is + not available. */ DuplicateHandle (GetCurrentProcess (), child.shared_handle (), pi.hProcess, NULL, 0, 0, DUPLICATE_SAME_ACCESS); + if (!real_path.iscygexec ()) + { + /* If the child process is not a Cygwin process, we have to + create a new winpid symlink and induce it into the child + process as well to keep it over the lifetime of the child. */ + child.create_winpid_symlink (); + DuplicateHandle (GetCurrentProcess (), + child.shared_winpid_handle (), + pi.hProcess, NULL, 0, 0, DUPLICATE_SAME_ACCESS); + } child->start_time = time (NULL); /* Register child's starting time. */ child->nice = myself->nice; postfork (child);