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/pinfo.cc | |
parent | aa67a4484ee30a61d1d12da8209308ab691f6bba (diff) | |
download | newlib-2380dfe14ca24fcc7ddb63feb8f7e4958c1a76ea.zip newlib-2380dfe14ca24fcc7ddb63feb8f7e4958c1a76ea.tar.gz newlib-2380dfe14ca24fcc7ddb63feb8f7e4958c1a76ea.tar.bz2 |
* 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/pinfo.cc')
-rw-r--r-- | winsup/cygwin/pinfo.cc | 80 |
1 files changed, 46 insertions, 34 deletions
diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index 8b184a6..6d55dc4 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -39,6 +39,8 @@ static char NO_COPY pinfo_dummy[sizeof (_pinfo)] = {0}; pinfo NO_COPY myself ((_pinfo *)&pinfo_dummy); // Avoid myself != NULL checks +bool is_toplevel_proc; + /* Initialize the process table. This is done once when the dll is first loaded. */ @@ -101,40 +103,55 @@ pinfo_init (char **envp, int envc) debug_printf ("pid %d, pgid %d", myself->pid, myself->pgid); } +# define self (*this) void -_pinfo::exit (UINT n, bool norecord) +pinfo::set_exit_state (DWORD pidstate) +{ + DWORD x = 0xdeadbeef; + DWORD oexitcode = self->exitcode; + if (hProcess && self->exitcode == EXITCODE_UNSET) + { + GetExitCodeProcess (hProcess, &x); + self->exitcode = (x & 0xff) << 8; + } + sigproc_printf ("exit value - old %p, windows %p, cygwin %p", oexitcode, x, + self->exitcode); + if (self->exitcode != EXITCODE_NOSET) + self->process_state = pidstate; +} + +void +pinfo::exit (DWORD n) { exit_state = ES_FINAL; cygthread::terminate (); - if (norecord) - sigproc_terminate (); /* Just terminate signal and process stuff */ - else - exitcode = n; /* We're really exiting. Record the UNIX exit code. */ - - if (this) + if (n != EXITCODE_EXEC) { - /* FIXME: There is a potential race between an execed process and its - parent here. I hated to add a mutex just for this, though. */ - struct rusage r; - fill_rusage (&r, hMainProc); - add_rusage (&rusage_self, &r); - - if (!norecord) - { - process_state = PID_EXITED; - /* Ensure that the parent knows that this logical process has - terminated. */ - myself->alert_parent (0); - - } + sigproc_terminate (); /* Just terminate signal and process stuff */ + self->exitcode = n; /* We're really exiting. Record the UNIX exit code. */ } - - sigproc_printf ("Calling ExitProcess norecord %d, n %p, exitcode %p", - norecord, n, exitcode); + sigproc_printf ("1 hProcess %p, n %p, exitcode %p", hProcess, n, self->exitcode); + + /* FIXME: There is a potential race between an execed process and its + parent here. I hated to add a mutex just for this, though. */ + struct rusage r; + fill_rusage (&r, hMainProc); + add_rusage (&self->rusage_self, &r); + + set_exit_state (PID_EXITED); + sigproc_printf ("2 hProcess %p, n %p, exitcode %p, EXITCODE_EXEC %p", hProcess, n, self->exitcode, EXITCODE_EXEC); + if (n != EXITCODE_EXEC) +{sigproc_printf ("3 hProcess %p, n %p, exitcode %p, EXITCODE_EXE %pC", hProcess, n, self->exitcode, EXITCODE_EXEC); + myself->alert_parent (0); +} + _my_tls.stacklock = 0; _my_tls.stackptr = _my_tls.stack; - ExitProcess (exitcode); + sigproc_printf ("Calling ExitProcess hProcess %p, n %p, exitcode %p", + hProcess, n, self->exitcode); + ExitProcess (self->exitcode); } +# undef self void pinfo::init (pid_t n, DWORD flag, HANDLE in_h) @@ -664,7 +681,6 @@ _pinfo::cmdline (size_t& n) static DWORD WINAPI proc_waiter (void *arg) { - extern HANDLE hExeced; pinfo& vchild = *(pinfo *) arg; siginfo_t si; @@ -685,6 +701,8 @@ proc_waiter (void *arg) { DWORD nb; char buf = '\0'; + extern HANDLE hExeced; + if (!ReadFile (vchild.rd_proc_pipe, &buf, 1, &nb, NULL) && GetLastError () != ERROR_BROKEN_PIPE) { @@ -702,12 +720,7 @@ proc_waiter (void *arg) /* Child exited. Do some cleanup and signal myself. */ CloseHandle (vchild.rd_proc_pipe); vchild.rd_proc_pipe = NULL; - if (vchild->exitcode == EXITCODE_UNSET) - { - DWORD x; - GetExitCodeProcess (vchild.hProcess, &x); - vchild->exitcode = (x & 0xff) << 8; - } + vchild.set_exit_state (PID_ZOMBIE); if (WIFEXITED (vchild->exitcode)) si.si_sigval.sival_int = CLD_EXITED; else if (WCOREDUMP (vchild->exitcode)) @@ -715,7 +728,6 @@ proc_waiter (void *arg) else si.si_sigval.sival_int = CLD_KILLED; si.si_status = vchild->exitcode; - vchild->process_state = PID_ZOMBIE; break; case SIGTTIN: case SIGTTOU: @@ -769,7 +781,7 @@ _pinfo::dup_proc_pipe (HANDLE hProcess) /* Grr. Can't set DUPLICATE_CLOSE_SOURCE for exec case because we could be execing a non-cygwin process and we need to set the exit value before the parent sees it. */ - if (this != myself) + if (this != myself || is_toplevel_proc) flags |= DUPLICATE_CLOSE_SOURCE; bool res = DuplicateHandle (hMainProc, wr_proc_pipe, hProcess, &wr_proc_pipe, 0, FALSE, flags); |