summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--runtime/staprun/ChangeLog6
-rw-r--r--runtime/staprun/mainloop.c47
2 files changed, 53 insertions, 0 deletions
diff --git a/runtime/staprun/ChangeLog b/runtime/staprun/ChangeLog
index 6c2304ce..4a483b3e 100644
--- a/runtime/staprun/ChangeLog
+++ b/runtime/staprun/ChangeLog
@@ -1,3 +1,9 @@
+2009-01-28 David Smith <dsmith@redhat.com>
+
+ PR9788
+ * mainloop.c (cleanup_and_exit): Added workaround for bug 9788 by
+ fork'ing/exec'ing staprun.
+
2008-01-11 Mark Wielaard <mjw@redhat.com>
* staprun.h: include config.h for dependency.
diff --git a/runtime/staprun/mainloop.c b/runtime/staprun/mainloop.c
index 2fb049b0..29eb4f1f 100644
--- a/runtime/staprun/mainloop.c
+++ b/runtime/staprun/mainloop.c
@@ -357,6 +357,8 @@ void cleanup_and_exit(int detach)
err("\nDisconnecting from systemtap module.\n" "To reconnect, type \"staprun -A %s\"\n", modname);
} else {
const char *staprun = getenv ("SYSTEMTAP_STAPRUN") ?: BINDIR "/staprun";
+#define BUG9788_WORKAROUND
+#ifndef BUG9788_WORKAROUND
dbug(2, "removing %s\n", modname);
if (execlp(staprun, basename (staprun), "-d", modname, NULL) < 0) {
if (errno == ENOEXEC) {
@@ -368,6 +370,51 @@ void cleanup_and_exit(int detach)
perror(staprun);
_exit(1);
}
+#else
+ pid_t pid;
+ int rstatus;
+ struct sigaction sa;
+
+ dbug(2, "removing %s\n", modname);
+
+ // So that waitpid() below will work correctly, we need to clear
+ // out our SIGCHLD handler.
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ sa.sa_handler = SIG_DFL;
+ sigaction(SIGCHLD, &sa, NULL);
+
+ pid = fork();
+ if (pid < 0) {
+ _perr("fork");
+ _exit(-1);
+ }
+
+ if (pid == 0) { /* child process */
+ /* Run the command. */
+ if (execlp(staprun, basename (staprun), "-d", modname, NULL) < 0) {
+ if (errno == ENOEXEC) {
+ char *cmd;
+ if (asprintf(&cmd, "%s -d '%s'", staprun, modname) > 0)
+ execl("/bin/sh", "sh", "-c", cmd, NULL);
+ free(cmd);
+ }
+ perror(staprun);
+ _exit(1);
+ }
+ }
+
+ /* parent process */
+ if (waitpid(pid, &rstatus, 0) < 0) {
+ _perr("waitpid");
+ _exit(-1);
+ }
+
+ if (WIFEXITED(rstatus)) {
+ _exit(WEXITSTATUS(rstatus));
+ }
+ _exit(-1);
+#endif
}
_exit(0);
}