From 2380dfe14ca24fcc7ddb63feb8f7e4958c1a76ea Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Tue, 11 Jan 2005 15:31:04 +0000 Subject: * 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. --- winsup/cygwin/spawn.cc | 82 ++++++++++++++++++++++++++------------------------ 1 file changed, 43 insertions(+), 39 deletions(-) (limited to 'winsup/cygwin/spawn.cc') 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 -- cgit v1.2.3