From 69aa1bdbbcc270d55f879c3a167dfee9baa03f61 Mon Sep 17 00:00:00 2001 From: David Smith Date: Wed, 28 Jan 2009 12:05:33 -0600 Subject: [PATCH] 2009-01-28 David Smith PR9788 * mainloop.c (cleanup_and_exit): Added workaround for bug 9788 by fork'ing/exec'ing staprun. --- runtime/staprun/ChangeLog | 6 +++++ runtime/staprun/mainloop.c | 47 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/runtime/staprun/ChangeLog b/runtime/staprun/ChangeLog index 6c2304ce3..4a483b3eb 100644 --- a/runtime/staprun/ChangeLog +++ b/runtime/staprun/ChangeLog @@ -1,3 +1,9 @@ +2009-01-28 David Smith + + PR9788 + * mainloop.c (cleanup_and_exit): Added workaround for bug 9788 by + fork'ing/exec'ing staprun. + 2008-01-11 Mark Wielaard * staprun.h: include config.h for dependency. diff --git a/runtime/staprun/mainloop.c b/runtime/staprun/mainloop.c index 2fb049b0b..29eb4f1f1 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); } -- 2.43.5