diff options
author | Christopher Faylor <me@cgf.cx> | 2005-01-11 15:31:04 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2005-01-11 15:31:04 +0000 |
commit | 2380dfe14ca24fcc7ddb63feb8f7e4958c1a76ea (patch) | |
tree | 38221c0ab6a47ce8876b141458489586a7a6b635 /winsup/cygwin/spawn.cc | |
parent | aa67a4484ee30a61d1d12da8209308ab691f6bba (diff) | |
download | cygnal-2380dfe14ca24fcc7ddb63feb8f7e4958c1a76ea.tar.gz cygnal-2380dfe14ca24fcc7ddb63feb8f7e4958c1a76ea.tar.bz2 cygnal-2380dfe14ca24fcc7ddb63feb8f7e4958c1a76ea.zip |
* pinfo.h (_pinfo::set_exit_state): Declare new function.
(pinfo::exit): Move here from _pinfo::exit.
* sigproc.cc (child_info::sync): Use new function to set exitcode and
process_state.
* pinfo.cc (_pinfo::exit): Ditto.
(proc_waiter): Ditto.
(_pinfo::set_exit_state): Define new function.
(_pinfo::dup_proc_pipe): Close handle when there is no parent process around to
care about the exit value.
* dcrt0.cc (dll_crt0_0): Move subproc_ready synchronization later to make sure
that myself is still mapped in parent.
(do_exit): Reflect movement to pinfo::exit.
(__api_fatal): Ditto.
* exceptions.cc (signal_exit): Ditto.
* errno.cc (errmap): Map PROC_NOT_FOUND.
* init.cc (dll_entry): Release myself before exiting.
* sigproc.cc (proc_can_be_signalled): Set errno appropriately.
(sig_send): Ditto. Also remove ill-advised test for !myself->sendsig since
this is an indication of a process which is still initializating -- it is not
an error.
(child_info::sync): Don't set exitcode here. Assume that will happen in
proc_waiter, if necessary.
* spawn.cc (spawn_guts): Delay "wait_for_myself" logic until later. Don't wait
at all if the process has already exited. Reflect movement to pinfo::exit.
Diffstat (limited to 'winsup/cygwin/spawn.cc')
-rw-r--r-- | winsup/cygwin/spawn.cc | 82 |
1 files changed, 43 insertions, 39 deletions
diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index e18b3e20a..d41c58673 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -645,7 +645,7 @@ spawn_guts (const char * prog_arg, const char *const *argv, after CreateProcess and before copying the datastructures to the child. So we have to start the child in suspend state, unfortunately, to avoid a race condition. */ - if (wincap.start_proc_suspended() || mode != _P_OVERLAY + if (wincap.start_proc_suspended () || mode != _P_OVERLAY || cygheap->fdtab.need_fixup_before ()) flags |= CREATE_SUSPENDED; @@ -787,7 +787,7 @@ spawn_guts (const char * prog_arg, const char *const *argv, /* Name the handle similarly to proc_subproc. */ ProtectHandle1 (pi.hProcess, childhProc); - bool wait_for_myself = false; + bool synced; if (mode == _P_OVERLAY) { myself->dwProcessId = dwExeced = pi.dwProcessId; @@ -807,12 +807,7 @@ spawn_guts (const char * prog_arg, const char *const *argv, on this fact when we exit. dup_proc_pipe also closes our end of the pipe. Note that wr_proc_pipe may also be == INVALID_HANDLE_VALUE. That will make dup_proc_pipe essentially a no-op. */ - if (!myself->wr_proc_pipe) - { - myself.remember (false); - wait_for_myself = true; - } - else + if (myself->wr_proc_pipe) { /* Make sure that we own wr_proc_pipe just in case we've been previously execed. */ @@ -855,42 +850,51 @@ spawn_guts (const char * prog_arg, const char *const *argv, } } -/* Start the child running */ -if (flags & CREATE_SUSPENDED) - ResumeThread (pi.hThread); -ForceCloseHandle (pi.hThread); + /* Start the child running */ + if (flags & CREATE_SUSPENDED) + ResumeThread (pi.hThread); + ForceCloseHandle (pi.hThread); -sigproc_printf ("spawned windows pid %d", pi.dwProcessId); + sigproc_printf ("spawned windows pid %d", pi.dwProcessId); -ciresrv.sync (myself, INFINITE); + synced = ciresrv.sync (myself, INFINITE); -switch (mode) - { - case _P_OVERLAY: - if (wait_for_myself) - waitpid (myself->pid, &res, 0); - myself->exit (res, 1); - break; - case _P_WAIT: - case _P_SYSTEM: - if (waitpid (cygpid, (int *) &res, 0) != cygpid) - res = -1; - break; - case _P_DETACH: - res = 0; /* Lost all memory of this child. */ - break; - case _P_NOWAIT: - case _P_NOWAITO: - case _P_VFORK: - res = cygpid; - break; - default: - break; - } + switch (mode) + { + case _P_OVERLAY: + if (!synced) + /* let myself.exit handle this */; + else if (myself->wr_proc_pipe) + myself.hProcess = NULL; + else + { + extern bool is_toplevel_proc; + is_toplevel_proc = true; + myself.remember (false); + waitpid (myself->pid, &res, 0); + } + myself.exit (EXITCODE_EXEC); + break; + case _P_WAIT: + case _P_SYSTEM: + if (waitpid (cygpid, &res, 0) != cygpid) + res = -1; + break; + case _P_DETACH: + res = 0; /* Lost all memory of this child. */ + break; + case _P_NOWAIT: + case _P_NOWAITO: + case _P_VFORK: + res = cygpid; + break; + default: + break; + } out: -pthread_cleanup_pop (1); -return (int) res; + pthread_cleanup_pop (1); + return (int) res; } extern "C" int |