aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2005-09-20 02:06:57 +0000
committerChristopher Faylor <me@cgf.cx>2005-09-20 02:06:57 +0000
commitc529909f45fe73394d2846f6b886218449a4b2a0 (patch)
tree6384cc4fbe4fea54c45f99b57ec6dc794ac382a1
parentcddfc170fd5e28012ea231e62062cb5dcf31b782 (diff)
downloadnewlib-c529909f45fe73394d2846f6b886218449a4b2a0.zip
newlib-c529909f45fe73394d2846f6b886218449a4b2a0.tar.gz
newlib-c529909f45fe73394d2846f6b886218449a4b2a0.tar.bz2
* dcrt0.cc (do_exit): Only call sigproc_terminate from one location --
pinfo::exit. * pinfo.cc (pinfo::exit): Move sigproc_terminate later so that signals can be processed while waiting for hExeced child. (pinfo::maybe_set_exit_code_from_windows): Set exit code from sigExeced if it is non-zero. Set exit_state to ES_EXEC_EXIT prior to waiting for captive process exit code. * exceptions.cc (sigExeced): New global variable. (signal_exit): Remove noreturn attribute from declaration. (signal_exit): Just terminate captive process and return if hExeced on the theory that the exit will be subsequently handled in the main thread. * sigproc.cc (sigproc_terminate): Eliminate test for ES_SIGPROCTERMINATE and use ES_FINAL instead. (sig_send): Use no_signals_available instead of duplicate test. * winsup.h (ES_EXEC_EXIT): New enum. (ES_SIGPROCTERMINATE): Delete.
-rw-r--r--winsup/cygwin/ChangeLog20
-rw-r--r--winsup/cygwin/dcrt0.cc3
-rw-r--r--winsup/cygwin/exceptions.cc20
-rw-r--r--winsup/cygwin/pinfo.cc15
-rw-r--r--winsup/cygwin/sigproc.cc6
-rw-r--r--winsup/cygwin/winsup.h2
6 files changed, 45 insertions, 21 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 0f359da..f76e8ff 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,25 @@
2005-09-19 Christopher Faylor <cgf@timesys.com>
+ * dcrt0.cc (do_exit): Only call sigproc_terminate from one location --
+ pinfo::exit.
+ * pinfo.cc (pinfo::exit): Move sigproc_terminate later so that signals
+ can be processed while waiting for hExeced child.
+ (pinfo::maybe_set_exit_code_from_windows): Set exit code from sigExeced
+ if it is non-zero. Set exit_state to ES_EXEC_EXIT prior to waiting for
+ captive process exit code.
+ * exceptions.cc (sigExeced): New global variable.
+ (signal_exit): Remove noreturn attribute from declaration.
+ (signal_exit): Just terminate captive process and return if hExeced on
+ the theory that the exit will be subsequently handled in the main
+ thread.
+ * sigproc.cc (sigproc_terminate): Eliminate test for
+ ES_SIGPROCTERMINATE and use ES_FINAL instead.
+ (sig_send): Use no_signals_available instead of duplicate test.
+ * winsup.h (ES_EXEC_EXIT): New enum.
+ (ES_SIGPROCTERMINATE): Delete.
+
+2005-09-19 Christopher Faylor <cgf@timesys.com>
+
* sigproc.cc (talktome): Take siginfo_t argument. Don't scan all pids
trying to find one that's talking to me. Just use the pid from
siginfo_t.
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index f293901..39dd08c 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -1091,9 +1091,6 @@ do_exit (int status)
}
- if (exit_state < ES_SIGPROCTERMINATE)
- sigproc_terminate (ES_SIGPROCTERMINATE); // sets exit_state directly
-
if (exit_state < ES_TITLE)
{
exit_state = ES_TITLE;
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index 0f61409..efd49ce 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -36,10 +36,11 @@ static int handle_exceptions (EXCEPTION_RECORD *, void *, CONTEXT *, void *);
extern void sigdelayed ();
};
-extern DWORD dwExeced;
+extern NO_COPY DWORD dwExeced;
+int NO_COPY sigExeced;
static BOOL WINAPI ctrl_c_handler (DWORD);
-static void signal_exit (int) __attribute__ ((noreturn));
+static void signal_exit (int);
char windows_system_directory[1024];
static size_t windows_system_directory_length;
@@ -1160,7 +1161,7 @@ exit_sig:
}
sigproc_printf ("signal %d, about to call do_exit", si.si_signo);
signal_exit (si.si_signo);
- /* Never returns */
+ /* May not return */
}
CRITICAL_SECTION NO_COPY exit_lock;
@@ -1171,6 +1172,13 @@ CRITICAL_SECTION NO_COPY exit_lock;
static void
signal_exit (int rc)
{
+ if (hExeced)
+ {
+ sigproc_printf ("terminating captive process");
+ TerminateProcess (hExeced, sigExeced = rc);
+ return;
+ }
+
EnterCriticalSection (&exit_lock);
if (exit_already++)
myself.exit (rc);
@@ -1184,12 +1192,6 @@ signal_exit (int rc)
user_data->resourcelocks->Delete ();
user_data->resourcelocks->Init ();
- if (hExeced)
- {
- sigproc_printf ("terminating captive process");
- TerminateProcess (hExeced, rc);
- }
-
sigproc_printf ("about to call do_exit (%x)", rc);
SetEvent (signal_arrived);
do_exit (rc);
diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc
index 5d0b890..f28d715 100644
--- a/winsup/cygwin/pinfo.cc
+++ b/winsup/cygwin/pinfo.cc
@@ -111,13 +111,15 @@ pinfo::maybe_set_exit_code_from_windows ()
{
DWORD x = 0xdeadbeef;
DWORD oexitcode = self->exitcode;
+ extern int sigExeced;
+
if (hProcess && !(self->exitcode & EXITCODE_SET))
{
WaitForSingleObject (hProcess, INFINITE); // just to be safe, in case
// process hasn't quite exited
// after closing pipe
GetExitCodeProcess (hProcess, &x);
- self->exitcode = EXITCODE_SET | (x & 0xff) << 8;
+ self->exitcode = EXITCODE_SET | (sigExeced ?: (x & 0xff) << 8);
}
sigproc_printf ("pid %d, exit value - old %p, windows %p, cygwin %p",
self->pid, oexitcode, x, self->exitcode);
@@ -136,11 +138,16 @@ pinfo::zap_cwd ()
void
pinfo::exit (DWORD n)
{
- sigproc_terminate (ES_FINAL);
-
cygthread::terminate ();
if (n != EXITCODE_NOSET)
self->exitcode = EXITCODE_SET | n;/* We're really exiting. Record the UNIX exit code. */
+ else
+ {
+ exit_state = ES_EXEC_EXIT;
+ maybe_set_exit_code_from_windows ();
+ }
+
+ sigproc_terminate (ES_FINAL);
/* FIXME: There is a potential race between an execed process and its
parent here. I hated to add a mutex just for this, though. */
@@ -148,8 +155,6 @@ pinfo::exit (DWORD n)
fill_rusage (&r, hMainProc);
add_rusage (&self->rusage_self, &r);
- maybe_set_exit_code_from_windows ();
-
if (n != EXITCODE_NOSET)
{
zap_cwd ();
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index 59f7996..b9c66f3 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -492,7 +492,7 @@ sigproc_terminate (exit_states es)
{
exit_states prior_exit_state = exit_state;
exit_state = es;
- if (prior_exit_state > ES_SIGPROCTERMINATE)
+ if (prior_exit_state >= ES_FINAL)
sigproc_printf ("already performed");
else
{
@@ -541,7 +541,7 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
}
else
{
- if (!my_sendsig || (si.si_signo != __SIGEXIT && myself->exitcode & EXITCODE_SET) || &_my_tls == _sig_tls)
+ if (no_signals_available (si.si_signo != __SIGEXIT))
{
sigproc_printf ("my_sendsig %p, myself->sendsig %p, exit_state %d",
my_sendsig, myself->sendsig, exit_state);
@@ -638,7 +638,7 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls)
}
else
{
- if (no_signals_available (si.si_signo != __SIGEXIT))
+ if (no_signals_available (true))
sigproc_printf ("I'm going away now");
else if (!p->exec_sendsig)
system_printf ("error sending signal %d to pid %d, pipe handle %p, %E",
diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h
index 960c6c4..d31dd9a 100644
--- a/winsup/cygwin/winsup.h
+++ b/winsup/cygwin/winsup.h
@@ -195,7 +195,7 @@ enum exit_states
ES_CLOSEALL,
ES_HUP_PGRP,
ES_HUP_SID,
- ES_SIGPROCTERMINATE,
+ ES_EXEC_EXIT,
ES_TITLE,
ES_TTY_TERMINATE,
ES_FINAL