diff options
author | Dave Brolley <brolley@redhat.com> | 2009-10-13 11:55:11 -0400 |
---|---|---|
committer | Dave Brolley <brolley@redhat.com> | 2009-10-13 11:55:11 -0400 |
commit | f990359bd63bd4fc21e600e71c6a513d5b5b2ccb (patch) | |
tree | 16fb7638f2089476b2994ec7d8b2131e4a7b0b69 /runtime/staprun/mainloop.c | |
parent | 8f6d8c2bd3e5c1d2881e2ebe1c7ad5deb389e581 (diff) | |
parent | ba9abf303e1bed196668f103b2a17c48e3df70aa (diff) | |
download | systemtap-steved-f990359bd63bd4fc21e600e71c6a513d5b5b2ccb.tar.gz systemtap-steved-f990359bd63bd4fc21e600e71c6a513d5b5b2ccb.tar.xz systemtap-steved-f990359bd63bd4fc21e600e71c6a513d5b5b2ccb.zip |
Merge branch 'master' of ssh://sources.redhat.com/git/systemtap
Diffstat (limited to 'runtime/staprun/mainloop.c')
-rw-r--r-- | runtime/staprun/mainloop.c | 61 |
1 files changed, 43 insertions, 18 deletions
diff --git a/runtime/staprun/mainloop.c b/runtime/staprun/mainloop.c index 45b142bc..513a9569 100644 --- a/runtime/staprun/mainloop.c +++ b/runtime/staprun/mainloop.c @@ -60,12 +60,15 @@ static void chld_proc(int signum) } #if WORKAROUND_BZ467568 -/* Used for pause()-based synchronization. */ -static void signal_dontcare(int signum) +/* When a SIGUSR1 signal arrives, set this variable. */ +volatile sig_atomic_t usr1_interrupt = 0; + +static void signal_usr1(int signum) { (void) signum; + usr1_interrupt = 1; } -#endif +#endif /* WORKAROUND_BZ467568 */ static void setup_main_signals(void) { @@ -115,6 +118,10 @@ void start_cmd(void) { pid_t pid; struct sigaction a; +#if WORKAROUND_BZ467568 + struct sigaction usr1_action, old_action; + sigset_t blockmask, oldmask; +#endif /* WORKAROUND_BZ467568 */ /* if we are execing a target cmd, ignore ^C in stapio */ /* and let the target cmd get it. */ @@ -123,6 +130,21 @@ void start_cmd(void) a.sa_handler = SIG_IGN; sigaction(SIGINT, &a, NULL); +#if WORKAROUND_BZ467568 + /* Set up the mask of signals to temporarily block. */ + sigemptyset (&blockmask); + sigaddset (&blockmask, SIGUSR1); + + /* Establish the SIGUSR1 signal handler. */ + sigfillset (&usr1_action.sa_mask); + usr1_action.sa_flags = 0; + usr1_action.sa_handler = signal_usr1; + sigaction (SIGUSR1, &usr1_action, &old_action); + + /* Block SIGUSR1 */ + sigprocmask(SIG_BLOCK, &blockmask, &oldmask); +#endif /* WORKAROUND_BZ467568 */ + if ((pid = fork()) < 0) { _perr("fork"); exit(1); @@ -175,22 +197,21 @@ void start_cmd(void) dbug(1, "blocking briefly\n"); #if WORKAROUND_BZ467568 { - /* We use SIGUSR1 here, since pause() only returns if a - handled signal was received. */ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sigfillset(&sa.sa_mask); - sa.sa_handler = signal_dontcare; - sigaction(SIGUSR1, &sa, NULL); - pause (); - sa.sa_handler = SIG_DFL; - sigaction(SIGUSR1, &sa, NULL); + /* Wait for the SIGUSR1 */ + while (!usr1_interrupt) + sigsuspend(&oldmask); + + /* Restore the old SIGUSR1 signal handler. */ + sigaction (SIGUSR1, &old_action, NULL); + + /* Restore the original signal mask */ + sigprocmask(SIG_SETMASK, &oldmask, NULL); } -#else +#else /* !WORKAROUND_BZ467568 */ rc = ptrace (PTRACE_TRACEME, 0, 0, 0); if (rc < 0) perror ("ptrace me"); raise (SIGCONT); /* Harmless; just passes control to parent. */ -#endif +#endif /* !WORKAROUND_BZ467568 */ dbug(1, "execing target_cmd %s\n", target_cmd); @@ -217,12 +238,16 @@ void start_cmd(void) us to release it. */ target_pid = pid; #if WORKAROUND_BZ467568 - /* Do nothing else here; see stp_main_loop's handling of a received STP_START. */ -#else + /* Restore the old SIGUSR1 signal handler. */ + sigaction (SIGUSR1, &old_action, NULL); + + /* Restore the original signal mask */ + sigprocmask(SIG_SETMASK, &oldmask, NULL); +#else /* !WORKAROUND_BZ467568 */ int status; waitpid (target_pid, &status, 0); dbug(1, "waited for target_cmd %s pid %d status %x\n", target_cmd, target_pid, (unsigned) status); -#endif +#endif /* !WORKAROUND_BZ467568 */ } } |