diff options
Diffstat (limited to 'winsup/cygwin/spawn.cc')
-rw-r--r-- | winsup/cygwin/spawn.cc | 55 |
1 files changed, 19 insertions, 36 deletions
diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index 8a82f8a11..c05c7af9f 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -422,10 +422,10 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, moreinfo->argc = newargv.argc; moreinfo->argv = newargv; - if (mode != _P_OVERLAY || !real_path.iscygexec () - || !DuplicateHandle (GetCurrentProcess (), myself.shared_handle (), - GetCurrentProcess (), &moreinfo->myself_pinfo, - 0, TRUE, DUPLICATE_SAME_ACCESS)) + if (mode != _P_OVERLAY || + !DuplicateHandle (GetCurrentProcess (), myself.shared_handle (), + GetCurrentProcess (), &moreinfo->myself_pinfo, + 0, TRUE, DUPLICATE_SAME_ACCESS)) moreinfo->myself_pinfo = NULL; else VerifyHandle (moreinfo->myself_pinfo); @@ -453,7 +453,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, c_flags |= CREATE_SEPARATE_WOW_VDM | CREATE_UNICODE_ENVIRONMENT; - if (wincap.has_program_compatibility_assistant ()) + if (wincap.has_program_compatibility_assitant ()) { /* We're adding the CREATE_BREAKAWAY_FROM_JOB flag here to workaround issues with the "Program Compatibility Assistant (PCA) Service" @@ -517,6 +517,17 @@ 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) @@ -596,7 +607,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, in a console will break native processes running in the background, because the Ctrl-C event is sent to all processes in the console, unless they ignore it explicitely. CREATE_NEW_PROCESS_GROUP does that for us. */ - if (!iscygwin () && fhandler_console::exists () + if (!iscygwin () && myself->ctty >= 0 && iscons_dev (myself->ctty) && fhandler_console::tc_getpgid () != myself->pgid) c_flags |= CREATE_NEW_PROCESS_GROUP; refresh_cygheap (); @@ -608,20 +619,6 @@ 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); - } - parent_winpid = GetCurrentProcessId (); - /* 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. @@ -743,12 +740,6 @@ 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 (!iscygwin () && 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; @@ -770,7 +761,7 @@ loop: cygpid = myself->pid; /* We print the original program name here so the user can see that too. */ - syscall_printf ("pid %d, prog_arg %s, cmd line %.9500s)", + syscall_printf ("%d = child_info_spawn::worker(%s, %.9500s)", rc ? cygpid : (unsigned int) -1, prog_arg, one_line.buf); /* Name the handle similarly to proc_subproc. */ @@ -830,12 +821,6 @@ 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); @@ -848,9 +833,7 @@ loop: if ((mode == _P_DETACH || mode == _P_NOWAIT) && !iscygwin ()) synced = false; else - /* 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; + synced = sync (pi.dwProcessId, pi.hProcess, INFINITE); switch (mode) { |