summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <cgf@redhat.com>2004-11-20 18:35:08 +0000
committerChristopher Faylor <cgf@redhat.com>2004-11-20 18:35:08 +0000
commit02abf3460335791ef947a3934c80e13a87175145 (patch)
tree9f6d2a7d930c97afe9440512acb8824dff5bd276
parent846b25398f247e7e659e09f12d5c420af08ae1d8 (diff)
downloadgdb-02abf3460335791ef947a3934c80e13a87175145.tar.gz
* 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 84680aa10e1..02010f1a09c 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 8fdecbaa7b0..bc28cc85b45 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 8bcf5b0035a..706b8548fb0 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 c04f09e4a47..6af9cd647ba 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 2fddc32836c..a0cf36383d5 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 8a01a6748f1..9c7807a495b 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 7f2a9798bad..bebbf22ca3f 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)
{