diff options
author | David Smith <dsmith@redhat.com> | 2009-01-28 12:05:33 -0600 |
---|---|---|
committer | David Smith <dsmith@redhat.com> | 2009-01-28 12:05:33 -0600 |
commit | 69aa1bdbbcc270d55f879c3a167dfee9baa03f61 (patch) | |
tree | 98158174bcf97271f1393c7177d10bc7a52c0d09 | |
parent | ffaf6b84d9a3820d538e2d20df0e19e7fd0607d8 (diff) | |
download | systemtap-steved-69aa1bdbbcc270d55f879c3a167dfee9baa03f61.tar.gz systemtap-steved-69aa1bdbbcc270d55f879c3a167dfee9baa03f61.tar.xz systemtap-steved-69aa1bdbbcc270d55f879c3a167dfee9baa03f61.zip |
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.
-rw-r--r-- | runtime/staprun/ChangeLog | 6 | ||||
-rw-r--r-- | runtime/staprun/mainloop.c | 47 |
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); } |