OSDN Git Service

* dcrt0.cc (do_exit): Only call sigproc_terminate from one location --
authorcgf <cgf>
Tue, 20 Sep 2005 02:06:54 +0000 (02:06 +0000)
committercgf <cgf>
Tue, 20 Sep 2005 02:06:54 +0000 (02:06 +0000)
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.

winsup/cygwin/ChangeLog
winsup/cygwin/dcrt0.cc
winsup/cygwin/exceptions.cc
winsup/cygwin/pinfo.cc
winsup/cygwin/sigproc.cc
winsup/cygwin/winsup.h

index 0f359da..f76e8ff 100644 (file)
@@ -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.
index f293901..39dd08c 100644 (file)
@@ -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;
index 0f61409..efd49ce 100644 (file)
@@ -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);
index 5d0b890..f28d715 100644 (file)
@@ -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 ();
index 59f7996..b9c66f3 100644 (file)
@@ -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",
index 960c6c4..d31dd9a 100644 (file)
@@ -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