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:
parent
d6cf2b781f
commit
3a3934252c
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue