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>
This commit is contained in:
		| @@ -204,6 +204,7 @@ public: | |||||||
|   } |   } | ||||||
| #endif | #endif | ||||||
|   HANDLE shared_handle () {return h;} |   HANDLE shared_handle () {return h;} | ||||||
|  |   HANDLE shared_winpid_handle () {return winpid_hdl;} | ||||||
|   void set_acl (); |   void set_acl (); | ||||||
|   friend class _pinfo; |   friend class _pinfo; | ||||||
|   friend class winpids; |   friend class winpids; | ||||||
|   | |||||||
| @@ -725,6 +725,16 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, | |||||||
| 	  myself->dwProcessId = pi.dwProcessId; | 	  myself->dwProcessId = pi.dwProcessId; | ||||||
| 	  strace.execing = 1; | 	  strace.execing = 1; | ||||||
| 	  myself.hProcess = hExeced = pi.hProcess; | 	  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? | 	  real_path.get_wide_win32_path (myself->progname); // FIXME: race? | ||||||
| 	  sigproc_printf ("new process name %W", myself->progname); | 	  sigproc_printf ("new process name %W", myself->progname); | ||||||
| 	  if (!iscygwin ()) | 	  if (!iscygwin ()) | ||||||
| @@ -748,13 +758,23 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, | |||||||
| 	  child.hProcess = pi.hProcess; | 	  child.hProcess = pi.hProcess; | ||||||
|  |  | ||||||
| 	  real_path.get_wide_win32_path (child->progname); | 	  real_path.get_wide_win32_path (child->progname); | ||||||
| 	  /* FIXME: This introduces an unreferenced, open handle into the child. | 	  /* This introduces an unreferenced, open handle into the child. | ||||||
| 	     The purpose is to keep the pid shared memory open so that all of | 	     The purpose is to keep the pid shared memory open so that all | ||||||
| 	     the fields filled out by child.remember do not disappear and so | 	     of the fields filled out by child.remember do not disappear | ||||||
| 	     there is not a brief period during which the pid is not available. | 	     and so there is not a brief period during which the pid is | ||||||
| 	     However, we should try to find another way to do this eventually. */ | 	     not available. */ | ||||||
| 	  DuplicateHandle (GetCurrentProcess (), child.shared_handle (), | 	  DuplicateHandle (GetCurrentProcess (), child.shared_handle (), | ||||||
| 			   pi.hProcess, NULL, 0, 0, DUPLICATE_SAME_ACCESS); | 			   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->start_time = time (NULL); /* Register child's starting time. */ | ||||||
| 	  child->nice = myself->nice; | 	  child->nice = myself->nice; | ||||||
| 	  postfork (child); | 	  postfork (child); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user