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:
parent
5ab307ccfd
commit
0199487e6a
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user