4
0
mirror of git://sourceware.org/git/newlib-cygwin.git synced 2025-02-21 00:07:36 +08:00

* 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.
This commit is contained in:
Christopher Faylor 2003-09-20 19:51:48 +00:00
parent 5ab307ccfd
commit 0199487e6a
2 changed files with 37 additions and 13 deletions

View 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.

View 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;
}