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:
authorChristopher Faylor <me@cgf.cx>2012-05-07 19:05:56 +0400
committerChristopher Faylor <me@cgf.cx>2012-05-07 19:05:56 +0400
commit06bd0ef2ab50252b81344d6810378b18f49c0e9c (patch)
tree706b392427696073753a7abd18e00d5615d5acb7 /winsup/cygwin/spawn.cc
parent8620cb792502d89d399064ea038d2b32bc611f45 (diff)
* 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'.
Diffstat (limited to 'winsup/cygwin/spawn.cc')
-rw-r--r--winsup/cygwin/spawn.cc42
1 files changed, 29 insertions, 13 deletions
diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc
index d296597d1..8b5e382c5 100644
--- a/winsup/cygwin/spawn.cc
+++ b/winsup/cygwin/spawn.cc
@@ -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)
{