From aab875a40b61711077e90be904c9977b47931ec3 Mon Sep 17 00:00:00 2001 From: =?utf8?q?P=C3=A1draig=20Brady?= Date: Thu, 15 Jun 2017 02:41:14 -0700 Subject: [PATCH] tail: with -f don't warn if doing a blocking read of a tty * src/tail.c: (main): Only issue the warning about -f being ineffective when we're not going into simple blocking mode. * tests/tail-2/follow-stdin.sh: Ensure the warning is output correctly. Fixes http://bugs.gnu.org/27368 --- NEWS | 8 ++++++-- src/tail.c | 18 ++++++++++++++---- tests/tail-2/follow-stdin.sh | 21 ++++++++++++++++++++- 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/NEWS b/NEWS index d2672e86bc..eb0271cf8f 100644 --- a/NEWS +++ b/NEWS @@ -31,7 +31,7 @@ GNU coreutils NEWS -*- outline -*- tail -F 'dir/file' is now monitored even when 'dir' is replaced. [bug introduced with inotify support added in coreutils-7.5] - tail -f with --pid=PID will now process all inotify events. + tail -f with --pid=PID now processes all inotify events. Previously events may have been ignored completely upon PID death, or ignored until future events on the monitored files. [bug introduced with inotify support added in coreutils-7.5] @@ -53,9 +53,13 @@ GNU coreutils NEWS -*- outline -*- mv --verbose now distinguishes rename and copy operations. - tail -f will now exit immediately if the output is piped + tail -f now exits immediately if the output is piped and the reader of the pipe terminates. + tail -f no longer erroneously warns about being ineffective + when following a single tty, as the simple blocking loop used + is effective in this case. + * Noteworthy changes in release 8.27 (2017-03-08) [stable] diff --git a/src/tail.c b/src/tail.c index 3918373f60..2f9b981f0d 100644 --- a/src/tail.c +++ b/src/tail.c @@ -2365,12 +2365,22 @@ main (int argc, char **argv) if (found_hyphen && follow_mode == Follow_name) die (EXIT_FAILURE, 0, _("cannot follow %s by name"), quoteaf ("-")); - /* When following forever, warn if any file is '-'. + /* When following forever, and not using simple blocking, warn if + any file is '-' as the stats() used to check for input are ineffective. This is only a warning, since tail's output (before a failing seek, and that from any non-stdin files) might still be useful. */ - if (forever && found_hyphen && isatty (STDIN_FILENO)) - error (0, 0, _("warning: following standard input" - " indefinitely is ineffective")); + if (forever && found_hyphen) + { + struct stat in_stat; + bool blocking_stdin; + blocking_stdin = (pid == 0 && follow_mode == Follow_descriptor + && n_files == 1 && ! fstat (STDIN_FILENO, &in_stat) + && ! S_ISREG (in_stat.st_mode)); + + if (! blocking_stdin && isatty (STDIN_FILENO)) + error (0, 0, _("warning: following standard input" + " indefinitely is ineffective")); + } } /* Don't read anything if we'll never output anything. */ diff --git a/tests/tail-2/follow-stdin.sh b/tests/tail-2/follow-stdin.sh index 7e82835ffb..c922ea11ad 100755 --- a/tests/tail-2/follow-stdin.sh +++ b/tests/tail-2/follow-stdin.sh @@ -1,5 +1,5 @@ #!/bin/sh -# tail -f - would fail with the initial inotify implementation +# Test tail -f - # Copyright (C) 2009-2017 Free Software Foundation, Inc. @@ -19,6 +19,9 @@ . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src print_ver_ tail +################# +# tail -f - would fail with the initial inotify implementation + check_tail_output() { local delay="$1" @@ -51,6 +54,7 @@ for mode in '' '---disable-inotify'; do done +################# # Before coreutils-8.26 this would induce an UMR under UBSAN returns_ 1 timeout 10 tail -f - <&- 2>errt || fail=1 cat <<\EOF >exp || framework_failure_ @@ -63,4 +67,19 @@ sed 's/\(tail:.*\):.*/\1/' errt > err || framework_failure_ compare exp err || fail=1 +################# +# Before coreutils-8.28 this would erroneously issue a warning +if tty -s err || fail=1 + compare /dev/null err || fail=1 + done + + tail -f - /dev/null out & pid=$! + # Wait up to 12.7s for output to appear: + tail_re='ineffective' retry_delay_ check_tail_output .1 7 || + { cat out; fail=1; } + cleanup_ +fi + Exit $fail -- 2.47.2