Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2003-09-20 23:51:48 +0400
committerChristopher Faylor <me@cgf.cx>2003-09-20 23:51:48 +0400
commit0199487e6a7933f9a6757c77a409c6a8b271d1d3 (patch)
treef2f1fd22d15529c2d1b6796e5cfb709d5e5c7a14 /winsup
parent5ab307ccfd4dfb970e3b6a7c4710e0f3f5dcb442 (diff)
* 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.
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/ChangeLog8
-rw-r--r--winsup/cygwin/spawn.cc42
2 files changed, 37 insertions, 13 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 31480aac7..2f142c5fe 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -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.
diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc
index c6500ff15..cc7eae858 100644
--- a/winsup/cygwin/spawn.cc
+++ b/winsup/cygwin/spawn.cc
@@ -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;
}