aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2004-11-20 18:35:11 +0000
committerChristopher Faylor <me@cgf.cx>2004-11-20 18:35:11 +0000
commit6a6490181f4c85343fdda54d63689b5d47ba5a39 (patch)
treee795cddf0f7fe88cdded122786b36dc78c0b111a
parent83796ee6b789035d1f9128236699cfbf41dabf37 (diff)
downloadnewlib-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.
-rw-r--r--winsup/cygwin/ChangeLog15
-rw-r--r--winsup/cygwin/exceptions.cc27
-rw-r--r--winsup/cygwin/fork.cc2
-rw-r--r--winsup/cygwin/pinfo.cc41
-rw-r--r--winsup/cygwin/pinfo.h5
-rw-r--r--winsup/cygwin/sigproc.h3
-rw-r--r--winsup/cygwin/spawn.cc30
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)
{