* 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.
This commit is contained in:
Christopher Faylor
2005-01-11 15:31:04 +00:00
parent aa67a4484e
commit 2380dfe14c
10 changed files with 149 additions and 100 deletions

View File

@ -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