diff options
author | Christopher Faylor <me@cgf.cx> | 2004-11-20 18:35:11 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2004-11-20 18:35:11 +0000 |
commit | 6a6490181f4c85343fdda54d63689b5d47ba5a39 (patch) | |
tree | e795cddf0f7fe88cdded122786b36dc78c0b111a /winsup/cygwin | |
parent | 83796ee6b789035d1f9128236699cfbf41dabf37 (diff) | |
download | newlib-6a6490181f4c85343fdda54d63689b5d47ba5a39.zip newlib-6a6490181f4c85343fdda54d63689b5d47ba5a39.tar.gz newlib-6a6490181f4c85343fdda54d63689b5d47ba5a39.tar.bz2 |
* pinfo.h (pinfo::alert_parent): New function.
* exceptions.cc (sig_handle_tty_stop): Use alert_parent to send "signals" to
parent.
* fork.cc (fork_parent): Don't close pi.hProcess. Let the waiter thread do
that.
* pinfo.cc (proc_waiter): Detect case where process exits without setting the
exit code and use value from GetExitCodeProcess. Reluctantly implement
__SIGREPARENT.
(pinfo::alert_parent): Define.
* sigproc.h (__SIGREPARENT): New enum.
* spawn.cc (spawn_guts): Send reparent signal to parent on exec. Always create
process in suspended state to avoid races.
Diffstat (limited to 'winsup/cygwin')
-rw-r--r-- | winsup/cygwin/ChangeLog | 15 | ||||
-rw-r--r-- | winsup/cygwin/exceptions.cc | 27 | ||||
-rw-r--r-- | winsup/cygwin/fork.cc | 2 | ||||
-rw-r--r-- | winsup/cygwin/pinfo.cc | 41 | ||||
-rw-r--r-- | winsup/cygwin/pinfo.h | 5 | ||||
-rw-r--r-- | winsup/cygwin/sigproc.h | 3 | ||||
-rw-r--r-- | winsup/cygwin/spawn.cc | 30 |
7 files changed, 78 insertions, 45 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 84680aa..02010f1 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,5 +1,20 @@ 2004-11-20 Christopher Faylor <cgf@timesys.com> + * pinfo.h (pinfo::alert_parent): New function. + * exceptions.cc (sig_handle_tty_stop): Use alert_parent to send + "signals" to parent. + * fork.cc (fork_parent): Don't close pi.hProcess. Let the waiter + thread do that. + * pinfo.cc (proc_waiter): Detect case where process exits without + setting the exit code and use value from GetExitCodeProcess. + Reluctantly implement __SIGREPARENT. + (pinfo::alert_parent): Define. + * sigproc.h (__SIGREPARENT): New enum. + * spawn.cc (spawn_guts): Send reparent signal to parent on exec. + Always create process in suspended state to avoid races. + +2004-11-20 Christopher Faylor <cgf@timesys.com> + Remove cygthread.h in favor of cygtls.h throughout since cygtls now includes cygthread.h. Eliminate ppid_handle usage throughout. * child_info.h: Regenerate magic number diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 8fdecba..bc28cc8 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -600,21 +600,7 @@ sig_handle_tty_stop (int sig) } myself->stopsig = sig; - char pipesig; - DWORD nb; - /* See if we have a living parent. If so, send it a special signal. - It will figure out exactly which pid has stopped by scanning - its list of subprocesses. */ - if (my_parent_is_alive ()) - { - pinfo parent (myself->ppid); - if (NOTSTATE (parent, PID_NOCLDSTOP)) - { - pipesig = sig; - if (!WriteFile (myself->wr_proc_pipe, &pipesig, 1, &nb, NULL)) - debug_printf ("sending stop notification to parent failed, %E"); - } - } + myself.alert_parent (sig); sigproc_printf ("process %d stopped by signal %d", myself->pid, sig); HANDLE w4[2]; w4[0] = sigCONT; @@ -624,16 +610,7 @@ sig_handle_tty_stop (int sig) case WAIT_OBJECT_0: case WAIT_OBJECT_0 + 1: reset_signal_arrived (); - if (my_parent_is_alive ()) - { - pinfo parent (myself->ppid); - if (parent) - { - sig = SIGCONT; - if (!WriteFile (myself->wr_proc_pipe, &sig, 1, &nb, NULL)) - debug_printf ("sending stop notification to parent failed, %E"); - } - } + myself.alert_parent (SIGCONT); break; default: api_fatal ("WaitSingleObject failed, %E"); diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index 8bcf5b0..706b854 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -569,8 +569,6 @@ fork_parent (HANDLE& hParent, dll *&first_dll, (void) resume_child (pi, forker_finished); } - if (pi.hProcess) - ForceCloseHandle1 (pi.hProcess, childhProc); ForceCloseHandle (subproc_ready); ForceCloseHandle (pi.hThread); ForceCloseHandle (forker_finished); diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index c04f09e..6af9cd6 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -698,14 +698,22 @@ proc_waiter (void *arg) switch (buf) { case 0: + CloseHandle (vchild.rd_proc_pipe); + vchild.rd_proc_pipe = NULL; + + if (vchild->process_state != PID_EXITED && vchild.hProcess) + { + DWORD exit_code; + if (GetExitCodeProcess (vchild.hProcess, &exit_code)) + vchild->exitcode = (exit_code & 0xff) << 8; + } + ForceCloseHandle1 (vchild.hProcess, childhProc); if (WIFEXITED (vchild->exitcode)) si.si_sigval.sival_int = CLD_EXITED; else if (WCOREDUMP (vchild->exitcode)) si.si_sigval.sival_int = CLD_DUMPED; else si.si_sigval.sival_int = CLD_KILLED; - CloseHandle (vchild.rd_proc_pipe); - vchild.rd_proc_pipe = NULL; si.si_status = vchild->exitcode; vchild->process_state = PID_ZOMBIE; break; @@ -717,6 +725,16 @@ proc_waiter (void *arg) break; case SIGCONT: continue; + case __SIGREPARENT: /* sigh */ + if (vchild.hProcess) + ForceCloseHandle1 (vchild.hProcess, childhProc); + vchild.hProcess = OpenProcess (PROCESS_QUERY_INFORMATION, FALSE, + vchild->dwProcessId); + vchild->cygstarted++; + if (vchild.hProcess) + ProtectHandle1 (vchild.hProcess, childhProc); + continue; + break; default: system_printf ("unknown value %d on proc pipe", buf); continue; @@ -784,6 +802,25 @@ pinfo::wait () } void +pinfo::alert_parent (int sig) +{ + /* See if we have a living parent. If so, send it a special signal. + It will figure out exactly which pid has stopped by scanning + its list of subprocesses. */ + if (my_parent_is_alive ()) + { + pinfo parent (myself->ppid); + if (NOTSTATE (parent, PID_NOCLDSTOP)) + { + DWORD nb; + unsigned char pipesig = sig; + if (!WriteFile (myself->wr_proc_pipe, &pipesig, 1, &nb, NULL)) + debug_printf ("sending %d notification to parent failed, %E", sig); + } + } +} + +void pinfo::release () { if (h) diff --git a/winsup/cygwin/pinfo.h b/winsup/cygwin/pinfo.h index 2fddc32..a0cf363 100644 --- a/winsup/cygwin/pinfo.h +++ b/winsup/cygwin/pinfo.h @@ -43,7 +43,7 @@ public: /* Handle associated with initial Windows pid which started it all. */ HANDLE pid_handle; - /* True if started by a cygwin process (DWORD for hysterical reasons) */ + /* > 0 if started by a cygwin process */ DWORD cygstarted; /* Parent process id. */ @@ -153,7 +153,8 @@ public: _pinfo *operator * () const {return procinfo;} operator _pinfo * () const {return procinfo;} // operator bool () const {return (int) h;} - void preserve() { destroy = false; } + void preserve () { destroy = false; } + void alert_parent (int); #ifndef _SIGPROC_H int remember () {system_printf ("remember is not here"); return 0;} #else diff --git a/winsup/cygwin/sigproc.h b/winsup/cygwin/sigproc.h index 8a01a67..9c7807a 100644 --- a/winsup/cygwin/sigproc.h +++ b/winsup/cygwin/sigproc.h @@ -22,7 +22,8 @@ enum __SIGDELETE = -(NSIG + 5), __SIGFLUSHFAST = -(NSIG + 6), __SIGHOLD = -(NSIG + 7), - __SIGNOHOLD = -(NSIG + 8) + __SIGNOHOLD = -(NSIG + 8), + __SIGREPARENT = (NSIG + 2) }; #endif diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index 7f2a979..bebbf22 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -618,23 +618,19 @@ spawn_guts (const char * prog_arg, const char *const *argv, flags |= DETACHED_PROCESS; HANDLE saved_sendsig; - if (mode == _P_OVERLAY) + if (mode != _P_OVERLAY) + saved_sendsig = NULL; + else { saved_sendsig = myself->sendsig; myself->sendsig = INVALID_HANDLE_VALUE; } - else - { - flags |= CREATE_SUSPENDED; - saved_sendsig = NULL; - } /* Some file types (currently only sockets) need extra effort in the parent 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 (!myself->wr_proc_pipe || cygheap->fdtab.need_fixup_before ()) - flags |= CREATE_SUSPENDED; + flags |= CREATE_SUSPENDED; const char *runpath = null_app_name ? NULL : (const char *) real_path; @@ -771,14 +767,17 @@ spawn_guts (const char * prog_arg, const char *const *argv, ProtectHandle1 (pi.hProcess, childhProc); int wait_for_myself = false; + DWORD exec_cygstarted; if (mode == _P_OVERLAY) { + exec_cygstarted = myself->cygstarted; + myself->dwProcessId = dwExeced = pi.dwProcessId; + myself.alert_parent (__SIGREPARENT); CloseHandle (saved_sendsig); /* These are both duplicated in the child code. We do this here, primarily for strace. */ strace.execing = 1; hExeced = pi.hProcess; - dwExeced = pi.dwProcessId; strcpy (myself->progname, real_path); close_all_files (); if (!myself->wr_proc_pipe) @@ -790,6 +789,7 @@ spawn_guts (const char * prog_arg, const char *const *argv, } else { + exec_cygstarted = 0; myself->set_has_pgid_children (); ProtectHandle (pi.hThread); pinfo child (cygpid, PID_IN_USE); @@ -825,14 +825,18 @@ spawn_guts (const char * prog_arg, const char *const *argv, if (flags & CREATE_SUSPENDED) ResumeThread (pi.hThread); ForceCloseHandle (pi.hThread); - ForceCloseHandle1 (pi.hProcess, childhProc); sigproc_printf ("spawned windows pid %d", pi.dwProcessId); - if (!wait_for_myself) - res = 0; - else + if (wait_for_myself) waitpid (myself->pid, &res, 0); + else + { + if (exec_cygstarted) + while (myself->cygstarted == exec_cygstarted) + low_priority_sleep (0); + res = 42; + } switch (mode) { |