From ca9b9162a75d1ab9ce2a52823c3fae2b85173cec Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Wed, 4 Sep 2013 10:45:29 -0500 Subject: [PATCH] Fix raw execution input reader's signal blocking. Signals are generally blocked within threads in Bro so that the main thread does all signal handling, however, signal masks are inherited over fork() and exec(), so they should be unblocked before exec() so that process can respond to signals normally. This fixes the raw reader from leaving behind processes that didn't respond to SIGTERM at shutdown because it was blocked before exec(). --- src/input/readers/Raw.cc | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/input/readers/Raw.cc b/src/input/readers/Raw.cc index 2a890eab4e..f8facca374 100644 --- a/src/input/readers/Raw.cc +++ b/src/input/readers/Raw.cc @@ -14,6 +14,10 @@ #include #include +extern "C" { +#include "setsignal.h" +} + using namespace input::reader; using threading::Value; using threading::Field; @@ -70,14 +74,14 @@ void Raw::DoClose() if ( execute && childpid > 0 && kill(childpid, 0) == 0 ) { // kill child process - kill(childpid, 15); // sigterm + kill(childpid, SIGTERM); if ( forcekill ) { usleep(200); // 200 msecs should be enough for anyone ;) if ( kill(childpid, 0) == 0 ) // perhaps it is already gone - kill(childpid, 9); // TERMINATE + kill(childpid, SIGKILL); } } } @@ -160,6 +164,15 @@ bool Raw::Execute() close(pipes[stderr_out]); + // Signal mask is inherited over fork-exec, so reset any ignored + // signals to default behavior and unblock any blocked signals. + setsignal(SIGPIPE, SIG_DFL); // May be ignored when debugging scripts. + sigset_t mask; + sigfillset(&mask); + // Assuming the fork-one model of pthreads' fork(), using sigprocmask() + // makes sense over pthread_sigmask() here. + sigprocmask(SIG_UNBLOCK, &mask, 0); + execl("/bin/sh", "sh", "-c", fname.c_str(), (char*) NULL); fprintf(stderr, "Exec failed :(......\n"); _exit(255);