From 3cb9da14617c58c2821c80d48f0bd80a2deb5fdf Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Tue, 30 Apr 2013 23:51:08 +0000 Subject: [PATCH] * 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. --- winsup/cygwin/ChangeLog | 13 ++++++++++ winsup/cygwin/spawn.cc | 55 ++++++++++++++++++++++------------------- 2 files changed, 42 insertions(+), 26 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 60e0a301f..8a0b399ba 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,16 @@ +2013-04-30 Christopher Faylor + + * 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 * exceptions.cc (cygwin_exception::dumpstack): Guard against wild diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index 1225a3765..5a748a42e 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -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; }