summaryrefslogtreecommitdiffstats
path: root/util.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 /util.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 'util.cxx')
-rw-r--r--util.cxx41
1 files changed, 37 insertions, 4 deletions
diff --git a/util.cxx b/util.cxx
index 68cc27f7..5fa7a5f2 100644
--- a/util.cxx
+++ b/util.cxx
@@ -20,13 +20,15 @@
#include <cerrno>
extern "C" {
-#include <sys/types.h>
-#include <sys/stat.h>
+#include <fcntl.h>
#include <pwd.h>
-#include <unistd.h>
+#include <spawn.h>
#include <stdio.h>
#include <stdlib.h>
-#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
}
using namespace std;
@@ -275,4 +277,35 @@ git_revision(const string& path)
return revision;
}
+
+static pid_t spawned_pid = 0;
+
+// Runs a command with a saved PID, so we can kill it from the signal handler
+int
+stap_system(const char *command)
+{
+ const char * argv[] = { "sh", "-c", command, NULL };
+ int ret, status;
+
+ spawned_pid = 0;
+ ret = posix_spawn(&spawned_pid, "/bin/sh", NULL, NULL,
+ const_cast<char **>(argv), environ);
+ if (ret == 0)
+ {
+ if (waitpid(spawned_pid, &status, 0) == spawned_pid)
+ ret = WIFEXITED(status) ? WEXITSTATUS(status) : 128 + WTERMSIG(status);
+ else
+ ret = errno;
+ }
+ spawned_pid = 0;
+ return ret;
+}
+
+// Send a signal to our spawned command
+int
+kill_stap_spawn(int sig)
+{
+ return spawned_pid ? kill(spawned_pid, sig) : 0;
+}
+
/* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */