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
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2013-05-01 03:51:08 +0400
committerChristopher Faylor <me@cgf.cx>2013-05-01 03:51:08 +0400
commit3cb9da14617c58c2821c80d48f0bd80a2deb5fdf (patch)
tree33a5c8c366c63360a766696505b74d29a320d3bb /winsup/cygwin/spawn.cc
parentcc5bdf003f650ce5938640c4dd1ffd84259dcc42 (diff)
* 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.
Diffstat (limited to 'winsup/cygwin/spawn.cc')
-rw-r--r--winsup/cygwin/spawn.cc55
1 files changed, 29 insertions, 26 deletions
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;
}