[newlib-cygwin] Cygwin: spawn: create and maintain winpid symlinks

Corinna Vinschen corinna@sourceware.org
Sat Feb 2 20:07:00 GMT 2019


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

commit 3a3934252c2cb390b3970edb4898f452ea2f641a
Author: Corinna Vinschen <corinna@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 <corinna@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);



More information about the Cygwin-cvs mailing list