diff options
author | Josh Stone <jistone@redhat.com> | 2009-04-01 14:49:12 -0700 |
---|---|---|
committer | Josh Stone <jistone@redhat.com> | 2009-04-01 15:39:04 -0700 |
commit | 4cc40e829870dd6a1d9714706d38f5fd4b2ec982 (patch) | |
tree | 9c9607d35b5b4c9578b057627d4542836b67875c /util.cxx | |
parent | 0dbfd2a9ccad1759c58f240843cabc50d502e44a (diff) | |
download | systemtap-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.cxx | 41 |
1 files changed, 37 insertions, 4 deletions
@@ -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 : */ |