* spawn.cc (system_call_cleanup): Rename from pthread_cleanup. Extend

functionality.
(system_call_cleanup::system_call_cleanup): Set up signals like system()
requires.  Unblock previously-blocked signal handling.
(system_call_cleanup::~system_call_cleanup): Restore signal handling after
system().
(child_info_spawn::worker): Put signals on hold and use system_call_cleanup
class to set and restore signals rather than doing it prior to to running the
program.  Remove the ill-conceived pthread_cleanup stuff.
This commit is contained in:
Christopher Faylor 2013-04-30 23:51:08 +00:00
parent cc5bdf003f
commit 3cb9da1461
2 changed files with 42 additions and 26 deletions

View File

@ -1,3 +1,16 @@
2013-04-30 Christopher Faylor <me.cygwin2013@cgf.cx>
* spawn.cc (system_call_cleanup): Rename from pthread_cleanup. Extend
functionality.
(system_call_cleanup::system_call_cleanup): Set up signals like
system() requires. Unblock previously-blocked signal handling.
(system_call_cleanup::~system_call_cleanup): Restore signal handling
after system().
(child_info_spawn::worker): Put signals on hold and use
system_call_cleanup class to set and restore signals rather than doing
it prior to to running the program. Remove the ill-conceived
pthread_cleanup stuff.
2013-04-30 Christopher Faylor <me.cygwin2013@cgf.cx>
* exceptions.cc (cygwin_exception::dumpstack): Guard against wild

View File

@ -234,26 +234,37 @@ iscmd (const char *argv0, const char *what)
(n == 0 || isdirsep (argv0[n - 1]));
}
struct pthread_cleanup
struct system_call_cleanup
{
_sig_func_ptr oldint;
_sig_func_ptr oldquit;
sigset_t oldmask;
pthread_cleanup (): oldint (NULL), oldquit (NULL), oldmask ((sigset_t) -1) {}
};
static void
do_cleanup (void *args)
{
# define cleanup ((pthread_cleanup *) args)
if (cleanup->oldmask != (sigset_t) -1)
{
signal (SIGINT, cleanup->oldint);
signal (SIGQUIT, cleanup->oldquit);
sigprocmask (SIG_SETMASK, &(cleanup->oldmask), NULL);
}
system_call_cleanup (bool issystem)
{
if (!issystem)
oldint = (_sig_func_ptr) -1;
else
{
sigset_t child_block;
oldint = signal (SIGINT, SIG_IGN);
oldquit = signal (SIGQUIT, SIG_IGN);
sigemptyset (&child_block);
sigaddset (&child_block, SIGCHLD);
sigprocmask (SIG_BLOCK, &child_block, &oldmask);
sig_send (NULL, __SIGNOHOLD);
}
}
~system_call_cleanup ()
{
if (oldmask != (sigset_t) -1)
{
signal (SIGINT, oldint);
signal (SIGQUIT, oldquit);
sigprocmask (SIG_SETMASK, &oldmask, NULL);
}
}
# undef cleanup
}
};
child_info_spawn NO_COPY ch_spawn;
@ -295,17 +306,8 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
}
/* FIXME: There is a small race here and FIXME: not thread safe! */
pthread_cleanup cleanup;
if (mode == _P_SYSTEM)
{
sigset_t child_block;
cleanup.oldint = signal (SIGINT, SIG_IGN);
cleanup.oldquit = signal (SIGQUIT, SIG_IGN);
sigemptyset (&child_block);
sigaddset (&child_block, SIGCHLD);
sigprocmask (SIG_BLOCK, &child_block, &cleanup.oldmask);
}
pthread_cleanup_push (do_cleanup, (void *) &cleanup);
sig_send (NULL, __SIGHOLD);
av newargv;
linebuf one_line;
PWCHAR envblock = NULL;
@ -739,6 +741,8 @@ loop:
goto out;
}
system_call_cleanup (mode == _P_SYSTEM);
/* The CREATE_SUSPENDED case is handled below */
if (iscygwin () && !(c_flags & CREATE_SUSPENDED))
strace.write_childpid (pi.dwProcessId);
@ -880,7 +884,6 @@ out:
this->cleanup ();
if (envblock)
free (envblock);
pthread_cleanup_pop (1);
return (int) res;
}