Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2019-02-02 22:01:41 +0300
committerCorinna Vinschen <corinna@vinschen.de>2019-02-02 22:01:41 +0300
commit3a3934252c2cb390b3970edb4898f452ea2f641a (patch)
treead8c956eac42cd8c1c1cfc9e86dd2dccac56ea03
parentd6cf2b781f4e14f81442ee5aaeaea9f6da73199b (diff)
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>
-rw-r--r--winsup/cygwin/pinfo.h1
-rw-r--r--winsup/cygwin/spawn.cc30
2 files changed, 26 insertions, 5 deletions
diff --git a/winsup/cygwin/pinfo.h b/winsup/cygwin/pinfo.h
index 38a34f327..8cf1bba2e 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 58e2696a1..d969c66ea 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);