diff options
Diffstat (limited to 'winsup/cygwin/spawn.cc')
-rw-r--r-- | winsup/cygwin/spawn.cc | 32 |
1 files changed, 20 insertions, 12 deletions
diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index ef175e7..680f0fe 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -542,10 +542,6 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, ::cygheap->ctty ? ::cygheap->ctty->tc_getpgid () : 0; if (!iscygwin () && ctty_pgid && ctty_pgid != myself->pgid) c_flags |= CREATE_NEW_PROCESS_GROUP; - refresh_cygheap (); - - if (c_flags & CREATE_NEW_PROCESS_GROUP) - InterlockedOr ((LONG *) &myself->process_state, PID_NEW_PG); if (mode == _P_DETACH) /* all set */; @@ -605,10 +601,17 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, ::cygheap->user.deimpersonate (); if (!real_path.iscygexec () && mode == _P_OVERLAY) - InterlockedOr ((LONG *) &myself->process_state, PID_NOTCYGWIN); + { + LONG pidflags = PID_NOTCYGWIN; + if (c_flags & CREATE_NEW_PROCESS_GROUP) + pidflags |= PID_NEW_PG; + InterlockedOr ((LONG *) &myself->process_state, pidflags); + } cygpid = (mode != _P_OVERLAY) ? create_cygwin_pid () : myself->pid; + cygheap->lock (); + refresh_cygheap (); wchar_t wcmd[(size_t) cmd]; if (!::cygheap->user.issetuid () || (::cygheap->user.saved_uid == ::cygheap->user.real_uid @@ -707,7 +710,8 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, myself->sendsig = myself->exec_sendsig; myself->exec_sendsig = NULL; } - InterlockedAnd ((LONG *) &myself->process_state, ~PID_NOTCYGWIN); + InterlockedAnd ((LONG *) &myself->process_state, + ~(PID_NOTCYGWIN|PID_NEW_PG)); /* 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 @@ -725,6 +729,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, ::cygheap->user.reimpersonate (); res = -1; + cygheap->unlock (); __leave; } @@ -761,21 +766,22 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, NtClose (old_winpid_hdl); real_path.get_wide_win32_path (myself->progname); // FIXME: race? sigproc_printf ("new process name %W", myself->progname); - if (!iscygwin ()) - close_all_files (); } else { myself->set_has_pgid_children (); ProtectHandle (pi.hThread); pinfo child (cygpid, - PID_IN_USE | (real_path.iscygexec () ? 0 : PID_NOTCYGWIN)); + PID_IN_USE | + (real_path.iscygexec () ? 0 : PID_NOTCYGWIN) | + ((c_flags & CREATE_NEW_PROCESS_GROUP) ? PID_NEW_PG : 0)); if (!child) { syscall_printf ("pinfo failed"); if (get_errno () != ENOMEM) set_errno (EAGAIN); res = -1; + cygheap->unlock (); __leave; } child->dwProcessId = pi.dwProcessId; @@ -811,6 +817,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, CloseHandle (pi.hProcess); ForceCloseHandle (pi.hThread); res = -1; + cygheap->unlock (); __leave; } } @@ -839,6 +846,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, /* 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; + cygheap->unlock (); switch (mode) { @@ -855,8 +863,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, } else { - if (iscygwin ()) - close_all_files (true); + close_all_files (iscygwin ()); if (!my_wr_proc_pipe && WaitForSingleObject (pi.hProcess, 0) == WAIT_TIMEOUT) wait_for_myself (); @@ -943,6 +950,7 @@ spawnve (int mode, const char *path, const char *const *argv, if (!envp) envp = empty_env; + child_info_spawn ch_spawn_local (_CH_NADA, false); switch (_P_MODE (mode)) { case _P_OVERLAY: @@ -956,7 +964,7 @@ spawnve (int mode, const char *path, const char *const *argv, case _P_WAIT: case _P_DETACH: case _P_SYSTEM: - ret = ch_spawn.worker (path, argv, envp, mode); + ret = ch_spawn_local.worker (path, argv, envp, mode); break; default: set_errno (EINVAL); |