* DevNotes: Add entry cgf-000003.

* cygheap.h (init_cygheap::pid_handle): Delete.
* dcrt0.cc (child_info_spawn::handle_spawn): Keep parent open if we have
execed.
* pinfo.cc (pinfo::thisproc): Remove pid_handle manipulations.
(pinfo::init): Don't consider a reaped process to be available.
* spawn.cc (child_info_spawn::worker): Remove pid_handle manipulations.  Make
wr_proc_pipe and parent noninheritable when starting a program which doesn't
use the Cygwin DLL.  Conditionally reset wr_proc_pipe to inheritable if
CreateProcess fails.  Inject wr_proc_pipe handle into non-Cygwin process.
Consider a non-cygwin process to be 'synced'.
This commit is contained in:
Christopher Faylor
2012-05-07 15:05:56 +00:00
parent 8620cb7925
commit 06bd0ef2ab
7 changed files with 110 additions and 24 deletions

View File

@ -517,17 +517,6 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
myself->sendsig = NULL;
reset_sendsig = true;
}
/* Save a copy of a handle to the current process around the first time we
exec so that the pid will not be reused. Why did I stop cygwin from
generating its own pids again? */
if (::cygheap->pid_handle)
/* already done previously */;
else if (DuplicateHandle (GetCurrentProcess (), GetCurrentProcess (),
GetCurrentProcess (), &::cygheap->pid_handle,
PROCESS_QUERY_INFORMATION, TRUE, 0))
ProtectHandleINH (::cygheap->pid_handle);
else
system_printf ("duplicate to pid_handle failed, %E");
}
if (null_app_name)
@ -613,6 +602,19 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
else
wr_proc_pipe = my_wr_proc_pipe;
/* Don't allow child to inherit these handles if it's not a Cygwin program.
wr_proc_pipe will be injected later. parent won't be used by the child
so there is no reason for the child to have it open as it can confuse
ps into thinking that children of windows processes are all part of
the same "execed" process.
FIXME: Someday, make it so that parent is never created when starting
non-Cygwin processes. */
if (!iscygwin ())
{
SetHandleInformation (wr_proc_pipe, HANDLE_FLAG_INHERIT, 0);
SetHandleInformation (parent, HANDLE_FLAG_INHERIT, 0);
}
/* When ruid != euid we create the new process under the current original
account and impersonate in child, this way maintaining the different
effective vs. real ids.
@ -734,6 +736,12 @@ loop:
myself->exec_sendsig = NULL;
}
myself->process_state &= ~PID_NOTCYGWIN;
/* Reset handle inheritance to default when the execution of a non-Cygwin
process fails. Only need to do this for _P_OVERLAY since the handle will
be closed otherwise. Don't need to do this for 'parent' since it will
be closed in every case. See FIXME above. */
if (!real_path.iscygexec () && mode == _P_OVERLAY)
SetHandleInformation (wr_proc_pipe, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
if (wr_proc_pipe == my_wr_proc_pipe)
wr_proc_pipe = NULL; /* We still own it: don't nuke in destructor */
res = -1;
@ -755,7 +763,7 @@ loop:
cygpid = myself->pid;
/* We print the original program name here so the user can see that too. */
syscall_printf ("%d = child_info_spawn::worker(%s, %.9500s)",
syscall_printf ("pid %d, prog_arg %s, cmd line %.9500s)",
rc ? cygpid : (unsigned int) -1, prog_arg, one_line.buf);
/* Name the handle similarly to proc_subproc. */
@ -815,6 +823,12 @@ loop:
/* Start the child running */
if (c_flags & CREATE_SUSPENDED)
{
/* Inject a non-inheritable wr_proc_pipe handle into child so that we
can accurately track when the child exits without keeping this
process waiting around for it to exit. */
if (!iscygwin ())
DuplicateHandle (GetCurrentProcess (), wr_proc_pipe, pi.hProcess, NULL,
0, false, DUPLICATE_SAME_ACCESS);
ResumeThread (pi.hThread);
if (iscygwin ())
strace.write_childpid (pi.dwProcessId);
@ -827,7 +841,9 @@ loop:
if ((mode == _P_DETACH || mode == _P_NOWAIT) && !iscygwin ())
synced = false;
else
synced = sync (pi.dwProcessId, pi.hProcess, INFINITE);
/* Just mark a non-cygwin process as 'synced'. We will still eventually
wait for it to exit in maybe_set_exit_code_from_windows(). */
synced = iscygwin () ? sync (pi.dwProcessId, pi.hProcess, INFINITE) : true;
switch (mode)
{