diff options
Diffstat (limited to 'winsup/cygwin/spawn.cc')
-rw-r--r-- | winsup/cygwin/spawn.cc | 42 |
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) { |