diff options
-rw-r--r-- | src/tail.c | 30 | ||||
-rwxr-xr-x | tests/tail-2/append-only | 9 | ||||
-rwxr-xr-x | tests/tail-2/pid | 46 | ||||
-rwxr-xr-x | tests/tail-2/tail-n0f | 24 | ||||
-rwxr-xr-x | tests/tail-2/wait | 67 |
5 files changed, 101 insertions, 75 deletions
diff --git a/src/tail.c b/src/tail.c index f0dbf5d5e..6077473c0 100644 --- a/src/tail.c +++ b/src/tail.c @@ -201,6 +201,10 @@ static bool have_read_stdin; more expensive) code unconditionally. Intended solely for testing. */ static bool presume_input_pipe; +/* If nonzero then don't use inotify even if available. + Intended solely for testing. */ +static bool disable_inotify; + /* For long options that have no equivalent short option, use a non-character as a pseudo short option, starting with CHAR_MAX + 1. */ enum @@ -209,7 +213,8 @@ enum MAX_UNCHANGED_STATS_OPTION, PID_OPTION, PRESUME_INPUT_PIPE_OPTION, - LONG_FOLLOW_OPTION + LONG_FOLLOW_OPTION, + DISABLE_INOTIFY_OPTION }; static struct option const long_options[] = @@ -218,6 +223,8 @@ static struct option const long_options[] = {"follow", optional_argument, NULL, LONG_FOLLOW_OPTION}, {"lines", required_argument, NULL, 'n'}, {"max-unchanged-stats", required_argument, NULL, MAX_UNCHANGED_STATS_OPTION}, + {"-disable-inotify", no_argument, NULL, + DISABLE_INOTIFY_OPTION}, /* do not document */ {"pid", required_argument, NULL, PID_OPTION}, {"-presume-input-pipe", no_argument, NULL, PRESUME_INPUT_PIPE_OPTION}, /* do not document */ @@ -1794,6 +1801,10 @@ parse_options (int argc, char **argv, } break; + case DISABLE_INOTIFY_OPTION: + disable_inotify = true; + break; + case PID_OPTION: { strtol_error s_err; @@ -1972,15 +1983,18 @@ main (int argc, char **argv) if (forever) { #if HAVE_INOTIFY - int wd = inotify_init (); - if (wd < 0) - error (0, errno, _("inotify cannot be used, reverting to polling")); - else + if (!disable_inotify) { - tail_forever_inotify (wd, F, n_files, sleep_interval); + int wd = inotify_init (); + if (wd < 0) + error (0, errno, _("inotify cannot be used, reverting to polling")); + else + { + tail_forever_inotify (wd, F, n_files, sleep_interval); - /* The only way the above returns is upon failure. */ - exit (EXIT_FAILURE); + /* The only way the above returns is upon failure. */ + exit (EXIT_FAILURE); + } } #endif tail_forever (F, n_files, sleep_interval); diff --git a/tests/tail-2/append-only b/tests/tail-2/append-only index 0b4a95958..2d38d4f0f 100755 --- a/tests/tail-2/append-only +++ b/tests/tail-2/append-only @@ -37,9 +37,12 @@ fi fail=0 -sleep 1 & -pid=$! -tail --pid=$pid -f f || fail=1 +for inotify in ---disable-inotify ''; do + sleep 1 & + pid=$! + tail --pid=$pid -f $inotify f || fail=1 +done + chattr -a f 2>/dev/null Exit $fail diff --git a/tests/tail-2/pid b/tests/tail-2/pid index a797666fe..aaf2e01ba 100755 --- a/tests/tail-2/pid +++ b/tests/tail-2/pid @@ -22,32 +22,34 @@ if test "$VERBOSE" = yes; then fi . $srcdir/test-lib.sh +getlimits_ touch here || framework_failure fail=0 -# Use tail itself to create a background process to monitor. -tail -f here & -bg_pid=$! - -# Ensure that tail --pid=PID does not exit when PID is alive. -timeout 1 tail -s.1 -f here --pid=$bg_pid -test $? = 124 || fail=1 - -# Cleanup background process -kill $bg_pid - -# Ensure that tail --pid=PID exits successfully when PID is dead. -# Use an unlikely-to-be-live PID -getlimits_ -timeout 1 tail -s.1 --pid=$PID_T_MAX -f /dev/null -ret=$? -test $ret = 124 && skip_test_ "pid $PID_T_MAX present" -test $ret = 0 || fail=1 - -# Ensure fractional sleep parameter is honored with --pid -timeout 1 tail -s.1 -f /dev/null --pid=$PID_T_MAX -test $? = 124 && fail=1 +for inotify in ---disable-inotify ''; do + # Use tail itself to create a background process to monitor. + tail -f $inotify here & + bg_pid=$! + + # Ensure that tail --pid=PID does not exit when PID is alive. + timeout 1 tail -s.1 -f $inotify here --pid=$bg_pid + test $? = 124 || fail=1 + + # Cleanup background process + kill $bg_pid + + # Ensure that tail --pid=PID exits successfully when PID is dead. + # Use an unlikely-to-be-live PID + timeout 1 tail -s.1 --pid=$PID_T_MAX -f $inotify /dev/null + ret=$? + test $ret = 124 && skip_test_ "pid $PID_T_MAX present" + test $ret = 0 || fail=1 + + # Ensure fractional sleep parameter is honored with --pid + timeout 1 tail -s.1 -f $inotify /dev/null --pid=$PID_T_MAX + test $? = 124 && fail=1 +done Exit $fail diff --git a/tests/tail-2/tail-n0f b/tests/tail-2/tail-n0f index fce7ed16e..ddfbe6645 100755 --- a/tests/tail-2/tail-n0f +++ b/tests/tail-2/tail-n0f @@ -35,17 +35,19 @@ echo anything > nonempty || framework_failure fail=0 -for file in empty nonempty; do - for c_or_n in c n; do - tail --sleep=4 -${c_or_n} 0 -f $file & - pid=$! - sleep .5 - state=$(get_process_status_ $pid) - case $state in - S*) ;; - *) echo $0: process in unexpected state: $state 1>&2; fail=1 ;; - esac - kill $pid +for inotify in ---disable-inotify ''; do + for file in empty nonempty; do + for c_or_n in c n; do + tail --sleep=4 -${c_or_n} 0 -f $inotify $file & + pid=$! + sleep .5 + state=$(get_process_status_ $pid) + case $state in + S*) ;; + *) echo $0: process in unexpected state: $state 1>&2; fail=1 ;; + esac + kill $pid + done done done diff --git a/tests/tail-2/wait b/tests/tail-2/wait index a5f189fe0..62498d5dc 100755 --- a/tests/tail-2/wait +++ b/tests/tail-2/wait @@ -30,43 +30,48 @@ touch k || framework_failure fail=0 -timeout 1 tail -s0.1 -f not_here -test $? = 124 && fail=1 - -if test ! -r unreadable; then # can't test this when root - timeout 1 tail -s0.1 -f unreadable +for inotify in ---disable-inotify ''; do + timeout 1 tail -s0.1 -f $inotify not_here test $? = 124 && fail=1 -fi -timeout 1 tail -s0.1 -f here 2>tail.err -test $? = 124 || fail=1 + if test ! -r unreadable; then # can't test this when root + timeout 1 tail -s0.1 -f $inotify unreadable + test $? = 124 && fail=1 + fi -# `tail -F' must wait in any case. + timeout 1 tail -s0.1 -f $inotify here 2>tail.err + test $? = 124 || fail=1 -timeout 1 tail -s0.1 -F here 2>>tail.err -test $? = 124 || fail=1 + # `tail -F' must wait in any case. -if test ! -r unreadable; then # can't test this when root - timeout 1 tail -s0.1 -F unreadable + timeout 1 tail -s0.1 -F $inotify here 2>>tail.err test $? = 124 || fail=1 -fi -timeout 1 tail -s0.1 -F not_here -test $? = 124 || fail=1 - -test -s tail.err && fail=1 - -tail -s.1 --max-unchanged-stats=2 -F k > tail.out & -pid=$! -sleep .5 -mv k l -sleep .5 -touch k -mv k l -sleep .5 -echo NO >> l -sleep .5 -kill $pid -test -s tail.out && fail=1 + if test ! -r unreadable; then # can't test this when root + timeout 1 tail -s0.1 -F $inotify unreadable + test $? = 124 || fail=1 + fi + + timeout 1 tail -s0.1 -F $inotify not_here + test $? = 124 || fail=1 + + + test -s tail.err && fail=1 + :>tail.err + + + tail -s.1 --max-unchanged-stats=2 -F $inotify k > tail.out & + pid=$! + sleep .5 + mv k l + sleep .5 + touch k + mv k l + sleep .5 + echo NO >> l + sleep .5 + kill $pid + test -s tail.out && fail=1 +done Exit $fail |