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