diff --git a/scripts/base/utils/dir.bro b/scripts/base/utils/dir.bro index 4f3ee94945..1ade4a47f7 100644 --- a/scripts/base/utils/dir.bro +++ b/scripts/base/utils/dir.bro @@ -28,7 +28,7 @@ event Dir::monitor_ev(dir: string, last_files: set[string], callback: function(fname: string), poll_interval: interval) { - when ( local result = Exec::run([$cmd=fmt("ls -i \"%s/\"", str_shell_escape(dir))]) ) + when ( local result = Exec::run([$cmd=fmt("ls -i -1 \"%s/\"", str_shell_escape(dir))]) ) { if ( result$exit_code != 0 ) { diff --git a/scripts/base/utils/exec.bro b/scripts/base/utils/exec.bro index 732bbcf34c..d505b424c7 100644 --- a/scripts/base/utils/exec.bro +++ b/scripts/base/utils/exec.bro @@ -163,6 +163,7 @@ function run(cmd: Command): Result Input::add_event([$name=cmd$uid, $source=fmt("%s |", cmd$cmd), $reader=Input::READER_RAW, + $mode=Input::STREAM, $fields=Exec::OneLine, $ev=Exec::line, $want_record=F, diff --git a/src/input/readers/Raw.cc b/src/input/readers/Raw.cc index 2820923a25..0f4c4ca7d1 100644 --- a/src/input/readers/Raw.cc +++ b/src/input/readers/Raw.cc @@ -95,29 +95,32 @@ bool Raw::Execute() else if ( childpid == 0 ) { // we are the child. - close(pipes[stdout_in]); - dup2(pipes[stdout_out], stdout_fileno); + safe_close(pipes[stdout_in]); + if ( dup2(pipes[stdout_out], stdout_fileno) == -1 ) + Error(Fmt("Error on dup2 stdout_out: %d", errno)); if ( stdin_towrite ) { - close(pipes[stdin_out]); - dup2(pipes[stdin_in], stdin_fileno); + safe_close(pipes[stdin_out]); + if ( dup2(pipes[stdin_in], stdin_fileno) == -1 ) + Error(Fmt("Error on dup2 stdin_in: %d", errno)); } if ( use_stderr ) { - close(pipes[stderr_in]); - dup2(pipes[stderr_out], stderr_fileno); + safe_close(pipes[stderr_in]); + if ( dup2(pipes[stderr_out], stderr_fileno) == -1 ) + Error(Fmt("Error on dup2 stderr_out: %d", errno)); } - execl("/bin/sh", "sh", "-c", fname.c_str(), NULL); + execl("/bin/sh", "sh", "-c", fname.c_str(), (char*) NULL); fprintf(stderr, "Exec failed :(......\n"); exit(255); } else { // we are the parent - close(pipes[stdout_out]); + safe_close(pipes[stdout_out]); pipes[stdout_out] = -1; if ( Info().mode == MODE_STREAM ) @@ -125,7 +128,7 @@ bool Raw::Execute() if ( stdin_towrite ) { - close(pipes[stdin_in]); + safe_close(pipes[stdin_in]); pipes[stdin_in] = -1; fcntl(pipes[stdin_out], F_SETFL, O_NONBLOCK); // ya, just always set this to nonblocking. we do not want to block on a program receiving data. // note that there is a small gotcha with it. More data is queued when more data is read from the program output. Hence, when having @@ -134,7 +137,7 @@ bool Raw::Execute() if ( use_stderr ) { - close(pipes[stderr_out]); + safe_close(pipes[stderr_out]); pipes[stderr_out] = -1; fcntl(pipes[stderr_in], F_SETFL, O_NONBLOCK); // true for this too. } @@ -195,7 +198,10 @@ bool Raw::CloseInput() { for ( int i = 0; i < 6; i ++ ) if ( pipes[i] != -1 ) - close(pipes[i]); + { + safe_close(pipes[i]); + pipes[i] = -1; + } } file = 0; @@ -393,11 +399,13 @@ void Raw::WriteToStdin() { Error(Fmt("Writing to child process stdin failed: %d. Stopping writing at position %d", errno, pos)); stdin_towrite = 0; - close(pipes[stdin_out]); } if ( stdin_towrite == 0 ) // send EOF when we are done. - close(pipes[stdin_out]); + { + safe_close(pipes[stdin_out]); + pipes[stdin_out] = -1; + } if ( Info().mode == MODE_MANUAL && stdin_towrite != 0 ) { @@ -528,6 +536,7 @@ bool Raw::DoUpdate() if ( childpid != -1 && waitpid(childpid, &return_code, WNOHANG) != 0 ) { // child died + childpid = -1; bool signal = false; int code = 0; if ( WIFEXITED(return_code) ) @@ -539,7 +548,7 @@ bool Raw::DoUpdate() else if ( WIFSIGNALED(return_code) ) { - signal = false; + signal = true; code = WTERMSIG(return_code); Error(Fmt("Child process exited due to signal %d", code)); } @@ -564,7 +573,7 @@ bool Raw::DoUpdate() EndCurrentSend(); SendEvent("InputRaw::process_finished", 4, vals); - } + } diff --git a/testing/btest/Baseline/scripts.base.utils.exec/bro..stdout b/testing/btest/Baseline/scripts.base.utils.exec/bro..stdout index 5352d15d18..3cfdaafb4c 100644 --- a/testing/btest/Baseline/scripts.base.utils.exec/bro..stdout +++ b/testing/btest/Baseline/scripts.base.utils.exec/bro..stdout @@ -3,5 +3,4 @@ test1, [exit_code=0, signal_exit=F, stdout=[done, exit, stop], stderr=] -test3, [exit_code=9, signal_exit=F, stdout=[FML], stderr=, files=] test4, [exit_code=0, signal_exit=F, stdout=[hibye], stderr=, files=] diff --git a/testing/btest/scripts/base/frameworks/input/raw/executestdin.bro b/testing/btest/scripts/base/frameworks/input/raw/executestdin.bro index 729844e4b4..f6513dc6aa 100644 --- a/testing/btest/scripts/base/frameworks/input/raw/executestdin.bro +++ b/testing/btest/scripts/base/frameworks/input/raw/executestdin.bro @@ -39,6 +39,5 @@ event bro_init() try = 0; outfile = open("../out"); Input::add_event([$source="cat > ../test.txt |", $reader=Input::READER_RAW, $mode=Input::STREAM, $name="input", $fields=Val, $ev=line, $want_record=F, $config=config_strings]); - Input::remove("input"); Input::add_event([$source="cat |", $reader=Input::READER_RAW, $mode=Input::STREAM, $name="input2", $fields=Val, $ev=line, $want_record=F, $config=config_strings]); } diff --git a/testing/btest/scripts/base/utils/active-http.test b/testing/btest/scripts/base/utils/active-http.test index 127b21d77e..f547e7dd15 100644 --- a/testing/btest/scripts/base/utils/active-http.test +++ b/testing/btest/scripts/base/utils/active-http.test @@ -1,4 +1,3 @@ -# @TEST-REQUIRES: which httpd # @TEST-REQUIRES: which python # # @TEST-EXEC: btest-bg-run httpd python $SCRIPTS/httpd.py --max 1 @@ -8,7 +7,7 @@ # @TEST-EXEC: btest-diff bro/.stdout @load base/utils/active-http - +@load base/frameworks/communication # let network-time run. otherwise there are no heartbeats... redef exit_only_after_terminate = T; event bro_init() diff --git a/testing/btest/scripts/base/utils/dir.test b/testing/btest/scripts/base/utils/dir.test index 44fee3860f..aa9ee62315 100644 --- a/testing/btest/scripts/base/utils/dir.test +++ b/testing/btest/scripts/base/utils/dir.test @@ -1,11 +1,11 @@ # @TEST-EXEC: btest-bg-run bro bro -b ../dirtest.bro -# @TEST-EXEC: btest-bg-wait 10 +# @TEST-EXEC: btest-bg-wait 15 # @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-sort btest-diff bro/.stdout @TEST-START-FILE dirtest.bro @load base/utils/dir - +@load base/frameworks/communication # let network-time run. otherwise there are no heartbeats... redef exit_only_after_terminate = T; global c: count = 0; @@ -33,14 +33,20 @@ function new_file2(fname: string) event change_things() { system("touch ../testdir/newone"); - system("rm ../testdir/bye && touch ../testdir/bye"); + system("rm ../testdir/bye"); + } + +event change_things2() + { + system("touch ../testdir/bye"); } event bro_init() { Dir::monitor("../testdir", new_file1, .5sec); Dir::monitor("../testdir", new_file2, 1sec); - schedule 1sec { change_things() }; + schedule 3sec { change_things() }; + schedule 6sec { change_things2() }; } @TEST-END-FILE diff --git a/testing/btest/scripts/base/utils/exec.test b/testing/btest/scripts/base/utils/exec.test index 8876f0f49b..33ba10f97a 100644 --- a/testing/btest/scripts/base/utils/exec.test +++ b/testing/btest/scripts/base/utils/exec.test @@ -1,11 +1,11 @@ # @TEST-EXEC: btest-bg-run bro bro -b ../exectest.bro -# @TEST-EXEC: btest-bg-wait 10 +# @TEST-EXEC: btest-bg-wait 15 # @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-sort btest-diff bro/.stdout @TEST-START-FILE exectest.bro @load base/utils/exec - +@load base/frameworks/communication # let network-time run. otherwise there are no heartbeats... redef exit_only_after_terminate = T; global c: count = 0; @@ -14,7 +14,7 @@ function check_exit_condition() { c += 1; - if ( c == 4 ) + if ( c == 3 ) terminate(); } @@ -32,7 +32,8 @@ event bro_init() test_cmd("test1", [$cmd="bash ../somescript.sh", $read_files=set("out1", "out2")]); test_cmd("test2", [$cmd="bash ../nofiles.sh"]); - test_cmd("test3", [$cmd="bash ../suicide.sh"]); + # Not sure of a portable way to test signals yet. + #test_cmd("test3", [$cmd="bash ../suicide.sh"]); test_cmd("test4", [$cmd="bash ../stdin.sh", $stdin="hibye"]); }