]> sourceware.org Git - newlib-cygwin.git/commitdiff
* spawn.cc (pthread_cleanup): New struct.
authorChristopher Faylor <me@cgf.cx>
Sat, 20 Sep 2003 19:51:48 +0000 (19:51 +0000)
committerChristopher Faylor <me@cgf.cx>
Sat, 20 Sep 2003 19:51:48 +0000 (19:51 +0000)
(do_cleanup): New function.
(spawn_guts): Initialize struct for pthread_cleanup handling to ensure proper
restoration of signals if/when thread is cancelled.  Restore settings using
pthread_cancel_pop.

winsup/cygwin/ChangeLog
winsup/cygwin/spawn.cc

index 31480aac76d72a20b2b4b5964f4c6cd53b94b623..2f142c5fe0f54bb913a2105f49e3ae7e1a8ac357 100644 (file)
@@ -1,3 +1,11 @@
+2003-09-20  Christopher Faylor  <cgf@redhat.com>
+
+       * spawn.cc (pthread_cleanup): New struct.
+       (do_cleanup): New function.
+       (spawn_guts): Initialize struct for pthread_cleanup handling to ensure
+       proper restoration of signals if/when thread is cancelled.  Restore
+       settings using pthread_cancel_pop.
+
 2003-09-19  Christopher Faylor  <cgf@redhat.com>
 
        * include/cygwin/version.h: Bump DLL minor number to 6.
index c6500ff1552c04a6c6a024659605ae99a3f8eac5..cc7eae858dc9d2fccfc8f18fb03e6e65c4e8ecbd 100644 (file)
@@ -323,6 +323,28 @@ av::unshift (const char *what, int conv)
   return 1;
 }
 
+struct pthread_cleanup
+{
+  _sig_func_ptr oldint;
+  _sig_func_ptr oldquit;
+  sigset_t oldmask;
+  pthread_cleanup (): oldint (NULL), oldquit (NULL), oldmask (0) {}
+};
+
+static void
+do_cleanup (void *args)
+{
+# define cleanup ((pthread_cleanup *) args)
+  if (cleanup->oldint)
+    signal (SIGINT, cleanup->oldint);
+  if (cleanup->oldquit)
+    signal (SIGQUIT, cleanup->oldquit);
+  if (cleanup->oldmask)
+    sigprocmask (SIG_SETMASK, &(cleanup->oldmask), NULL);
+# undef cleanup
+}
+
+
 static int __stdcall
 spawn_guts (const char * prog_arg, const char *const *argv,
            const char *const envp[], int mode)
@@ -689,17 +711,17 @@ spawn_guts (const char * prog_arg, const char *const *argv,
 
   /* FIXME: There is a small race here */
 
-  sigset_t old_mask;
-  _sig_func_ptr oldint = (_sig_func_ptr) NULL;
-  _sig_func_ptr oldquit = (_sig_func_ptr) NULL;
+  DWORD res;
+  pthread_cleanup cleanup;
+  pthread_cleanup_push (do_cleanup, (void *) &cleanup);
   if (mode == _P_SYSTEM)
     {
       sigset_t child_block;
-      oldint = signal (SIGINT, SIG_IGN);
-      oldquit = signal (SIGQUIT, SIG_IGN);
+      cleanup.oldint = signal (SIGINT, SIG_IGN);
+      cleanup.oldquit = signal (SIGQUIT, SIG_IGN);
       sigemptyset (&child_block);
       sigaddset (&child_block, SIGCHLD);
-      (void) sigprocmask (SIG_BLOCK, &child_block, &old_mask);
+      (void) sigprocmask (SIG_BLOCK, &child_block, &cleanup.oldmask);
     }
 
   /* Restore impersonation. In case of _P_OVERLAY this isn't
@@ -792,7 +814,6 @@ spawn_guts (const char * prog_arg, const char *const *argv,
 
   sigproc_printf ("spawned windows pid %d", pi.dwProcessId);
 
-  DWORD res;
   BOOL exited;
 
   res = 0;
@@ -885,12 +906,6 @@ spawn_guts (const char * prog_arg, const char *const *argv,
     case _P_WAIT:
     case _P_SYSTEM:
       waitpid (cygpid, (int *) &res, 0);
-      if (mode == _P_SYSTEM)
-       {
-         signal (SIGINT, oldint);
-         signal (SIGQUIT, oldquit);
-         sigprocmask (SIG_SETMASK, &old_mask, NULL);
-       }
       break;
     case _P_DETACH:
       res = 0; /* Lose all memory of this child. */
@@ -904,6 +919,7 @@ spawn_guts (const char * prog_arg, const char *const *argv,
       break;
     }
 
+  pthread_cleanup_pop (1);
   return (int) res;
 }
 
This page took 0.03808 seconds and 5 git commands to generate.