summaryrefslogtreecommitdiffstats
path: root/main.cxx
diff options
context:
space:
mode:
authorJosh Stone <jistone@redhat.com>2009-04-01 14:49:12 -0700
committerJosh Stone <jistone@redhat.com>2009-04-01 15:39:04 -0700
commit4cc40e829870dd6a1d9714706d38f5fd4b2ec982 (patch)
tree9c9607d35b5b4c9578b057627d4542836b67875c /main.cxx
parent0dbfd2a9ccad1759c58f240843cabc50d502e44a (diff)
downloadsystemtap-steved-4cc40e829870dd6a1d9714706d38f5fd4b2ec982.tar.gz
systemtap-steved-4cc40e829870dd6a1d9714706d38f5fd4b2ec982.tar.xz
systemtap-steved-4cc40e829870dd6a1d9714706d38f5fd4b2ec982.zip
PR10016: Purge stap of all pgrp and system() usage
We hereby no longer try to manipulate process groups in any way. We don't set a private process group, and we never kill() our entire group either. Instead of using system(), we now have a stap_system() which saves the child PID, so when we get a terminating signal we can pass it along to the child. Signals sent through the TTY have always worked, since the TTY sends it to the entire pgrp. However, if we're running as part of a wrapper script or GUI, which may not have a separate process group for stap, we still would like to allow "kill -TERM $STAPPID" to terminate stap nicely. There's still a short window of failure in the time that staprun is active, because we can't kill a setuid process from a user process. Once staprun drops privileges and execs to stapio though, everything should work fine.
Diffstat (limited to 'main.cxx')
-rw-r--r--main.cxx77
1 files changed, 4 insertions, 73 deletions
diff --git a/main.cxx b/main.cxx
index 3b88a1c8..794a5891 100644
--- a/main.cxx
+++ b/main.cxx
@@ -36,8 +36,6 @@ extern "C" {
#include <sys/times.h>
#include <sys/time.h>
#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/wait.h>
#include <time.h>
#include <elfutils/libdwfl.h>
#include <getopt.h>
@@ -293,14 +291,9 @@ int pending_interrupts;
extern "C"
void handle_interrupt (int sig)
{
- if (pending_interrupts == 0)
- kill (0, sig); // Forward signals to child processes if any.
-
+ kill_stap_spawn(sig);
pending_interrupts ++;
- // NB: the "2" below is intended to skip the effect of the self-induced
- // deferred signal coming from the kill() above.
-
- if (pending_interrupts > 2) // XXX: should be configurable? time-based?
+ if (pending_interrupts > 1) // XXX: should be configurable? time-based?
{
char msg[] = "Too many interrupts received, exiting.\n";
int rc = write (2, msg, sizeof(msg)-1);
@@ -324,7 +317,7 @@ setup_signals (sighandler_t handler)
sigaddset (&sa.sa_mask, SIGINT);
sigaddset (&sa.sa_mask, SIGTERM);
}
- sa.sa_flags = 0;
+ sa.sa_flags = SA_RESTART;
sigaction (SIGHUP, &sa, NULL);
sigaction (SIGPIPE, &sa, NULL);
@@ -332,62 +325,10 @@ setup_signals (sighandler_t handler)
sigaction (SIGTERM, &sa, NULL);
}
-pid_t runner_pid;
-int runner (int, char * const []);
-
-// Passes on signals to runner process.
-// In practise passes signal to runner process process group,
-// since run_pass() uses system() to spawn child processes,
-// which makes the process ignore SIGINT during the command run.
-extern "C"
-void waiter_handler (int sig)
-{
- // Process group is negative process id.
- kill (-1 * runner_pid, sig);
-}
-
-// Just sits there till the runner exits and then exits the same way.
-void waiter()
-{
- int status;
- setup_signals (&waiter_handler);
- while (waitpid (runner_pid, &status, 0) != runner_pid);
-
- // Exit as our runner child exitted.
- if (WIFEXITED(status))
- exit (WEXITSTATUS(status));
-
- // Or simulate as if we were killed by the same signal.
- if (WIFSIGNALED(status))
- {
- int sig = WTERMSIG(status);
- signal (sig, SIG_DFL);
- raise (sig);
- }
-
- // Should not happen, exit as if error.
- exit(-1);
-}
int
main (int argc, char * const argv [])
{
- // Fork to make sure runner gets its own process group, while
- // the waiter sits in the original process group of the shell
- // and forwards any signals.
- runner_pid = fork ();
- if (runner_pid == 0)
- return runner (argc, argv);
- if (runner_pid > 0)
- waiter ();
-
- perror ("couldn't fork");
- exit (-1);
-}
-
-int
-runner (int argc, char * const argv [])
-{
string cmdline_script; // -e PROGRAM
string script_file; // FILE
bool have_script = false;
@@ -899,16 +840,6 @@ runner (int argc, char * const argv [])
// directory.
s.translated_source = string(s.tmpdir) + "/" + s.module_name + ".c";
- // We want a new process group so we can use kill (0, sig) to send a
- // signal to all children (but not the parent). As done in
- // handle_interrupt ().
- if (setpgrp() != 0)
- {
- const char* e = strerror (errno);
- if (! s.suppress_warnings)
- cerr << "Warning: failed to set new process group: " << e << endl;
- }
-
// Set up our handler to catch routine signals, to allow clean
// and reasonably timely exit.
setup_signals(&handle_interrupt);
@@ -1251,7 +1182,7 @@ pass_5:
string cleanupcmd = "rm -rf ";
cleanupcmd += s.tmpdir;
if (s.verbose>1) clog << "Running " << cleanupcmd << endl;
- int status = system (cleanupcmd.c_str());
+ int status = stap_system (cleanupcmd.c_str());
if (status != 0 && s.verbose>1)
clog << "Cleanup command failed, status: " << status << endl;
}