diff --git a/src/input/readers/raw/Raw.cc b/src/input/readers/raw/Raw.cc index a820ed0619..277d64577f 100644 --- a/src/input/readers/raw/Raw.cc +++ b/src/input/readers/raw/Raw.cc @@ -291,7 +291,7 @@ bool Raw::OpenInput() return false; } - if ( Info().mode == MODE_STREAM ) + if ( Info().mode == MODE_STREAM || Info().mode == MODE_REREAD ) { struct stat sb; if ( fstat(fileno(file.get()), &sb) == -1 ) @@ -300,6 +300,8 @@ bool Raw::OpenInput() Error(Fmt("Could not get fstat for %s", fname.c_str())); return false; } + + mtime = sb.st_mtime; ino = sb.st_ino; dev = sb.st_dev; } @@ -587,7 +589,7 @@ bool Raw::DoUpdate() return false; } - if ( sb.st_ino == ino && sb.st_mtime == mtime ) + if ( sb.st_dev == dev && sb.st_ino == ino && sb.st_mtime == mtime ) // no change return true; diff --git a/testing/btest/Baseline/scripts.base.frameworks.input.raw.rereadraw2/out b/testing/btest/Baseline/scripts.base.frameworks.input.raw.rereadraw2/out new file mode 100644 index 0000000000..ffa4b2758d --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.input.raw.rereadraw2/out @@ -0,0 +1,8 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +A::line, 1, First, 5 +A::line, 2, Second, 6 +A::line, 3, Third, 5 +A::line, 4, , 0 +A::line, 5, Fourth, 6 +end_of_data, input, ./input.log +terminate diff --git a/testing/btest/scripts/base/frameworks/input/raw/rereadraw2.zeek b/testing/btest/scripts/base/frameworks/input/raw/rereadraw2.zeek new file mode 100644 index 0000000000..c996166d94 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/input/raw/rereadraw2.zeek @@ -0,0 +1,64 @@ +# @TEST-DOC: The raw reader would read a file in MODE_REREAD twice initially. Check this is fixed by running with reduced heartbeat_interval and waiting for 20 intervals after the first end_of_data event. +# +# @TEST-EXEC: zeek -b %INPUT > out +# @TEST-EXEC: btest-diff out + +@TEST-START-FILE input.log +First +Second +Third + +Fourth +@TEST-END-FILE + +@load base/frameworks/input + +# By default the heartbeat timer is 1sec. To avoid running this test for +# multiple seconds, tune it down 100x. 10msec is still pretty long. +redef Threading::heartbeat_interval = 10msec; +redef exit_only_after_terminate = T; + +module A; + +type Val: record { + s: string; +}; + +event do_terminate() + { + if ( zeek_is_terminating() ) + return; + + print "terminate"; + terminate(); + } + +event Input::end_of_data(name: string, source: string) + { + print "end_of_data", name, source; + schedule 20 * Threading::heartbeat_interval { do_terminate() }; + } + +global lines = 0; + +event A::line(description: Input::EventDescription, tpe: Input::Event, s: string) + { + ++lines; + print "A::line", lines, s, |s|; + } + +event zeek_init() + { + # In case something goes wrong. + schedule 10sec { do_terminate() }; + + Input::add_event([ + $source="./input.log", + $reader=Input::READER_RAW, + $mode=Input::REREAD, + $name="input", + $fields=Val, + $ev=A::line, + $want_record=F, + ]); + }