From 18f6b22fe1eb4447b26fafd3bed1e6bb23c9adc2 Mon Sep 17 00:00:00 2001 From: =?utf8?q?P=C3=A1draig=20Brady?= Date: Fri, 16 Jun 2017 23:50:47 -0700 Subject: [PATCH] tail: only use inotify with regular files * src/tail.c (any_non_regular): A new function to check passed files. (main): Use the above to skip inotify if any non regular files passed like /dev/tty or /dev/ttyUSB0 etc. * tests/tail-2/inotify-only-regular.sh: A new test. * tests/local.mk: Reference the new test. * NEWS: Mention the bug fix. Fixes http://bugs.gnu.org/21265 and http://bugs.gnu.org/27368 --- NEWS | 4 ++++ src/tail.c | 17 +++++++++++++++++ tests/local.mk | 1 + tests/tail-2/inotify-only-regular.sh | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 54 insertions(+) create mode 100755 tests/tail-2/inotify-only-regular.sh diff --git a/NEWS b/NEWS index eb0271cf8..071be4bb4 100644 --- a/NEWS +++ b/NEWS @@ -36,6 +36,10 @@ GNU coreutils NEWS -*- outline -*- or ignored until future events on the monitored files. [bug introduced with inotify support added in coreutils-7.5] + tail -f /dev/tty is now supported by not using inotify when any + non regular files are specified, as inotify is ineffective with these. + [bug introduced with inotify support added in coreutils-7.5] + uptime no longer outputs the AM/PM component of the current time, as that's inconsistent with the 24 hour time format used. [bug introduced in coreutils-7.0] diff --git a/src/tail.c b/src/tail.c index 2f9b981f0..b8be1d21d 100644 --- a/src/tail.c +++ b/src/tail.c @@ -1339,6 +1339,22 @@ any_symlinks (const struct File_spec *f, size_t n_files) return false; } +/* Return true if any of the N_FILES files in F is not + a regular file. This is used to avoid adding inotify + watches on a device file for example, which inotify + will accept, but not give any events for. */ + +static bool +any_non_regular (const struct File_spec *f, size_t n_files) +{ + size_t i; + + for (i = 0; i < n_files; i++) + if (0 <= f[i].fd && ! S_ISREG (f[i].mode)) + return true; + return false; +} + /* Return true if any of the N_FILES files in F represents stdin and is tailable. */ @@ -2457,6 +2473,7 @@ main (int argc, char **argv) || any_remote_file (F, n_files) || ! any_non_remote_file (F, n_files) || any_symlinks (F, n_files) + || any_non_regular (F, n_files) || (!ok && follow_mode == Follow_descriptor))) disable_inotify = true; diff --git a/tests/local.mk b/tests/local.mk index fdf3edfb2..6112e88ed 100644 --- a/tests/local.mk +++ b/tests/local.mk @@ -177,6 +177,7 @@ all_tests = \ tests/tail-2/inotify-rotate.sh \ tests/tail-2/inotify-rotate-resources.sh \ tests/tail-2/inotify-dir-recreate.sh \ + tests/tail-2/inotify-only-regular.sh \ tests/chmod/no-x.sh \ tests/chgrp/basic.sh \ tests/rm/dangling-symlink.sh \ diff --git a/tests/tail-2/inotify-only-regular.sh b/tests/tail-2/inotify-only-regular.sh new file mode 100755 index 000000000..4d106fbb8 --- /dev/null +++ b/tests/tail-2/inotify-only-regular.sh @@ -0,0 +1,32 @@ +#!/bin/sh +# ensure that tail -f only uses inotify for regular files + +# Copyright (C) 2017 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ tail + +grep '^#define HAVE_INOTIFY 1' "$CONFIG_HEADER" >/dev/null \ + || skip_ 'inotify support required' + +require_strace_ 'inotify_add_watch' + +returns_ 124 timeout .1 strace -e inotify_add_watch -o strace.out \ + tail -f /dev/null || fail=1 + +grep 'inotify' strace.out && fail=1 + +Exit $fail -- 2.11.4.GIT