summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/spawn.cc
diff options
context:
space:
mode:
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;
}