summaryrefslogtreecommitdiff
path: root/tests/tail-2
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2016-01-20 10:55:18 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2016-01-20 10:55:18 +0000
commit70e9163c9c18e995515598085cb824e554eb7ae7 (patch)
treea42dc8b2a6c031354bf31472de888bfc8a060132 /tests/tail-2
parentcbf5993c43f49281173f185863577d86bfac6eae (diff)
downloadcoreutils-tarball-70e9163c9c18e995515598085cb824e554eb7ae7.tar.gz
Diffstat (limited to 'tests/tail-2')
-rwxr-xr-xtests/tail-2/F-headers.sh59
-rwxr-xr-xtests/tail-2/F-vs-missing.sh59
-rwxr-xr-xtests/tail-2/F-vs-rename.sh83
-rw-r--r--tests/tail-2/Makefile.am34
-rw-r--r--tests/tail-2/Makefile.in744
-rwxr-xr-xtests/tail-2/append-only55
-rwxr-xr-xtests/tail-2/append-only.sh46
-rwxr-xr-xtests/tail-2/assert78
-rwxr-xr-xtests/tail-2/assert-266
-rwxr-xr-xtests/tail-2/assert-2.sh57
-rwxr-xr-xtests/tail-2/assert.sh68
-rwxr-xr-xtests/tail-2/big-4gb71
-rwxr-xr-xtests/tail-2/big-4gb.sh50
-rwxr-xr-xtests/tail-2/descriptor-vs-rename.sh56
-rwxr-xr-xtests/tail-2/flush-initial.sh44
-rwxr-xr-xtests/tail-2/follow-name.sh36
-rwxr-xr-xtests/tail-2/follow-stdin.sh53
-rwxr-xr-xtests/tail-2/inotify-hash-abuse.sh71
-rwxr-xr-xtests/tail-2/inotify-hash-abuse2.sh46
-rwxr-xr-xtests/tail-2/inotify-race.sh98
-rwxr-xr-xtests/tail-2/inotify-race2.sh103
-rwxr-xr-xtests/tail-2/inotify-rotate-resources.sh108
-rwxr-xr-xtests/tail-2/inotify-rotate.sh77
-rwxr-xr-xtests/tail-2/pid.sh51
-rwxr-xr-xtests/tail-2/pipe-f.sh27
-rwxr-xr-xtests/tail-2/pipe-f2.sh47
-rwxr-xr-xtests/tail-2/proc-ksyms38
-rwxr-xr-xtests/tail-2/proc-ksyms.sh28
-rwxr-xr-xtests/tail-2/retry.sh131
-rwxr-xr-xtests/tail-2/start-middle53
-rwxr-xr-xtests/tail-2/start-middle.sh33
-rwxr-xr-xtests/tail-2/symlink.sh94
-rwxr-xr-xtests/tail-2/tail-c.sh34
-rwxr-xr-xtests/tail-2/tail-n0f76
-rwxr-xr-xtests/tail-2/tail-n0f.sh62
-rwxr-xr-xtests/tail-2/truncate.sh56
-rwxr-xr-xtests/tail-2/wait.sh96
37 files changed, 1773 insertions, 1215 deletions
diff --git a/tests/tail-2/F-headers.sh b/tests/tail-2/F-headers.sh
new file mode 100755
index 0000000..5747263
--- /dev/null
+++ b/tests/tail-2/F-headers.sh
@@ -0,0 +1,59 @@
+#!/bin/sh
+# Ensure tail -F distinguishes output with the correct headers
+# Between coreutils 7.5 and 8.23 inclusive, 'tail -F ...' would
+# not output headers for or created/renamed files in certain cases.
+
+# Copyright (C) 2015-2016 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 <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ tail
+
+check_tail_output()
+{
+ local delay="$1"
+ grep "$tail_re" out ||
+ { sleep $delay; return 1; }
+}
+
+# Terminate any background tail process
+cleanup_() { kill $pid 2>/dev/null && wait $pid; }
+
+# Speedup the non inotify case
+fastpoll='-s.1 --max-unchanged-stats=1'
+
+for mode in '' '---disable-inotify'; do
+ rm -f a b out
+
+ tail $mode -F $fastpoll a b > out 2>&1 & pid=$!
+
+ # Wait up to 12.7s for tail to start.
+ tail_re="cannot open 'b'" retry_delay_ check_tail_output .1 7 ||
+ { cat out; fail=1; }
+
+ echo x > a
+ # Wait up to 12.7s for a's header to appear in the output:
+ tail_re='==> a <==' retry_delay_ check_tail_output .1 7 ||
+ { echo "$0: a: unexpected delay?"; cat out; fail=1; }
+
+ echo y > b
+ # Wait up to 12.7s for b's header to appear in the output:
+ tail_re='==> b <==' retry_delay_ check_tail_output .1 7 ||
+ { echo "$0: b: unexpected delay?"; cat out; fail=1; }
+
+ cleanup_
+done
+
+Exit $fail
diff --git a/tests/tail-2/F-vs-missing.sh b/tests/tail-2/F-vs-missing.sh
new file mode 100755
index 0000000..361719d
--- /dev/null
+++ b/tests/tail-2/F-vs-missing.sh
@@ -0,0 +1,59 @@
+#!/bin/sh
+# demonstrate that tail -F works for currently missing dirs
+# Before coreutils-8.6, tail -F missing/file would not
+# notice any subsequent availability of the missing/file.
+
+# Copyright (C) 2010-2016 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 <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ tail
+
+check_tail_output()
+{
+ local delay="$1"
+ grep "$tail_re" out > /dev/null ||
+ { sleep $delay; return 1; }
+}
+
+# Terminate any background tail process
+cleanup_() { kill $pid 2>/dev/null && wait $pid; }
+
+# Speedup the non inotify case
+fastpoll='-s.1 --max-unchanged-stats=1'
+
+for mode in '' '---disable-inotify'; do
+ rm -rf out missing
+
+ tail $mode -F $fastpoll missing/file > out 2>&1 & pid=$!
+
+ # Wait up to 12.7s for tail to start with diagnostic:
+ # tail: cannot open 'missing/file' for reading: No such file or directory
+ tail_re='cannot open' retry_delay_ check_tail_output .1 7 ||
+ { cat out; fail=1; }
+
+ mkdir missing || framework_failure_
+ (cd missing && echo x > file) || framework_failure_
+
+ # Wait up to 12.7s for this to appear in the output:
+ # "tail: '...' has appeared; following new file"
+ tail_re='has appeared' retry_delay_ check_tail_output .1 7 ||
+ { echo "$0: file: unexpected delay?"; cat out; fail=1; }
+
+ cleanup_
+done
+
+
+Exit $fail
diff --git a/tests/tail-2/F-vs-rename.sh b/tests/tail-2/F-vs-rename.sh
new file mode 100755
index 0000000..760bbc2
--- /dev/null
+++ b/tests/tail-2/F-vs-rename.sh
@@ -0,0 +1,83 @@
+#!/bin/sh
+# Demonstrate that tail -F works when renaming the tailed files.
+# Between coreutils 7.5 and 8.2 inclusive, 'tail -F a b' would
+# stop tracking additions to b after 'mv a b'.
+
+# Copyright (C) 2009-2016 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 <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ tail
+
+check_tail_output()
+{
+ local delay="$1"
+ grep "$tail_re" out ||
+ { sleep $delay; return 1; }
+}
+
+# Terminate any background tail process
+cleanup_() { kill $pid 2>/dev/null && wait $pid; }
+
+# Speedup the non inotify case
+fastpoll='-s.1 --max-unchanged-stats=1'
+
+for mode in '' '---disable-inotify'; do
+ rm -f a b out
+ touch a b || framework_failure_
+
+ tail $mode -F $fastpoll a b > out 2>&1 & pid=$!
+
+ # Wait up to 12.7s for tail to start.
+ echo x > a
+ tail_re='^x$' retry_delay_ check_tail_output .1 7 || { cat out; fail=1; }
+
+ mv a b || framework_failure_
+
+ # Wait 12.7s for this diagnostic:
+ # tail: 'a' has become inaccessible: No such file or directory
+ tail_re='inaccessible' retry_delay_ check_tail_output .1 7 ||
+ { cat out; fail=1; }
+
+ echo x > a
+ # Wait up to 12.7s for this to appear in the output:
+ # "tail: '...' has appeared; following new file"
+ tail_re='has appeared' retry_delay_ check_tail_output .1 7 ||
+ { echo "$0: a: unexpected delay?"; cat out; fail=1; }
+
+ echo y >> b
+ # Wait up to 12.7s for "y" to appear in the output:
+ tail_f_vs_rename_2() {
+ local delay="$1"
+ tr '\n' @ < out | grep '@@==> b <==@y@$' > /dev/null ||
+ { sleep $delay; return 1; }
+ }
+ retry_delay_ tail_f_vs_rename_2 .1 7 ||
+ { echo "$0: b: unexpected delay?"; cat out; fail=1; }
+
+ echo z >> a
+ # Wait up to 12.7s for "z" to appear in the output:
+ tail_f_vs_rename_3() {
+ local delay="$1"
+ tr '\n' @ < out | grep '@@==> a <==@z@$' > /dev/null ||
+ { sleep $delay; return 1; }
+ }
+ retry_delay_ tail_f_vs_rename_3 .1 7 ||
+ { echo "$0: a: unexpected delay?"; cat out; fail=1; }
+
+ cleanup_
+done
+
+Exit $fail
diff --git a/tests/tail-2/Makefile.am b/tests/tail-2/Makefile.am
deleted file mode 100644
index e038a1b..0000000
--- a/tests/tail-2/Makefile.am
+++ /dev/null
@@ -1,34 +0,0 @@
-# Make coreutils tests for "tail". -*-Makefile-*-
-
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2006 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 2 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.
-
-EXTRA_DIST = $(TESTS)
-
-TESTS_ENVIRONMENT = \
- top_srcdir=$(top_srcdir) \
- srcdir=$(srcdir) \
- PERL="$(PERL)" \
- CU_TEST_NAME=`basename $(abs_srcdir)`,$$tst \
- PATH="$(VG_PATH_PREFIX)`pwd`/../../src$(PATH_SEPARATOR)$$PATH" \
- PROG=tail
-
-TESTS = \
- append-only \
- tail-n0f \
- big-4gb proc-ksyms start-middle assert assert-2
diff --git a/tests/tail-2/Makefile.in b/tests/tail-2/Makefile.in
deleted file mode 100644
index 4a3818a..0000000
--- a/tests/tail-2/Makefile.in
+++ /dev/null
@@ -1,744 +0,0 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-@SET_MAKE@
-
-# Make coreutils tests for "tail". -*-Makefile-*-
-
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2006 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 2 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.
-VPATH = @srcdir@
-pkgdatadir = $(datadir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-build_triplet = @build@
-host_triplet = @host@
-subdir = tests/tail-2
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/absolute-header.m4 \
- $(top_srcdir)/m4/acl.m4 $(top_srcdir)/m4/alloca.m4 \
- $(top_srcdir)/m4/allocsa.m4 $(top_srcdir)/m4/argmatch.m4 \
- $(top_srcdir)/m4/arpa_inet_h.m4 $(top_srcdir)/m4/assert.m4 \
- $(top_srcdir)/m4/atexit.m4 $(top_srcdir)/m4/autobuild.m4 \
- $(top_srcdir)/m4/backupfile.m4 $(top_srcdir)/m4/base64.m4 \
- $(top_srcdir)/m4/bison.m4 $(top_srcdir)/m4/boottime.m4 \
- $(top_srcdir)/m4/c-strtod.m4 $(top_srcdir)/m4/calloc.m4 \
- $(top_srcdir)/m4/canon-host.m4 \
- $(top_srcdir)/m4/canonicalize.m4 \
- $(top_srcdir)/m4/chdir-long.m4 $(top_srcdir)/m4/check-decl.m4 \
- $(top_srcdir)/m4/chown.m4 $(top_srcdir)/m4/clock_time.m4 \
- $(top_srcdir)/m4/cloexec.m4 $(top_srcdir)/m4/close-stream.m4 \
- $(top_srcdir)/m4/closeout.m4 $(top_srcdir)/m4/codeset.m4 \
- $(top_srcdir)/m4/config-h.m4 $(top_srcdir)/m4/cycle-check.m4 \
- $(top_srcdir)/m4/d-ino.m4 $(top_srcdir)/m4/d-type.m4 \
- $(top_srcdir)/m4/dirfd.m4 $(top_srcdir)/m4/dirname.m4 \
- $(top_srcdir)/m4/dos.m4 $(top_srcdir)/m4/double-slash-root.m4 \
- $(top_srcdir)/m4/dup2.m4 $(top_srcdir)/m4/eealloc.m4 \
- $(top_srcdir)/m4/eoverflow.m4 $(top_srcdir)/m4/error.m4 \
- $(top_srcdir)/m4/euidaccess-stat.m4 \
- $(top_srcdir)/m4/euidaccess.m4 $(top_srcdir)/m4/exclude.m4 \
- $(top_srcdir)/m4/exitfail.m4 $(top_srcdir)/m4/extensions.m4 \
- $(top_srcdir)/m4/fchdir.m4 $(top_srcdir)/m4/fcntl-safer.m4 \
- $(top_srcdir)/m4/fcntl_h.m4 $(top_srcdir)/m4/fd-reopen.m4 \
- $(top_srcdir)/m4/file-type.m4 $(top_srcdir)/m4/fileblocks.m4 \
- $(top_srcdir)/m4/filemode.m4 $(top_srcdir)/m4/filenamecat.m4 \
- $(top_srcdir)/m4/flexmember.m4 $(top_srcdir)/m4/fnmatch.m4 \
- $(top_srcdir)/m4/fpending.m4 $(top_srcdir)/m4/fprintftime.m4 \
- $(top_srcdir)/m4/free.m4 $(top_srcdir)/m4/fstypename.m4 \
- $(top_srcdir)/m4/fsusage.m4 $(top_srcdir)/m4/ftruncate.m4 \
- $(top_srcdir)/m4/fts.m4 $(top_srcdir)/m4/getaddrinfo.m4 \
- $(top_srcdir)/m4/getcwd-abort-bug.m4 \
- $(top_srcdir)/m4/getcwd-path-max.m4 $(top_srcdir)/m4/getcwd.m4 \
- $(top_srcdir)/m4/getdate.m4 $(top_srcdir)/m4/getdelim.m4 \
- $(top_srcdir)/m4/getgroups.m4 $(top_srcdir)/m4/gethostname.m4 \
- $(top_srcdir)/m4/gethrxtime.m4 $(top_srcdir)/m4/getline.m4 \
- $(top_srcdir)/m4/getloadavg.m4 $(top_srcdir)/m4/getndelim2.m4 \
- $(top_srcdir)/m4/getopt.m4 $(top_srcdir)/m4/getpagesize.m4 \
- $(top_srcdir)/m4/getpass.m4 $(top_srcdir)/m4/gettext.m4 \
- $(top_srcdir)/m4/gettime.m4 $(top_srcdir)/m4/gettimeofday.m4 \
- $(top_srcdir)/m4/getugroups.m4 \
- $(top_srcdir)/m4/getusershell.m4 $(top_srcdir)/m4/glibc21.m4 \
- $(top_srcdir)/m4/gnulib-common.m4 \
- $(top_srcdir)/m4/gnulib-comp.m4 \
- $(top_srcdir)/m4/group-member.m4 \
- $(top_srcdir)/m4/hard-locale.m4 $(top_srcdir)/m4/hash.m4 \
- $(top_srcdir)/m4/host-os.m4 $(top_srcdir)/m4/human.m4 \
- $(top_srcdir)/m4/i-ring.m4 $(top_srcdir)/m4/iconv.m4 \
- $(top_srcdir)/m4/idcache.m4 $(top_srcdir)/m4/inet_ntop.m4 \
- $(top_srcdir)/m4/inline.m4 $(top_srcdir)/m4/intmax_t.m4 \
- $(top_srcdir)/m4/inttostr.m4 $(top_srcdir)/m4/inttypes-pri.m4 \
- $(top_srcdir)/m4/inttypes.m4 $(top_srcdir)/m4/inttypes_h.m4 \
- $(top_srcdir)/m4/isapipe.m4 $(top_srcdir)/m4/jm-macros.m4 \
- $(top_srcdir)/m4/jm-winsz1.m4 $(top_srcdir)/m4/jm-winsz2.m4 \
- $(top_srcdir)/m4/lchmod.m4 $(top_srcdir)/m4/lchown.m4 \
- $(top_srcdir)/m4/lib-check.m4 $(top_srcdir)/m4/lib-ignore.m4 \
- $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
- $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/link-follow.m4 \
- $(top_srcdir)/m4/localcharset.m4 \
- $(top_srcdir)/m4/long-options.m4 \
- $(top_srcdir)/m4/longdouble.m4 $(top_srcdir)/m4/longlong.m4 \
- $(top_srcdir)/m4/ls-mntd-fs.m4 $(top_srcdir)/m4/lstat.m4 \
- $(top_srcdir)/m4/mbchar.m4 $(top_srcdir)/m4/mbiter.m4 \
- $(top_srcdir)/m4/mbrtowc.m4 $(top_srcdir)/m4/mbscasecmp.m4 \
- $(top_srcdir)/m4/mbstate_t.m4 $(top_srcdir)/m4/mbswidth.m4 \
- $(top_srcdir)/m4/md5.m4 $(top_srcdir)/m4/memcasecmp.m4 \
- $(top_srcdir)/m4/memchr.m4 $(top_srcdir)/m4/memcmp.m4 \
- $(top_srcdir)/m4/memcoll.m4 $(top_srcdir)/m4/memcpy.m4 \
- $(top_srcdir)/m4/memmove.m4 $(top_srcdir)/m4/mempcpy.m4 \
- $(top_srcdir)/m4/memrchr.m4 $(top_srcdir)/m4/memset.m4 \
- $(top_srcdir)/m4/memxfrm.m4 $(top_srcdir)/m4/mkancesdirs.m4 \
- $(top_srcdir)/m4/mkdir-p.m4 $(top_srcdir)/m4/mkdir-slash.m4 \
- $(top_srcdir)/m4/mkstemp.m4 $(top_srcdir)/m4/mktime.m4 \
- $(top_srcdir)/m4/modechange.m4 $(top_srcdir)/m4/mountlist.m4 \
- $(top_srcdir)/m4/mpsort.m4 $(top_srcdir)/m4/nanosleep.m4 \
- $(top_srcdir)/m4/netinet_in_h.m4 $(top_srcdir)/m4/nls.m4 \
- $(top_srcdir)/m4/openat.m4 $(top_srcdir)/m4/pathmax.m4 \
- $(top_srcdir)/m4/perl.m4 $(top_srcdir)/m4/physmem.m4 \
- $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/posixtm.m4 \
- $(top_srcdir)/m4/posixver.m4 $(top_srcdir)/m4/prereq.m4 \
- $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/putenv.m4 \
- $(top_srcdir)/m4/quote.m4 $(top_srcdir)/m4/quotearg.m4 \
- $(top_srcdir)/m4/randint.m4 $(top_srcdir)/m4/randperm.m4 \
- $(top_srcdir)/m4/randread.m4 $(top_srcdir)/m4/readlink.m4 \
- $(top_srcdir)/m4/readtokens.m4 $(top_srcdir)/m4/readutmp.m4 \
- $(top_srcdir)/m4/regex.m4 \
- $(top_srcdir)/m4/rename-dest-slash.m4 \
- $(top_srcdir)/m4/rename.m4 $(top_srcdir)/m4/rmdir-errno.m4 \
- $(top_srcdir)/m4/rmdir.m4 $(top_srcdir)/m4/root-dev-ino.m4 \
- $(top_srcdir)/m4/rpmatch.m4 $(top_srcdir)/m4/safe-read.m4 \
- $(top_srcdir)/m4/safe-write.m4 $(top_srcdir)/m4/same.m4 \
- $(top_srcdir)/m4/save-cwd.m4 $(top_srcdir)/m4/savedir.m4 \
- $(top_srcdir)/m4/savewd.m4 $(top_srcdir)/m4/setenv.m4 \
- $(top_srcdir)/m4/settime.m4 $(top_srcdir)/m4/sha1.m4 \
- $(top_srcdir)/m4/sha256.m4 $(top_srcdir)/m4/sha512.m4 \
- $(top_srcdir)/m4/sig2str.m4 $(top_srcdir)/m4/snprintf.m4 \
- $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sockpfaf.m4 \
- $(top_srcdir)/m4/ssize_t.m4 $(top_srcdir)/m4/st_dm_mode.m4 \
- $(top_srcdir)/m4/stat-prog.m4 $(top_srcdir)/m4/stat-time.m4 \
- $(top_srcdir)/m4/stdarg.m4 $(top_srcdir)/m4/stdbool.m4 \
- $(top_srcdir)/m4/stdint.m4 $(top_srcdir)/m4/stdint_h.m4 \
- $(top_srcdir)/m4/stdio-safer.m4 $(top_srcdir)/m4/stdio_h.m4 \
- $(top_srcdir)/m4/stdlib-safer.m4 $(top_srcdir)/m4/stdlib_h.m4 \
- $(top_srcdir)/m4/stpcpy.m4 $(top_srcdir)/m4/strcspn.m4 \
- $(top_srcdir)/m4/strdup.m4 $(top_srcdir)/m4/strftime.m4 \
- $(top_srcdir)/m4/string_h.m4 $(top_srcdir)/m4/strndup.m4 \
- $(top_srcdir)/m4/strnlen.m4 $(top_srcdir)/m4/strnumcmp.m4 \
- $(top_srcdir)/m4/strpbrk.m4 $(top_srcdir)/m4/strtod.m4 \
- $(top_srcdir)/m4/strtoimax.m4 $(top_srcdir)/m4/strtol.m4 \
- $(top_srcdir)/m4/strtoll.m4 $(top_srcdir)/m4/strtoul.m4 \
- $(top_srcdir)/m4/strtoull.m4 $(top_srcdir)/m4/strtoumax.m4 \
- $(top_srcdir)/m4/strverscmp.m4 \
- $(top_srcdir)/m4/sys_socket_h.m4 \
- $(top_srcdir)/m4/sys_stat_h.m4 $(top_srcdir)/m4/sys_time_h.m4 \
- $(top_srcdir)/m4/tempname.m4 $(top_srcdir)/m4/time_h.m4 \
- $(top_srcdir)/m4/time_r.m4 $(top_srcdir)/m4/timespec.m4 \
- $(top_srcdir)/m4/tm_gmtoff.m4 $(top_srcdir)/m4/tzset.m4 \
- $(top_srcdir)/m4/unicodeio.m4 $(top_srcdir)/m4/unistd-safer.m4 \
- $(top_srcdir)/m4/unistd_h.m4 $(top_srcdir)/m4/unlink-busy.m4 \
- $(top_srcdir)/m4/unlinkdir.m4 $(top_srcdir)/m4/unlocked-io.m4 \
- $(top_srcdir)/m4/uptime.m4 $(top_srcdir)/m4/userspec.m4 \
- $(top_srcdir)/m4/utimbuf.m4 $(top_srcdir)/m4/utime.m4 \
- $(top_srcdir)/m4/utimecmp.m4 $(top_srcdir)/m4/utimens.m4 \
- $(top_srcdir)/m4/utimes-null.m4 $(top_srcdir)/m4/utimes.m4 \
- $(top_srcdir)/m4/vasnprintf.m4 $(top_srcdir)/m4/vasprintf.m4 \
- $(top_srcdir)/m4/wchar.m4 $(top_srcdir)/m4/wchar_t.m4 \
- $(top_srcdir)/m4/wctype.m4 $(top_srcdir)/m4/wcwidth.m4 \
- $(top_srcdir)/m4/wint_t.m4 $(top_srcdir)/m4/xalloc.m4 \
- $(top_srcdir)/m4/xfts.m4 $(top_srcdir)/m4/xgetcwd.m4 \
- $(top_srcdir)/m4/xnanosleep.m4 $(top_srcdir)/m4/xstrndup.m4 \
- $(top_srcdir)/m4/xstrtod.m4 $(top_srcdir)/m4/xstrtol.m4 \
- $(top_srcdir)/m4/yesno.m4 $(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
- $(ACLOCAL_M4)
-mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/lib/config.h
-CONFIG_CLEAN_FILES =
-SOURCES =
-DIST_SOURCES =
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ABSOLUTE_DIRENT_H = @ABSOLUTE_DIRENT_H@
-ABSOLUTE_FCNTL_H = @ABSOLUTE_FCNTL_H@
-ABSOLUTE_INTTYPES_H = @ABSOLUTE_INTTYPES_H@
-ABSOLUTE_NETINET_IN_H = @ABSOLUTE_NETINET_IN_H@
-ABSOLUTE_STDINT_H = @ABSOLUTE_STDINT_H@
-ABSOLUTE_STDIO_H = @ABSOLUTE_STDIO_H@
-ABSOLUTE_STDLIB_H = @ABSOLUTE_STDLIB_H@
-ABSOLUTE_STRING_H = @ABSOLUTE_STRING_H@
-ABSOLUTE_SYS_SOCKET_H = @ABSOLUTE_SYS_SOCKET_H@
-ABSOLUTE_SYS_STAT_H = @ABSOLUTE_SYS_STAT_H@
-ABSOLUTE_SYS_TIME_H = @ABSOLUTE_SYS_TIME_H@
-ABSOLUTE_TIME_H = @ABSOLUTE_TIME_H@
-ABSOLUTE_UNISTD_H = @ABSOLUTE_UNISTD_H@
-ABSOLUTE_WCHAR_H = @ABSOLUTE_WCHAR_H@
-ABSOLUTE_WCTYPE_H = @ABSOLUTE_WCTYPE_H@
-ACLOCAL = @ACLOCAL@
-ALLOCA = @ALLOCA@
-ALLOCA_H = @ALLOCA_H@
-AMTAR = @AMTAR@
-ARPA_INET_H = @ARPA_INET_H@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-BITSIZEOF_PTRDIFF_T = @BITSIZEOF_PTRDIFF_T@
-BITSIZEOF_SIG_ATOMIC_T = @BITSIZEOF_SIG_ATOMIC_T@
-BITSIZEOF_SIZE_T = @BITSIZEOF_SIZE_T@
-BITSIZEOF_WCHAR_T = @BITSIZEOF_WCHAR_T@
-BITSIZEOF_WINT_T = @BITSIZEOF_WINT_T@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
-CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DEFAULT_POSIX2_VERSION = @DEFAULT_POSIX2_VERSION@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-DF_PROG = @DF_PROG@
-DIRENT_H = @DIRENT_H@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EGREP = @EGREP@
-EOVERFLOW = @EOVERFLOW@
-EXEEXT = @EXEEXT@
-FCNTL_H = @FCNTL_H@
-FNMATCH_H = @FNMATCH_H@
-GETLOADAVG_LIBS = @GETLOADAVG_LIBS@
-GETOPT_H = @GETOPT_H@
-GLIBC21 = @GLIBC21@
-GMSGFMT = @GMSGFMT@
-GMSGFMT_015 = @GMSGFMT_015@
-GNULIB_CHOWN = @GNULIB_CHOWN@
-GNULIB_DUP2 = @GNULIB_DUP2@
-GNULIB_FCHDIR = @GNULIB_FCHDIR@
-GNULIB_FPRINTF_POSIX = @GNULIB_FPRINTF_POSIX@
-GNULIB_FTRUNCATE = @GNULIB_FTRUNCATE@
-GNULIB_GETCWD = @GNULIB_GETCWD@
-GNULIB_GETLOGIN_R = @GNULIB_GETLOGIN_R@
-GNULIB_GETSUBOPT = @GNULIB_GETSUBOPT@
-GNULIB_IMAXABS = @GNULIB_IMAXABS@
-GNULIB_IMAXDIV = @GNULIB_IMAXDIV@
-GNULIB_MBSCASECMP = @GNULIB_MBSCASECMP@
-GNULIB_MBSCASESTR = @GNULIB_MBSCASESTR@
-GNULIB_MBSCHR = @GNULIB_MBSCHR@
-GNULIB_MBSCSPN = @GNULIB_MBSCSPN@
-GNULIB_MBSLEN = @GNULIB_MBSLEN@
-GNULIB_MBSNCASECMP = @GNULIB_MBSNCASECMP@
-GNULIB_MBSPBRK = @GNULIB_MBSPBRK@
-GNULIB_MBSPCASECMP = @GNULIB_MBSPCASECMP@
-GNULIB_MBSRCHR = @GNULIB_MBSRCHR@
-GNULIB_MBSSEP = @GNULIB_MBSSEP@
-GNULIB_MBSSPN = @GNULIB_MBSSPN@
-GNULIB_MBSSTR = @GNULIB_MBSSTR@
-GNULIB_MBSTOK_R = @GNULIB_MBSTOK_R@
-GNULIB_MEMMEM = @GNULIB_MEMMEM@
-GNULIB_MEMPCPY = @GNULIB_MEMPCPY@
-GNULIB_MEMRCHR = @GNULIB_MEMRCHR@
-GNULIB_MKDTEMP = @GNULIB_MKDTEMP@
-GNULIB_MKSTEMP = @GNULIB_MKSTEMP@
-GNULIB_PRINTF_POSIX = @GNULIB_PRINTF_POSIX@
-GNULIB_READLINK = @GNULIB_READLINK@
-GNULIB_SNPRINTF = @GNULIB_SNPRINTF@
-GNULIB_SPRINTF_POSIX = @GNULIB_SPRINTF_POSIX@
-GNULIB_STPCPY = @GNULIB_STPCPY@
-GNULIB_STPNCPY = @GNULIB_STPNCPY@
-GNULIB_STRCASESTR = @GNULIB_STRCASESTR@
-GNULIB_STRCHRNUL = @GNULIB_STRCHRNUL@
-GNULIB_STRDUP = @GNULIB_STRDUP@
-GNULIB_STRNDUP = @GNULIB_STRNDUP@
-GNULIB_STRNLEN = @GNULIB_STRNLEN@
-GNULIB_STRPBRK = @GNULIB_STRPBRK@
-GNULIB_STRSEP = @GNULIB_STRSEP@
-GNULIB_STRTOIMAX = @GNULIB_STRTOIMAX@
-GNULIB_STRTOK_R = @GNULIB_STRTOK_R@
-GNULIB_STRTOUMAX = @GNULIB_STRTOUMAX@
-GNULIB_VFPRINTF_POSIX = @GNULIB_VFPRINTF_POSIX@
-GNULIB_VPRINTF_POSIX = @GNULIB_VPRINTF_POSIX@
-GNULIB_VSNPRINTF = @GNULIB_VSNPRINTF@
-GNULIB_VSPRINTF_POSIX = @GNULIB_VSPRINTF_POSIX@
-GNU_PACKAGE = @GNU_PACKAGE@
-GREP = @GREP@
-HAVE_DECL_GETLOGIN_R = @HAVE_DECL_GETLOGIN_R@
-HAVE_DECL_IMAXABS = @HAVE_DECL_IMAXABS@
-HAVE_DECL_IMAXDIV = @HAVE_DECL_IMAXDIV@
-HAVE_DECL_MEMMEM = @HAVE_DECL_MEMMEM@
-HAVE_DECL_MEMRCHR = @HAVE_DECL_MEMRCHR@
-HAVE_DECL_SNPRINTF = @HAVE_DECL_SNPRINTF@
-HAVE_DECL_STRDUP = @HAVE_DECL_STRDUP@
-HAVE_DECL_STRNCASECMP = @HAVE_DECL_STRNCASECMP@
-HAVE_DECL_STRNDUP = @HAVE_DECL_STRNDUP@
-HAVE_DECL_STRNLEN = @HAVE_DECL_STRNLEN@
-HAVE_DECL_STRTOIMAX = @HAVE_DECL_STRTOIMAX@
-HAVE_DECL_STRTOK_R = @HAVE_DECL_STRTOK_R@
-HAVE_DECL_STRTOUMAX = @HAVE_DECL_STRTOUMAX@
-HAVE_DECL_VSNPRINTF = @HAVE_DECL_VSNPRINTF@
-HAVE_DUP2 = @HAVE_DUP2@
-HAVE_FTRUNCATE = @HAVE_FTRUNCATE@
-HAVE_GETSUBOPT = @HAVE_GETSUBOPT@
-HAVE_INTTYPES_H = @HAVE_INTTYPES_H@
-HAVE_LONG_LONG_INT = @HAVE_LONG_LONG_INT@
-HAVE_MEMPCPY = @HAVE_MEMPCPY@
-HAVE_MKDTEMP = @HAVE_MKDTEMP@
-HAVE_NETINET_IN_H = @HAVE_NETINET_IN_H@
-HAVE_READLINK = @HAVE_READLINK@
-HAVE_SIGNED_SIG_ATOMIC_T = @HAVE_SIGNED_SIG_ATOMIC_T@
-HAVE_SIGNED_WCHAR_T = @HAVE_SIGNED_WCHAR_T@
-HAVE_SIGNED_WINT_T = @HAVE_SIGNED_WINT_T@
-HAVE_STDINT_H = @HAVE_STDINT_H@
-HAVE_STPCPY = @HAVE_STPCPY@
-HAVE_STPNCPY = @HAVE_STPNCPY@
-HAVE_STRCASECMP = @HAVE_STRCASECMP@
-HAVE_STRCASESTR = @HAVE_STRCASESTR@
-HAVE_STRCHRNUL = @HAVE_STRCHRNUL@
-HAVE_STRNDUP = @HAVE_STRNDUP@
-HAVE_STRPBRK = @HAVE_STRPBRK@
-HAVE_STRSEP = @HAVE_STRSEP@
-HAVE_STRUCT_TIMEVAL = @HAVE_STRUCT_TIMEVAL@
-HAVE_SYS_BITYPES_H = @HAVE_SYS_BITYPES_H@
-HAVE_SYS_INTTYPES_H = @HAVE_SYS_INTTYPES_H@
-HAVE_SYS_SOCKET_H = @HAVE_SYS_SOCKET_H@
-HAVE_SYS_TIME_H = @HAVE_SYS_TIME_H@
-HAVE_SYS_TYPES_H = @HAVE_SYS_TYPES_H@
-HAVE_UNISTD_H = @HAVE_UNISTD_H@
-HAVE_UNSIGNED_LONG_LONG_INT = @HAVE_UNSIGNED_LONG_LONG_INT@
-HAVE_WCTYPE_H = @HAVE_WCTYPE_H@
-HAVE_WINSOCK2_H = @HAVE_WINSOCK2_H@
-HAVE_WINT_T = @HAVE_WINT_T@
-HAVE_WS2TCPIP_H = @HAVE_WS2TCPIP_H@
-HAVE__BOOL = @HAVE__BOOL@
-HELP2MAN = @HELP2MAN@
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-INTLLIBS = @INTLLIBS@
-INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
-INTTYPES_H = @INTTYPES_H@
-KMEM_GROUP = @KMEM_GROUP@
-LDFLAGS = @LDFLAGS@
-LIBCOREUTILS_LIBDEPS = @LIBCOREUTILS_LIBDEPS@
-LIBCOREUTILS_LTLIBDEPS = @LIBCOREUTILS_LTLIBDEPS@
-LIBICONV = @LIBICONV@
-LIBINTL = @LIBINTL@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LIB_ACL = @LIB_ACL@
-LIB_ACL_TRIVIAL = @LIB_ACL_TRIVIAL@
-LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@
-LIB_CRYPT = @LIB_CRYPT@
-LIB_EACCESS = @LIB_EACCESS@
-LIB_FDATASYNC = @LIB_FDATASYNC@
-LIB_GETHRXTIME = @LIB_GETHRXTIME@
-LIB_NANOSLEEP = @LIB_NANOSLEEP@
-LN_S = @LN_S@
-LTLIBICONV = @LTLIBICONV@
-LTLIBINTL = @LTLIBINTL@
-LTLIBOBJS = @LTLIBOBJS@
-MAKEINFO = @MAKEINFO@
-MAN = @MAN@
-MKDIR_P = @MKDIR_P@
-MSGFMT = @MSGFMT@
-MSGFMT_015 = @MSGFMT_015@
-MSGMERGE = @MSGMERGE@
-NEED_SETGID = @NEED_SETGID@
-NETINET_IN_H = @NETINET_IN_H@
-OBJEXT = @OBJEXT@
-OPTIONAL_BIN_PROGS = @OPTIONAL_BIN_PROGS@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-PERL = @PERL@
-POSUB = @POSUB@
-POW_LIB = @POW_LIB@
-PRIPTR_PREFIX = @PRIPTR_PREFIX@
-PRI_MACROS_BROKEN = @PRI_MACROS_BROKEN@
-PTRDIFF_T_SUFFIX = @PTRDIFF_T_SUFFIX@
-RANLIB = @RANLIB@
-REPLACE_CHOWN = @REPLACE_CHOWN@
-REPLACE_FCHDIR = @REPLACE_FCHDIR@
-REPLACE_FPRINTF = @REPLACE_FPRINTF@
-REPLACE_GETCWD = @REPLACE_GETCWD@
-REPLACE_GETTIMEOFDAY = @REPLACE_GETTIMEOFDAY@
-REPLACE_LOCALTIME_R = @REPLACE_LOCALTIME_R@
-REPLACE_MKSTEMP = @REPLACE_MKSTEMP@
-REPLACE_NANOSLEEP = @REPLACE_NANOSLEEP@
-REPLACE_PRINTF = @REPLACE_PRINTF@
-REPLACE_SNPRINTF = @REPLACE_SNPRINTF@
-REPLACE_SPRINTF = @REPLACE_SPRINTF@
-REPLACE_STRPTIME = @REPLACE_STRPTIME@
-REPLACE_TIMEGM = @REPLACE_TIMEGM@
-REPLACE_VFPRINTF = @REPLACE_VFPRINTF@
-REPLACE_VPRINTF = @REPLACE_VPRINTF@
-REPLACE_VSNPRINTF = @REPLACE_VSNPRINTF@
-REPLACE_VSPRINTF = @REPLACE_VSPRINTF@
-SEQ_LIBM = @SEQ_LIBM@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-SIG_ATOMIC_T_SUFFIX = @SIG_ATOMIC_T_SUFFIX@
-SIZE_T_SUFFIX = @SIZE_T_SUFFIX@
-STDBOOL_H = @STDBOOL_H@
-STDINT_H = @STDINT_H@
-STRIP = @STRIP@
-SYS_SOCKET_H = @SYS_SOCKET_H@
-SYS_STAT_H = @SYS_STAT_H@
-SYS_TIME_H = @SYS_TIME_H@
-SYS_TIME_H_DEFINES_STRUCT_TIMESPEC = @SYS_TIME_H_DEFINES_STRUCT_TIMESPEC@
-TIME_H_DEFINES_STRUCT_TIMESPEC = @TIME_H_DEFINES_STRUCT_TIMESPEC@
-U = @U@
-USE_NLS = @USE_NLS@
-VERSION = @VERSION@
-WCHAR_H = @WCHAR_H@
-WCHAR_T_SUFFIX = @WCHAR_T_SUFFIX@
-WCTYPE_H = @WCTYPE_H@
-WINT_T_SUFFIX = @WINT_T_SUFFIX@
-XGETTEXT = @XGETTEXT@
-XGETTEXT_015 = @XGETTEXT_015@
-YACC = @YACC@
-YFLAGS = @YFLAGS@
-abs_builddir = @abs_builddir@
-abs_srcdir = @abs_srcdir@
-abs_top_builddir = @abs_top_builddir@
-abs_top_srcdir = @abs_top_srcdir@
-ac_ct_CC = @ac_ct_CC@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-bindir = @bindir@
-build = @build@
-build_alias = @build_alias@
-build_cpu = @build_cpu@
-build_os = @build_os@
-build_vendor = @build_vendor@
-builddir = @builddir@
-datadir = @datadir@
-datarootdir = @datarootdir@
-docdir = @docdir@
-dvidir = @dvidir@
-exec_prefix = @exec_prefix@
-gl_LIBOBJS = @gl_LIBOBJS@
-gl_LTLIBOBJS = @gl_LTLIBOBJS@
-host = @host@
-host_alias = @host_alias@
-host_cpu = @host_cpu@
-host_os = @host_os@
-host_vendor = @host_vendor@
-htmldir = @htmldir@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-libdir = @libdir@
-libexecdir = @libexecdir@
-localedir = @localedir@
-localstatedir = @localstatedir@
-mandir = @mandir@
-mkdir_p = @mkdir_p@
-oldincludedir = @oldincludedir@
-pdfdir = @pdfdir@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-psdir = @psdir@
-sbindir = @sbindir@
-sharedstatedir = @sharedstatedir@
-srcdir = @srcdir@
-sysconfdir = @sysconfdir@
-target_alias = @target_alias@
-top_builddir = @top_builddir@
-top_srcdir = @top_srcdir@
-EXTRA_DIST = $(TESTS)
-TESTS_ENVIRONMENT = \
- top_srcdir=$(top_srcdir) \
- srcdir=$(srcdir) \
- PERL="$(PERL)" \
- CU_TEST_NAME=`basename $(abs_srcdir)`,$$tst \
- PATH="$(VG_PATH_PREFIX)`pwd`/../../src$(PATH_SEPARATOR)$$PATH" \
- PROG=tail
-
-TESTS = \
- append-only \
- tail-n0f \
- big-4gb proc-ksyms start-middle assert assert-2
-
-all: all-am
-
-.SUFFIXES:
-$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
- @for dep in $?; do \
- case '$(am__configure_deps)' in \
- *$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
- exit 1;; \
- esac; \
- done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/tail-2/Makefile'; \
- cd $(top_srcdir) && \
- $(AUTOMAKE) --gnu tests/tail-2/Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
- @case '$?' in \
- *config.status*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
- *) \
- echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
- cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
- esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure: $(am__configure_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): $(am__aclocal_m4_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-tags: TAGS
-TAGS:
-
-ctags: CTAGS
-CTAGS:
-
-
-check-TESTS: $(TESTS)
- @failed=0; all=0; xfail=0; xpass=0; skip=0; ws='[ ]'; \
- srcdir=$(srcdir); export srcdir; \
- list=' $(TESTS) '; \
- if test -n "$$list"; then \
- for tst in $$list; do \
- if test -f ./$$tst; then dir=./; \
- elif test -f $$tst; then dir=; \
- else dir="$(srcdir)/"; fi; \
- if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
- all=`expr $$all + 1`; \
- case " $(XFAIL_TESTS) " in \
- *$$ws$$tst$$ws*) \
- xpass=`expr $$xpass + 1`; \
- failed=`expr $$failed + 1`; \
- echo "XPASS: $$tst"; \
- ;; \
- *) \
- echo "PASS: $$tst"; \
- ;; \
- esac; \
- elif test $$? -ne 77; then \
- all=`expr $$all + 1`; \
- case " $(XFAIL_TESTS) " in \
- *$$ws$$tst$$ws*) \
- xfail=`expr $$xfail + 1`; \
- echo "XFAIL: $$tst"; \
- ;; \
- *) \
- failed=`expr $$failed + 1`; \
- echo "FAIL: $$tst"; \
- ;; \
- esac; \
- else \
- skip=`expr $$skip + 1`; \
- echo "SKIP: $$tst"; \
- fi; \
- done; \
- if test "$$failed" -eq 0; then \
- if test "$$xfail" -eq 0; then \
- banner="All $$all tests passed"; \
- else \
- banner="All $$all tests behaved as expected ($$xfail expected failures)"; \
- fi; \
- else \
- if test "$$xpass" -eq 0; then \
- banner="$$failed of $$all tests failed"; \
- else \
- banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \
- fi; \
- fi; \
- dashes="$$banner"; \
- skipped=""; \
- if test "$$skip" -ne 0; then \
- skipped="($$skip tests were not run)"; \
- test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
- dashes="$$skipped"; \
- fi; \
- report=""; \
- if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
- report="Please report to $(PACKAGE_BUGREPORT)"; \
- test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
- dashes="$$report"; \
- fi; \
- dashes=`echo "$$dashes" | sed s/./=/g`; \
- echo "$$dashes"; \
- echo "$$banner"; \
- test -z "$$skipped" || echo "$$skipped"; \
- test -z "$$report" || echo "$$report"; \
- echo "$$dashes"; \
- test "$$failed" -eq 0; \
- else :; fi
-
-distdir: $(DISTFILES)
- @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- list='$(DISTFILES)'; \
- dist_files=`for file in $$list; do echo $$file; done | \
- sed -e "s|^$$srcdirstrip/||;t" \
- -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
- case $$dist_files in \
- */*) $(MKDIR_P) `echo "$$dist_files" | \
- sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
- sort -u` ;; \
- esac; \
- for file in $$dist_files; do \
- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
- if test -d $$d/$$file; then \
- dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
- fi; \
- cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
- else \
- test -f $(distdir)/$$file \
- || cp -p $$d/$$file $(distdir)/$$file \
- || exit 1; \
- fi; \
- done
-check-am: all-am
- $(MAKE) $(AM_MAKEFLAGS) check-TESTS
-check: check-am
-all-am: Makefile
-installdirs:
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- `test -z '$(STRIP)' || \
- echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
-mostlyclean-generic:
-
-clean-generic:
-
-distclean-generic:
- -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-
-maintainer-clean-generic:
- @echo "This command is intended for maintainers to use"
- @echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-generic mostlyclean-am
-
-distclean: distclean-am
- -rm -f Makefile
-distclean-am: clean-am distclean-generic
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-info: info-am
-
-info-am:
-
-install-data-am:
-
-install-dvi: install-dvi-am
-
-install-exec-am:
-
-install-html: install-html-am
-
-install-info: install-info-am
-
-install-man:
-
-install-pdf: install-pdf-am
-
-install-ps: install-ps-am
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
- -rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-generic
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am:
-
-.MAKE: install-am install-strip
-
-.PHONY: all all-am check check-TESTS check-am clean clean-generic \
- distclean distclean-generic distdir dvi dvi-am html html-am \
- info info-am install install-am install-data install-data-am \
- install-dvi install-dvi-am install-exec install-exec-am \
- install-html install-html-am install-info install-info-am \
- install-man install-pdf install-pdf-am install-ps \
- install-ps-am install-strip installcheck installcheck-am \
- installdirs maintainer-clean maintainer-clean-generic \
- mostlyclean mostlyclean-generic pdf pdf-am ps ps-am uninstall \
- uninstall-am
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/tests/tail-2/append-only b/tests/tail-2/append-only
deleted file mode 100755
index cee6644..0000000
--- a/tests/tail-2/append-only
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/bin/sh
-# Ensure that tail -f works on an append-only file
-# Requires root access to do chattr +a, as well as an ext[23] or xfs file system
-
-# Copyright (C) 2006 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 2 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.
-
-if test "$VERBOSE" = yes; then
- set -x
- tail --version
-fi
-
-PRIV_CHECK_ARG=require-root . $srcdir/../priv-check
-
-pwd=`pwd`
-t0=`echo "$0"|sed 's,.*/,,'`.tmp; tmp=$t0/$$
-trap 'status=$?; cd "$pwd" && chmod -R u+rwx $t0 && rm -rf $t0 && exit $status' 0
-trap '(exit $?); exit $?' 1 2 13 15
-
-framework_failure=0
-mkdir -p $tmp || framework_failure=1
-cd $tmp || framework_failure=1
-
-touch f
-chattr +a f 2>/dev/null || framework_failure=1
-( echo x > f ) 2>/dev/null && framework_failure=1
-echo x >> f || framework_failure=1
-
-if test $framework_failure = 1; then
- echo "$0: chattr +a doesn't work on this file system; skipping this test " 1>&2
- (exit 77); exit 77
-fi
-
-fail=0
-
-sleep 1 &
-pid=$!
-tail --pid=$pid -f f > /dev/null 2>&1 || fail=1
-chattr -a f 2>/dev/null
-
-(exit $fail); exit $fail
diff --git a/tests/tail-2/append-only.sh b/tests/tail-2/append-only.sh
new file mode 100755
index 0000000..42a3197
--- /dev/null
+++ b/tests/tail-2/append-only.sh
@@ -0,0 +1,46 @@
+#!/bin/sh
+# Ensure that tail -f works on an append-only file
+# Requires root access to do chattr +a, as well as an ext[23] or xfs file system
+
+# Copyright (C) 2006-2016 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 <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ tail
+require_root_
+
+# Terminate any background tail process
+cleanup_() { kill $pid 2>/dev/null && wait $pid; }
+
+chattr_a_works=1
+touch f
+chattr +a f 2>/dev/null || chattr_a_works=0
+( echo x > f ) 2>/dev/null && chattr_a_works=0
+echo x >> f || chattr_a_works=0
+
+if test $chattr_a_works = 0; then
+ skip_ "chattr +a doesn't work on this file system"
+fi
+
+
+for mode in '' '---disable-inotify'; do
+ sleep 1 & pid=$!
+ tail --pid=$pid -f $mode f || fail=1
+ cleanup_
+done
+
+chattr -a f 2>/dev/null
+
+Exit $fail
diff --git a/tests/tail-2/assert b/tests/tail-2/assert
deleted file mode 100755
index b94a6ba..0000000
--- a/tests/tail-2/assert
+++ /dev/null
@@ -1,78 +0,0 @@
-#!/bin/sh
-# Test for assertion failure in "test".
-
-# Copyright (C) 1999, 2000, 2004, 2006 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 2 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.
-
-
-# This test fails with tail from textutils-2.0.
-# It would get something like this:
-# tail: tail.c:718: recheck: Assertion `valid_file_spec (f)' failed.
-# Aborted
-# due to a race condition in which a dev/inode pair is reused.
-
-if test "$VERBOSE" = yes; then
- set -x
- tail --version
-fi
-
-# Not "expensive" per se, but sleeping for so long is annoying.
-. $srcdir/../very-expensive
-
-tmp=tail-assert.$$
-pwd=`pwd`
-trap 'cd "$pwd" && rm -rf $tmp' 0 1 2 3 15
-
-test_failure=0
-mkdir $tmp || test_failure=1
-cd $tmp || test_failure=1
-
-if test $test_failure = 1; then
- echo 'failure in testing framework'
- exit 1
-fi
-
-ok='ok ok ok'
-
-touch a foo
-tail --follow=name a foo > err 2>&1 &
-tail_pid=$!
-# Arrange for the tail process to die after 12 seconds.
-(sleep 12; kill $tail_pid) &
-
-echo sleeping for 7 seconds...
-
-# Give the backgrounded `tail' a chance to start before removing foo.
-# Otherwise, without --retry, tail wouldn't try to open `foo' again.
-sleep 1
-
-rm -f foo
-sleep 6
-echo $ok > f
-mv f foo
-
-# echo waiting....
-wait
-
-case "`cat err`" in
- *$ok) fail=0;;
- *) fail=1;;
-esac
-
-test $fail = 1 && cat err
-
-exit $fail
diff --git a/tests/tail-2/assert-2 b/tests/tail-2/assert-2
deleted file mode 100755
index f535758..0000000
--- a/tests/tail-2/assert-2
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/bin/sh
-# This variant of `assert' would get a UMR reliably in 2.0.9.
-# Due to a race condition in the test, the `assert' script would get
-# the UMR on Solaris only some of the time, and not at all on Linux/GNU.
-
-# Copyright (C) 2000, 2006 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 2 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.
-
-if test "$VERBOSE" = yes; then
- set -x
- tail --version
-fi
-
-# Not "expensive" per se, but sleeping for so long is annoying.
-. $srcdir/../very-expensive
-
-tmp=tail-as2.$$
-pwd=`pwd`
-trap 'cd "$pwd" && rm -rf $tmp' 0 1 2 3 15
-
-test_failure=0
-mkdir $tmp || test_failure=1
-cd $tmp || test_failure=1
-
-if test $test_failure = 1; then
- echo 'failure in testing framework'
- exit 1
-fi
-
-ok='ok ok ok'
-
-touch a
-tail --follow=name a foo > err 2>&1 &
-tail_pid=$!
-# Arrange for the tail process to die after 12 seconds.
-(sleep 12; kill $tail_pid) &
-echo $ok > f
-echo sleeping for 7 seconds...
-sleep 7
-mv f foo
-
-# echo waiting....
-wait
-
-case "`cat err`" in
- *$ok) fail=0;;
- *) fail=1;;
-esac
-
-test $fail = 1 && cat err
-
-exit $fail
diff --git a/tests/tail-2/assert-2.sh b/tests/tail-2/assert-2.sh
new file mode 100755
index 0000000..79d4254
--- /dev/null
+++ b/tests/tail-2/assert-2.sh
@@ -0,0 +1,57 @@
+#!/bin/sh
+# This variant of 'assert' would get a Uninit Mem Read reliably in 2.0.9.
+# Due to a race condition in the test, the 'assert' script would get
+# the UMR on Solaris only some of the time, and not at all on Linux/GNU.
+
+# Copyright (C) 2000-2016 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 <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ tail
+
+check_tail_output()
+{
+ local delay="$1"
+ grep "$tail_re" out ||
+ { sleep $delay; return 1; }
+}
+
+# Terminate any background tail process
+cleanup_() { kill $pid 2>/dev/null && wait $pid; }
+
+# Speedup the non inotify case
+fastpoll='-s.1 --max-unchanged-stats=1'
+
+for mode in '' '---disable-inotify'; do
+ rm -f a foo out
+ touch a || framework_failure_
+
+ tail $mode --follow=name $fastpoll a foo > out 2>&1 & pid=$!
+
+ # Wait up to 12.7s for tail to start.
+ echo x > a || framework_failure_
+ tail_re='^x$' retry_delay_ check_tail_output .1 7 ||
+ { cat out; fail=1; break; }
+
+ # Wait up to 12.7s for tail to notice new foo file
+ ok='ok ok ok'
+ echo "$ok" > foo || framework_failure_
+ tail_re="^$ok$" retry_delay_ check_tail_output .1 7 ||
+ { echo "$0: foo: unexpected delay?"; cat out; fail=1; break; }
+
+ cleanup_
+done
+
+Exit $fail
diff --git a/tests/tail-2/assert.sh b/tests/tail-2/assert.sh
new file mode 100755
index 0000000..c5f3703
--- /dev/null
+++ b/tests/tail-2/assert.sh
@@ -0,0 +1,68 @@
+#!/bin/sh
+# Test for assertion failure in "test".
+
+# Copyright (C) 1999-2016 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 <http://www.gnu.org/licenses/>.
+
+
+# This test fails with tail from textutils-2.0.
+# It would get something like this:
+# tail: tail.c:718: recheck: Assertion 'valid_file_spec (f)' failed.
+# Aborted
+# due to a race condition in which a dev/inode pair is reused.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ tail
+
+check_tail_output()
+{
+ local delay="$1"
+ grep "$tail_re" out ||
+ { sleep $delay; return 1; }
+}
+
+# Terminate any background tail process
+cleanup_() { kill $pid 2>/dev/null && wait $pid; }
+
+# Speedup the non inotify case
+fastpoll='-s.1 --max-unchanged-stats=1'
+
+for mode in '' '---disable-inotify'; do
+ rm -f a foo out
+ touch a foo || framework_failure_
+
+ tail $mode --follow=name $fastpoll a foo > out 2>&1 & pid=$!
+
+ # Wait up to 12.7s for tail to start.
+ echo x > a || framework_failure_
+ tail_re='^x$' retry_delay_ check_tail_output .1 7 ||
+ { cat out; fail=1; break; }
+
+ # Wait 12.7s for this diagnostic:
+ # tail: foo: No such file or directory
+ rm foo || framework_failure_
+ tail_re='No such file' retry_delay_ check_tail_output .1 7 ||
+ { cat out; fail=1; break; }
+
+ # Wait up to 12.7s for tail to notice new foo file
+ ok='ok ok ok'
+ echo "$ok" > foo || framework_failure_
+ tail_re="^$ok$" retry_delay_ check_tail_output .1 7 ||
+ { echo "$0: foo: unexpected delay?"; cat out; fail=1; break; }
+
+ cleanup_
+done
+
+Exit $fail
diff --git a/tests/tail-2/big-4gb b/tests/tail-2/big-4gb
deleted file mode 100755
index b0ca79d..0000000
--- a/tests/tail-2/big-4gb
+++ /dev/null
@@ -1,71 +0,0 @@
-#!/bin/sh
-# Demonstrate a bug in `tail -cN' when operating on files of size 4G and larger
-# Fixed in coreutils-4.5.2.
-
-# Copyright (C) 2002, 2003, 2006 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 2 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.
-
-. $srcdir/../expensive
-
-if test "$VERBOSE" = yes; then
- set -x
- tail --version
-fi
-
-pwd=`pwd`
-t0=`echo "$0"|sed 's,.*/,,'`.tmp; tmp=$t0/$$
-trap 'status=$?; cd "$pwd" && chmod -R u+rwx $t0 && rm -rf $t0 && exit $status' 0
-trap '(exit $?); exit $?' 1 2 13 15
-
-framework_failure=0
-mkdir -p $tmp || framework_failure=1
-cd $tmp || framework_failure=1
-
-# Create a file of size exactly 4GB (2^32) with 8 bytes
-# at the beginning and another set of 8 bytes at the end.
-# The rest will be NUL bytes. On most modern systems, the following
-# creates a file that takes up only a few KB. Here, du -sh says 16K.
-echo abcdefgh | tr -d '\n' > big || framework_failure=1
-echo 87654321 | tr -d '\n' > tmp || framework_failure=1
-# Seek 4GB - 8
-dd bs=1 seek=4294967288 if=tmp of=big 2> err || dd_failed=1
-if test "$dd_failed" = 1; then
- cat err 1>&2
- echo "$0: cannot create a file large enough for this test," 1>&2
- echo "$0: possibly because this system doesn't support large files;" 1>&2
- echo "$0: Consider rerunning this test on a different file system." 1>&2
- (exit 77); exit 77
-fi
-
-if test $framework_failure = 1; then
- echo "$0: failure in testing framework" 1>&2
- (exit 1); exit 1
-fi
-
-fail=0
-
-tail -c1 big > out || fail=1
-# Append a newline.
-echo >> out
-cat <<\EOF > exp
-1
-EOF
-
-cmp out exp || fail=1
-test $fail = 1 && diff out exp 2> /dev/null
-
-(exit $fail); exit $fail
diff --git a/tests/tail-2/big-4gb.sh b/tests/tail-2/big-4gb.sh
new file mode 100755
index 0000000..9c96725
--- /dev/null
+++ b/tests/tail-2/big-4gb.sh
@@ -0,0 +1,50 @@
+#!/bin/sh
+# Demonstrate a bug in 'tail -cN' when operating on files of size 4G and larger
+# Fixed in coreutils-4.5.2.
+
+# Copyright (C) 2002-2016 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 <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ tail
+expensive_
+
+# Create a file of size exactly 4GB (2^32) with 8 bytes
+# at the beginning and another set of 8 bytes at the end.
+# The rest will be NUL bytes. On most modern systems, the following
+# creates a file that takes up only a few KB. Here, du -sh says 16K.
+echo abcdefgh | tr -d '\n' > big || framework_failure_
+echo 87654321 | tr -d '\n' > tmp || framework_failure_
+# Seek 4GB - 8
+dd bs=1 seek=4294967288 if=tmp of=big 2> err || dd_failed=1
+if test "$dd_failed" = 1; then
+ cat err 1>&2
+ skip_ \
+'cannot create a file large enough for this test,
+possibly because this system does not support large files;
+Consider rerunning this test on a different file system.'
+fi
+
+
+tail -c1 big > out || fail=1
+# Append a newline.
+echo >> out
+cat <<\EOF > exp
+1
+EOF
+
+compare exp out || fail=1
+
+Exit $fail
diff --git a/tests/tail-2/descriptor-vs-rename.sh b/tests/tail-2/descriptor-vs-rename.sh
new file mode 100755
index 0000000..595013c
--- /dev/null
+++ b/tests/tail-2/descriptor-vs-rename.sh
@@ -0,0 +1,56 @@
+#!/bin/sh
+# Demonstrate that tail -f works when renaming the tailed files.
+# Between coreutils 7.5 and 8.23 inclusive, 'tail -f a' would
+# stop tracking additions to b after 'mv a b'.
+
+# Copyright (C) 2015-2016 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 <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ tail
+
+check_tail_output()
+{
+ local delay="$1"
+ grep "$tail_re" out ||
+ { sleep $delay; return 1; }
+}
+
+# Terminate any background tail process
+cleanup_() { kill $pid 2>/dev/null && wait $pid; }
+
+# Speedup the non inotify case
+fastpoll='-s.1 --max-unchanged-stats=1'
+
+for mode in '' '---disable-inotify'; do
+ rm -f a out
+ touch a || framework_failure_
+
+ tail $mode $fastpoll -f a > out 2>&1 & pid=$!
+
+ # Wait up to 12.7s for tail to start.
+ echo x > a
+ tail_re='^x$' retry_delay_ check_tail_output .1 7 || { cat out; fail=1; }
+
+ mv a b || framework_failure_
+
+ echo y >> b
+ # Wait up to 12.7s for "y" to appear in the output:
+ tail_re='^y$' retry_delay_ check_tail_output .1 7 || { cat out; fail=1; }
+
+ cleanup_
+done
+
+Exit $fail
diff --git a/tests/tail-2/flush-initial.sh b/tests/tail-2/flush-initial.sh
new file mode 100755
index 0000000..803502a
--- /dev/null
+++ b/tests/tail-2/flush-initial.sh
@@ -0,0 +1,44 @@
+#!/bin/sh
+# inotify-based tail -f didn't flush its initial output before blocking
+
+# Copyright (C) 2009-2016 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 <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ tail
+
+# Speedup the non inotify case
+fastpoll='-s.1 --max-unchanged-stats=1'
+
+# Terminate any background tail process
+cleanup_() { kill $pid 2>/dev/null && wait $pid; }
+
+echo line > in || framework_failure_
+# Output should be buffered since we're writing to file
+# so we're depending on the flush to write out
+tail $fastpoll -f in > out & pid=$!
+
+# Wait for 3.1s for the file to be flushed.
+tail_flush()
+{
+ local delay="$1"
+ sleep $delay
+ test -s out
+}
+retry_delay_ tail_flush .1 5 || fail=1
+
+cleanup_
+
+Exit $fail
diff --git a/tests/tail-2/follow-name.sh b/tests/tail-2/follow-name.sh
new file mode 100755
index 0000000..ea5c5d9
--- /dev/null
+++ b/tests/tail-2/follow-name.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+# ensure that --follow=name does not imply --retry
+
+# Copyright (C) 2011-2016 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 <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ tail
+
+cat <<\EOF > exp || framework_failure_
+tail: cannot open 'no-such' for reading: No such file or directory
+tail: no files remaining
+EOF
+
+timeout 10 tail --follow=name no-such > out 2> err
+test $? = 1 || fail=1
+
+# Remove an inconsequential inotify warning so
+# we can compare against the above error
+sed '/inotify cannot be used/d' err > k && mv k err
+
+compare exp err || fail=1
+
+Exit $fail
diff --git a/tests/tail-2/follow-stdin.sh b/tests/tail-2/follow-stdin.sh
new file mode 100755
index 0000000..a2f1804
--- /dev/null
+++ b/tests/tail-2/follow-stdin.sh
@@ -0,0 +1,53 @@
+#!/bin/sh
+# tail -f - would fail with the initial inotify implementation
+
+# Copyright (C) 2009-2016 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 <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ tail
+
+check_tail_output()
+{
+ local delay="$1"
+ grep "$tail_re" out ||
+ { sleep $delay; return 1; }
+}
+
+# Terminate any background tail process
+cleanup_() { kill $pid 2>/dev/null && wait $pid; }
+
+# Speedup the non inotify case
+fastpoll='-s.1 --max-unchanged-stats=1'
+
+echo line > in || framework_failure_
+echo line > exp || framework_failure_
+
+for mode in '' '---disable-inotify'; do
+ > out || framework_failure_
+
+ tail $mode -f $fastpoll < in > out 2> err & pid=$!
+
+ # Wait up to 12.7s for output to appear:
+ tail_re='line' retry_delay_ check_tail_output .1 7 ||
+ { echo "$0: a: unexpected delay?"; cat out; fail=1; }
+
+ # Ensure there was no error output.
+ compare /dev/null err || fail=1
+
+ cleanup_
+done
+
+Exit $fail
diff --git a/tests/tail-2/inotify-hash-abuse.sh b/tests/tail-2/inotify-hash-abuse.sh
new file mode 100755
index 0000000..ae86349
--- /dev/null
+++ b/tests/tail-2/inotify-hash-abuse.sh
@@ -0,0 +1,71 @@
+#!/bin/sh
+# Exercise an abort-inducing flaw in inotify-enabled tail -F.
+
+# Copyright (C) 2009-2016 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 <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ tail
+
+# 9 is a magic number, related to internal details of tail.c and hash.c
+n=9
+seq $n | xargs touch || framework_failure_
+
+check_tail_output()
+{
+ local delay="$1"
+ grep "$tail_re" out > /dev/null ||
+ { sleep $delay; return 1; }
+}
+
+# Terminate any background tail process
+cleanup_() { kill $pid 2>/dev/null && wait $pid; }
+
+# Speedup the non inotify case
+fastpoll='-s.1 --max-unchanged-stats=1'
+
+for mode in '' '---disable-inotify'; do
+ rm -f out
+
+ tail $mode $fastpoll -qF $(seq $n) > out 2>&1 & pid=$!
+
+ # Wait up to 12.7s for tail to start
+ echo x > $n
+ tail_re='^x$' retry_delay_ check_tail_output .1 7 ||
+ { cat out; fail=1; }
+
+ mv 1 f || framework_failure_
+
+ # Wait 12.7s for this diagnostic:
+ # tail: '1' has become inaccessible: No such file or directory
+ tail_re='inaccessible' retry_delay_ check_tail_output .1 7 ||
+ { cat out; fail=1; }
+
+ # Trigger the bug. Before the fix, this would provoke the abort.
+ echo a > 1 || framework_failure_
+
+ # Wait up to 6.3s for the "tail: '1' has appeared; ..." message
+ # (or for the buggy tail to die)
+ tail_re='has appeared' retry_delay_ check_tail_output .1 6 ||
+ { cat out; fail=1; }
+
+ # Double check that tail hasn't aborted
+ kill -0 $pid || fail=1
+
+ cleanup_
+done
+
+
+Exit $fail
diff --git a/tests/tail-2/inotify-hash-abuse2.sh b/tests/tail-2/inotify-hash-abuse2.sh
new file mode 100755
index 0000000..b7fa584
--- /dev/null
+++ b/tests/tail-2/inotify-hash-abuse2.sh
@@ -0,0 +1,46 @@
+#!/bin/sh
+# Exercise an abort-inducing flaw in inotify-enabled tail -F.
+# Like inotify-hash-abuse, but without a hard-coded "9".
+
+# Copyright (C) 2009-2016 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 <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ tail
+
+# Terminate any background tail process
+cleanup_() { kill $pid 2>/dev/null && wait $pid; }
+
+# Speedup the non inotify case
+fastpoll='-s.1 --max-unchanged-stats=1'
+
+for mode in '' '---disable-inotify'; do
+ touch f || framework_failure_
+
+ tail $mode $fastpoll -F f & pid=$!
+
+ for i in $(seq 200); do
+ kill -0 $pid || break;
+ mv f g
+ touch f
+ done
+
+ # Ensure tail hasn't aborted
+ kill -0 $pid || fail=1
+
+ cleanup_
+done
+
+Exit $fail
diff --git a/tests/tail-2/inotify-race.sh b/tests/tail-2/inotify-race.sh
new file mode 100755
index 0000000..75acca4
--- /dev/null
+++ b/tests/tail-2/inotify-race.sh
@@ -0,0 +1,98 @@
+#!/bin/sh
+# Ensure that tail does not ignore data that is appended to a tailed-forever
+# file between tail's initial read-to-EOF, and when the inotify watches
+# are established in tail_forever_inotify. That data could be ignored
+# indefinitely if no *other* data is appended, but it would be printed as
+# soon as any additional appended data is detected.
+
+# Copyright (C) 2009-2016 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 <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ tail sleep
+
+# Terminate any background gdb/tail process
+cleanup_() {
+ kill $pid 2>/dev/null && wait $pid
+ kill $sleep 2>/dev/null && wait $sleep
+}
+
+touch file || framework_failure_
+touch tail.out || framework_failure_
+
+( timeout 10s gdb --version ) > gdb.out 2>&1
+case $(cat gdb.out) in
+ *'GNU gdb'*) ;;
+ *) skip_ "can't run gdb";;
+esac
+
+# Break on a line rather than a symbol, to cater for inline functions
+break_src="$abs_top_srcdir/src/tail.c"
+break_line=$(grep -n ^tail_forever_inotify "$break_src") || framework_failure_
+break_line=$(echo "$break_line" | cut -d: -f1) || framework_failure_
+
+
+# Note we get tail to monitor a background sleep process
+# rather than using timeout(1), as timeout sends SIGCONT
+# signals to its monitored process, and gdb (7.9 at least)
+# has _intermittent_ issues with this.
+# Sending SIGCONT resulted in either delayed child termination,
+# or no child termination resulting in a hung test.
+# See https://sourceware.org/bugzilla/show_bug.cgi?id=18364
+
+env sleep 10 & sleep=$!
+
+# See if gdb works and
+# tail_forever_inotify is compiled and run
+gdb -nx --batch-silent \
+ --eval-command="break $break_line" \
+ --eval-command="run --pid=$sleep -f file" \
+ --eval-command='quit' \
+ tail < /dev/null > gdb.out 2>&1
+
+kill $sleep || skip_ 'breakpoint not hit'
+wait $sleep
+
+# FIXME: The above is seen to _intermittently_ fail with:
+# warning: .dynamic section for "/lib/libc.so.6" is not at the expected address
+# warning: difference appears to be caused by prelink, adjusting expectations
+compare /dev/null gdb.out || skip_ "can't set breakpoints in tail"
+
+env sleep 10 & sleep=$!
+
+# Run "tail -f file", stopping to append a line just before
+# inotify initialization, and then continue. Before the fix,
+# that just-appended line would never be output.
+gdb -nx --batch-silent \
+ --eval-command="break $break_line" \
+ --eval-command="run --pid=$sleep -f file >> tail.out" \
+ --eval-command='shell echo never-seen-with-tail-7.5 >> file' \
+ --eval-command='continue' \
+ --eval-command='quit' \
+ tail < /dev/null > /dev/null 2>&1 & pid=$!
+
+tail --pid=$pid -f tail.out | (read REPLY; kill $pid)
+
+# gdb has a bug in Debian's gdb-6.8-3 at least that causes it to not
+# cleanup and exit correctly when it receives a SIGTERM, but
+# killing sleep, should cause the tail process and thus gdb to exit.
+kill $sleep
+wait $sleep
+
+wait $pid
+
+compare /dev/null tail.out && fail=1
+
+Exit $fail
diff --git a/tests/tail-2/inotify-race2.sh b/tests/tail-2/inotify-race2.sh
new file mode 100755
index 0000000..9b4eeb6
--- /dev/null
+++ b/tests/tail-2/inotify-race2.sh
@@ -0,0 +1,103 @@
+#!/bin/sh
+# Ensure that tail does not ignore a tailed-forever file that has been
+# replaced between tail's initial read-to-EOF, and when the inotify watches
+# are established in tail_forever_inotify. That new file would be ignored
+# indefinitely.
+
+# Copyright (C) 2015-2016 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 <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ tail sleep
+
+# Terminate any background gdb/tail process
+cleanup_() {
+ kill $pid 2>/dev/null && wait $pid
+ kill $sleep 2>/dev/null && wait $sleep
+}
+
+touch file || framework_failure_
+touch tail.out || framework_failure_
+
+( timeout 10s gdb --version ) > gdb.out 2>&1
+case $(cat gdb.out) in
+ *'GNU gdb'*) ;;
+ *) skip_ "can't run gdb";;
+esac
+
+# Break on a line rather than a symbol, to cater for inline functions
+break_src="$abs_top_srcdir/src/tail.c"
+break_line=$(grep -n ^tail_forever_inotify "$break_src") || framework_failure_
+break_line=$(echo "$break_line" | cut -d: -f1) || framework_failure_
+
+
+# Note we get tail to monitor a background sleep process
+# rather than using timeout(1), as timeout sends SIGCONT
+# signals to its monitored process, and gdb (7.9 at least)
+# has _intermittent_ issues with this.
+# Sending SIGCONT resulted in either delayed child termination,
+# or no child termination resulting in a hung test.
+# See https://sourceware.org/bugzilla/show_bug.cgi?id=18364
+
+env sleep 10 & sleep=$!
+
+# See if gdb works and
+# tail_forever_inotify is compiled and run
+gdb -nx --batch-silent \
+ --eval-command="break $break_line" \
+ --eval-command="run --pid=$sleep -f file" \
+ --eval-command='quit' \
+ tail < /dev/null > gdb.out 2>&1
+
+kill $sleep || skip_ 'breakpoint not hit'
+wait $sleep
+
+# FIXME: The above is seen to _intermittently_ fail with:
+# warning: .dynamic section for "/lib/libc.so.6" is not at the expected address
+# warning: difference appears to be caused by prelink, adjusting expectations
+compare /dev/null gdb.out || skip_ "can't set breakpoints in tail"
+
+env sleep 10 & sleep=$!
+
+echo never-seen-with-tail-8.23 > file.new || framework_failure_
+
+# Run "tail -F file", stopping to replace with a new file before
+# inotify initialization, and then continue. Before the fix,
+# changes to the new file would effectively be ignored.
+gdb -nx --batch-silent \
+ --eval-command="break $break_line" \
+ --eval-command="run --pid=$sleep -F file 2>tail.err >>tail.out" \
+ --eval-command='shell mv file.new file' \
+ --eval-command='continue' \
+ --eval-command='quit' \
+ tail < /dev/null > /dev/null 2>&1 & pid=$!
+
+# Note even updating the watched 'file' wouldn't have output
+# anything between coreutils 7.5 and 8.23 inclusive as
+# The old file descriptor (still held open by tail) was being fstat().
+
+tail --pid=$pid -f tail.out | (read REPLY; kill $pid)
+
+# gdb has a bug in Debian's gdb-6.8-3 at least that causes it to not
+# cleanup and exit correctly when it receives a SIGTERM, but
+# killing sleep, should cause the tail process and thus gdb to exit.
+kill $sleep
+wait $sleep
+
+wait $pid
+
+compare /dev/null tail.out && { cat tail.err; fail=1; }
+
+Exit $fail
diff --git a/tests/tail-2/inotify-rotate-resources.sh b/tests/tail-2/inotify-rotate-resources.sh
new file mode 100755
index 0000000..5b88202
--- /dev/null
+++ b/tests/tail-2/inotify-rotate-resources.sh
@@ -0,0 +1,108 @@
+#!/bin/sh
+# ensure that tail -F doesn't leak inotify resources
+
+# Copyright (C) 2015-2016 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 <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ tail
+
+grep '^#define HAVE_INOTIFY 1' "$CONFIG_HEADER" >/dev/null \
+ || skip_ 'inotify required'
+
+require_strace_ 'inotify_add_watch,inotify_rm_watch'
+
+# Quickly skip on remote file systems
+is_local_dir_ . || skip_ 'inotify not used on remote file system'
+
+check_tail_output()
+{
+ local delay="$1"
+ grep "$tail_re" out > /dev/null ||
+ { sleep $delay; return 1; }
+}
+
+# Wait up to 25.5 seconds for grep REGEXP 'out' to succeed.
+grep_timeout() { tail_re="$1" retry_delay_ check_tail_output .1 8; }
+
+check_strace()
+{
+ local delay="$1"
+ grep "$strace_re" strace.out > /dev/null ||
+ { sleep $delay; return 1; }
+}
+
+cleanup_fail()
+{
+ cat out
+ warn_ $1
+ fail=1
+}
+
+# Terminate any background tail process
+cleanup_() { kill $pid 2>/dev/null && wait $pid; }
+
+fastpoll='-s.1 --max-unchanged-stats=1'
+
+touch k || framework_failure_
+
+# Note the timeout guard isn't strictly necessary here,
+# however without it strace will ignore SIGTERM.
+# strace does always honor SIGTERM with the -I2 option,
+# though that's not available on RHEL6 for example.
+timeout 180 strace -e inotify_add_watch,inotify_rm_watch -o strace.out \
+ tail -F $fastpoll k >> out 2>&1 & pid=$!
+
+reverted_to_polling_=0
+for i in $(seq 2); do
+ echo $i
+
+ echo 'tailed' > k;
+
+ # Wait for watch on (new) file
+ strace_re='inotify_add_watch.*MODIFY' retry_delay_ check_strace .1 8 ||
+ no_watch_=1
+
+ # Assume this is not because we're leaking
+ # (resources may already be depleted)
+ # The explicit check for inotify_rm_watch should confirm that.
+ grep -F 'reverting to polling' out >/dev/null && skip_ 'inotify unused'
+
+ # Otherwise failure is unknown
+ test "$no_watch_" && { cat out; framework_failure_ 'no inotify_add_watch'; }
+
+ mv k k.tmp
+ # wait for tail to detect the rename
+ grep_timeout 'inaccessible' ||
+ { cleanup_fail 'failed to detect rename'; break; }
+
+ # Note we strace here rather than consuming all available watches
+ # to be more efficient, but more importantly avoid depleting resources.
+ # Note also available resources can currently be tuned with:
+ # sudo sysctl -w fs.inotify.max_user_watches=$smallish_number
+ # However that impacts all processes for the current user, and also
+ # may not be supported in future, instead being auto scaled to RAM
+ # like the Linux epoll resources were.
+ if test "$i" -gt 1; then
+ strace_re='inotify_rm_watch' retry_delay_ check_strace .1 8 ||
+ { cleanup_fail 'failed to find inotify_rm_watch syscall'; break; }
+ fi
+
+ >out && >strace.out || framework_failure_ 'failed to reset output files'
+done
+
+cleanup_
+
+Exit $fail
diff --git a/tests/tail-2/inotify-rotate.sh b/tests/tail-2/inotify-rotate.sh
new file mode 100755
index 0000000..302c33c
--- /dev/null
+++ b/tests/tail-2/inotify-rotate.sh
@@ -0,0 +1,77 @@
+#!/bin/sh
+# ensure that tail -F handles rotation
+
+# Copyright (C) 2009-2016 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 <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ tail
+
+grep '^#define HAVE_INOTIFY 1' "$CONFIG_HEADER" >/dev/null \
+ || expensive_
+
+check_tail_output()
+{
+ local delay="$1"
+ grep "$tail_re" out > /dev/null ||
+ { sleep $delay; return 1; }
+}
+
+# Wait up to 25.5 seconds for grep REGEXP 'out' to succeed.
+grep_timeout() { tail_re="$1" retry_delay_ check_tail_output .1 8; }
+
+# Terminate any background tail process
+cleanup_() { kill $pid 2>/dev/null && wait $pid; }
+
+cleanup_fail()
+{
+ cat out
+ warn_ $1
+ cleanup_
+ fail=1
+}
+
+# Speedup the non inotify case
+fastpoll='-s.1 --max-unchanged-stats=1'
+
+# Perform at least this many iterations, because on multi-core systems
+# the offending sequence of events can be surprisingly uncommon.
+# See: http://lists.gnu.org/archive/html/bug-coreutils/2009-11/msg00213.html
+for i in $(seq 50); do
+ echo $i
+ rm -f k x out
+
+ # Normally less than a second is required here, but with heavy load
+ # and a lot of disk activity, even 20 seconds is insufficient, which
+ # leads to this timeout killing tail before the "ok" is written below.
+ >k && >x || framework_failure_ failed to initialize files
+ timeout 60 tail $fastpoll -F k > out 2>&1 & pid=$!
+
+ echo 'tailed' > k;
+ # wait for 'tailed' to appear in out
+ grep_timeout 'tailed' || { cleanup_fail 'failed to find "tailed"'; break; }
+
+ mv x k
+ # wait for tail to detect the rename
+ grep_timeout 'tail:' || { cleanup_fail 'failed to detect rename'; break; }
+
+ echo ok >> k
+ # wait for "ok" to appear in 'out'
+ grep_timeout 'ok' || { cleanup_fail 'failed to detect echoed ok'; break; }
+
+ cleanup_
+done
+
+Exit $fail
diff --git a/tests/tail-2/pid.sh b/tests/tail-2/pid.sh
new file mode 100755
index 0000000..9e73b84
--- /dev/null
+++ b/tests/tail-2/pid.sh
@@ -0,0 +1,51 @@
+#!/bin/sh
+# Test the --pid option of tail.
+
+# Copyright (C) 2003-2016 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 <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ tail
+getlimits_
+
+touch empty here || framework_failure_
+
+# Terminate any background tail process
+cleanup_() { kill $pid 2>/dev/null && wait $pid; }
+
+for mode in '' '---disable-inotify'; do
+ # Use tail itself to create a background process to monitor,
+ # which will auto exit when "here" is removed.
+ tail -f $mode here & pid=$!
+
+ # Ensure that tail --pid=PID does not exit when PID is alive.
+ timeout 1 tail -f -s.1 --pid=$pid $mode here
+ test $? = 124 || fail=1
+
+ cleanup_
+
+ # Ensure that tail --pid=PID exits with success status when PID is dead.
+ # Use an unlikely-to-be-live PID
+ timeout 10 tail -f -s.1 --pid=$PID_T_MAX $mode empty
+ ret=$?
+ test $ret = 124 && skip_ "pid $PID_T_MAX present or tail too slow"
+ test $ret = 0 || fail=1
+
+ # Ensure tail doesn't wait for data when PID is dead
+ timeout 10 tail -f -s10 --pid=$PID_T_MAX $mode empty
+ test $? = 124 && fail=1
+done
+
+Exit $fail
diff --git a/tests/tail-2/pipe-f.sh b/tests/tail-2/pipe-f.sh
new file mode 100755
index 0000000..7abb7d6
--- /dev/null
+++ b/tests/tail-2/pipe-f.sh
@@ -0,0 +1,27 @@
+#!/bin/sh
+# ensure that :|tail -f doesn't hang, per POSIX
+
+# Copyright (C) 2009-2016 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 <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ tail
+
+echo foo | timeout 10 tail -f -c3 > out || fail=1
+echo oo > exp || fail=1
+
+compare exp out || fail=1
+
+Exit $fail
diff --git a/tests/tail-2/pipe-f2.sh b/tests/tail-2/pipe-f2.sh
new file mode 100755
index 0000000..70fb3bd
--- /dev/null
+++ b/tests/tail-2/pipe-f2.sh
@@ -0,0 +1,47 @@
+#!/bin/sh
+# Ensure that "tail -f fifo" tails indefinitely.
+
+# Copyright (C) 2009-2016 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 <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ tail
+
+mkfifo_or_skip_ fifo
+
+echo 1 > fifo &
+echo 1 > exp || framework_failure_
+
+# Terminate any background tail process
+cleanup_() { kill $pid 2>/dev/null && wait $pid; }
+
+# Speedup the non inotify case
+fastpoll='-s.1 --max-unchanged-stats=1'
+
+timeout 10 tail $fastpoll -f fifo > out & pid=$!
+
+check_tail_output() { sleep $1; test -s out; }
+
+# Wait 12.7s for tail to write something.
+retry_delay_ check_tail_output .1 7 || fail=1
+
+compare exp out || fail=1
+
+# Ensure tail is still running
+kill -0 $pid || fail=1
+
+cleanup_
+
+Exit $fail
diff --git a/tests/tail-2/proc-ksyms b/tests/tail-2/proc-ksyms
deleted file mode 100755
index ba9fccd..0000000
--- a/tests/tail-2/proc-ksyms
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/sh
-# Prior to textutils-2.0.17, `tail /proc/ksyms' would segfault on Linux.
-
-# Copyright (C) 2001, 2004, 2006 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 2 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.
-
-if test "$VERBOSE" = yes; then
- set -x
- tail --version
-fi
-
-pwd=`pwd`
-tmp=proc-ksyms.$$
-trap 'status=$?; cd "$pwd" && rm -rf $tmp && exit $status' 0
-trap '(exit $?); exit' 1 2 13 15
-
-fail=0
-
-ksyms=/proc/ksyms
-if test -r $ksyms; then
- tail $ksyms > /dev/null || fail=1
-fi
-
-(exit $fail); exit $fail
diff --git a/tests/tail-2/proc-ksyms.sh b/tests/tail-2/proc-ksyms.sh
new file mode 100755
index 0000000..f238bc9
--- /dev/null
+++ b/tests/tail-2/proc-ksyms.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+# Prior to textutils-2.0.17, 'tail /proc/ksyms' would segfault on Linux.
+
+# Copyright (C) 2001-2016 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 <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ tail
+
+
+ksyms=/proc/ksyms
+if test -r $ksyms; then
+ tail $ksyms > /dev/null || fail=1
+fi
+
+Exit $fail
diff --git a/tests/tail-2/retry.sh b/tests/tail-2/retry.sh
new file mode 100755
index 0000000..37e01ed
--- /dev/null
+++ b/tests/tail-2/retry.sh
@@ -0,0 +1,131 @@
+#!/bin/sh
+# Exercise tail's behavior regarding missing files with/without --retry.
+
+# Copyright (C) 2013-2016 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 <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ tail
+
+# Function to count number of lines from tail
+# while ignoring transient errors due to resource limits
+countlines_ ()
+{
+ grep -Ev 'inotify (resources exhausted|cannot be used)' out | wc -l
+}
+
+# Function to check the expected line count in 'out'.
+# Called via retry_delay_(). Sleep some time - see retry_delay_() - if the
+# line count is still smaller than expected.
+wait4lines_ ()
+{
+ local delay=$1
+ local elc=$2 # Expected line count.
+ [ "$(countlines_)" -ge "$elc" ] || { sleep $delay; return 1; }
+}
+
+# Terminate any background tail process
+cleanup_() { kill $pid 2>/dev/null && wait $pid; }
+
+# Speedup the non inotify case
+fastpoll='-s.1 --max-unchanged-stats=1'
+
+# === Test:
+# Retry without --follow results in a warning.
+touch file
+tail --retry file > out 2>&1 || fail=1
+[ "$(countlines_)" = 1 ] || { cat out; fail=1; }
+grep -F 'tail: warning: --retry ignored' out || { cat out; fail=1; }
+
+# === Test:
+# The same with a missing file: expect error message and exit 1.
+tail --retry missing > out 2>&1 && fail=1
+[ "$(countlines_)" = 2 ] || { cat out; fail=1; }
+grep -F 'tail: warning: --retry ignored' out || { cat out; fail=1; }
+
+# === Test:
+# Ensure that "tail --retry --follow=name" waits for the file to appear.
+# Clear 'out' so that we can check its contents without races
+>out || framework_failure_
+timeout 10 tail $fastpoll --follow=name --retry missing >out 2>&1 & pid=$!
+# Wait for "cannot open" error.
+retry_delay_ wait4lines_ .1 6 1 || { cat out; fail=1; }
+echo "X" > missing || framework_failure_
+# Wait for the expected output.
+retry_delay_ wait4lines_ .1 6 3 || { cat out; fail=1; }
+cleanup_
+# Expect 3 lines in the output file.
+[ "$(countlines_)" = 3 ] || { fail=1; cat out; }
+grep -F 'cannot open' out || { fail=1; cat out; }
+grep -F 'has appeared' out || { fail=1; cat out; }
+grep '^X$' out || { fail=1; cat out; }
+rm -f missing out || framework_failure_
+
+# === Test:
+# Ensure that "tail --retry --follow=descriptor" waits for the file to appear.
+# tail-8.21 failed at this (since the implementation of the inotify support).
+timeout 10 tail $fastpoll --follow=descriptor --retry missing >out 2>&1 & pid=$!
+# Wait for "cannot open" error.
+retry_delay_ wait4lines_ .1 6 2 || { cat out; fail=1; }
+echo "X" > missing || framework_failure_
+# Wait for the expected output.
+retry_delay_ wait4lines_ .1 6 4 || { cat out; fail=1; }
+cleanup_
+# Expect 4 lines in the output file.
+[ "$(countlines_)" = 4 ] || { fail=1; cat out; }
+grep -F 'retry only effective for the initial open' out \
+ || { fail=1; cat out; }
+grep -F 'cannot open' out || { fail=1; cat out; }
+grep -F 'has appeared' out || { fail=1; cat out; }
+grep '^X$' out || { fail=1; cat out; }
+rm -f missing out || framework_failure_
+
+# === Test:
+# Ensure that tail --follow=descriptor --retry exits when the file appears
+# untailable. Expect exit status 1.
+timeout 10 tail $fastpoll --follow=descriptor --retry missing >out 2>&1 & pid=$!
+# Wait for "cannot open" error.
+retry_delay_ wait4lines_ .1 6 2 || { cat out; fail=1; }
+mkdir missing || framework_failure_ # Create untailable
+# Wait for the expected output.
+retry_delay_ wait4lines_ .1 6 4 || { cat out; fail=1; }
+wait $pid
+rc=$?
+[ "$(countlines_)" = 4 ] || { fail=1; cat out; }
+grep -F 'retry only effective for the initial open' out \
+ || { fail=1; cat out; }
+grep -F 'cannot open' out || { fail=1; cat out; }
+grep -F 'replaced with an untailable file' out || { fail=1; cat out; }
+grep -F 'no files remaining' out || { fail=1; cat out; }
+[ $rc = 1 ] || { fail=1; cat out; }
+rm -fd missing out || framework_failure_
+
+# === Test:
+# Ensure that --follow=descriptor (without --retry) does *not wait* for the
+# file to appear. Expect 2 lines in the output file ("cannot open" +
+# "no files remaining") and exit status 1.
+tail --follow=descriptor missing >out 2>&1 && fail=1
+[ "$(countlines_)" = 2 ] || { fail=1; cat out; }
+grep -F 'cannot open' out || { fail=1; cat out; }
+grep -F 'no files remaining' out || { fail=1; cat out; }
+
+# === Test:
+# Likewise for --follow=name (without --retry).
+tail --follow=name missing >out 2>&1 && fail=1
+[ "$(countlines_)" = 2 ] || { fail=1; cat out; }
+grep -F 'cannot open' out || { fail=1; cat out; }
+grep -F 'no files remaining' out || { fail=1; cat out; }
+
+Exit $fail
diff --git a/tests/tail-2/start-middle b/tests/tail-2/start-middle
deleted file mode 100755
index 92a939a..0000000
--- a/tests/tail-2/start-middle
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/bin/sh
-# Verify that tail works even when it's reading from a file
-# that is not at its beginning. Based on a report from John Roll.
-
-# Copyright (C) 2001, 2002, 2004, 2006 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 2 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.
-
-if test "$VERBOSE" = yes; then
- set -x
- tail --version
-fi
-
-pwd=`pwd`
-tmp=tail-mid.$$
-trap 'status=$?; cd "$pwd" && rm -rf $tmp && exit $status' 0
-trap '(exit $?); exit' 1 2 13 15
-
-framework_failure=0
-mkdir $tmp || framework_failure=1
-cd $tmp || framework_failure=1
-
-(echo 1; echo 2) > k || framework_failure=1
-
-if test $framework_failure = 1; then
- echo "$0: failure in testing framework" 1>&2
- (exit 1); exit 1
-fi
-
-fail=0
-
-sh -c 'read x; tail' < k > out || fail=1
-cat <<EOF > exp
-2
-EOF
-
-cmp out exp || fail=1
-test $fail = 1 && diff out exp 2> /dev/null
-
-(exit $fail); exit $fail
diff --git a/tests/tail-2/start-middle.sh b/tests/tail-2/start-middle.sh
new file mode 100755
index 0000000..5a9ebfc
--- /dev/null
+++ b/tests/tail-2/start-middle.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+# Verify that tail works even when it's reading from a file
+# that is not at its beginning. Based on a report from John Roll.
+
+# Copyright (C) 2001-2016 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 <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ tail
+
+(echo 1; echo 2) > k || framework_failure_
+
+
+sh -c 'read x; tail' < k > out || fail=1
+cat <<EOF > exp
+2
+EOF
+
+compare exp out || fail=1
+
+Exit $fail
diff --git a/tests/tail-2/symlink.sh b/tests/tail-2/symlink.sh
new file mode 100755
index 0000000..8a10577
--- /dev/null
+++ b/tests/tail-2/symlink.sh
@@ -0,0 +1,94 @@
+#!/bin/sh
+# Ensure tail tracks symlinks properly.
+
+# Copyright (C) 2013-2016 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 <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ tail
+
+# Function to count number of lines from tail
+# while ignoring transient errors due to resource limits
+countlines_ ()
+{
+ grep -Ev 'inotify (resources exhausted|cannot be used)' out | wc -l
+}
+
+# Function to check the expected line count in 'out'.
+# Called via retry_delay_(). Sleep some time - see retry_delay_() - if the
+# line count is still smaller than expected.
+wait4lines_ ()
+{
+ local delay=$1
+ local elc=$2 # Expected line count.
+ [ "$(countlines_)" -ge "$elc" ] || { sleep $delay; return 1; }
+}
+
+# Terminate any background tail process
+cleanup_() { kill $pid 2>/dev/null && wait $pid; }
+
+# speedup non inotify case
+fastpoll='-s.1 --max-unchanged-stats=1'
+
+# Ensure changing targets of cli specified symlinks are handled.
+# Prior to v8.22, inotify would fail to recognize changes in the targets.
+# Clear 'out' so that we can check its contents without races.
+>out || framework_failure_
+ln -nsf target symlink || framework_failure_
+timeout 10 tail $fastpoll -F symlink >out 2>&1 & pid=$!
+# Wait for "cannot open..."
+retry_delay_ wait4lines_ .1 6 1 || { cat out; fail=1; }
+echo "X" > target || framework_failure_
+# Wait for the expected output.
+retry_delay_ wait4lines_ .1 6 3 || { cat out; fail=1; }
+cleanup_
+# Expect 3 lines in the output file.
+[ "$(countlines_)" = 3 ] || { fail=1; cat out; }
+grep -F 'cannot open' out || { fail=1; cat out; }
+grep -F 'has appeared' out || { fail=1; cat out; }
+grep '^X$' out || { fail=1; cat out; }
+rm -f target out || framework_failure_
+
+# Ensure we correctly handle the source symlink itself changing.
+# I.e., that we don't operate solely on the targets.
+# Clear 'out' so that we can check its contents without races.
+>out || framework_failure_
+echo "X1" > target1 || framework_failure_
+ln -nsf target1 symlink || framework_failure_
+timeout 10 tail $fastpoll -F symlink >out 2>&1 & pid=$!
+# Wait for the expected output.
+retry_delay_ wait4lines_ .1 6 1 || { cat out; fail=1; }
+ln -nsf target2 symlink || framework_failure_
+# Wait for "become inaccess..."
+retry_delay_ wait4lines_ .1 6 2 || { cat out; fail=1; }
+echo "X2" > target2 || framework_failure_
+# Wait for the expected output.
+retry_delay_ wait4lines_ .1 6 4 || { cat out; fail=1; }
+cleanup_
+# Expect 4 lines in the output file.
+[ "$(countlines_)" = 4 ] || { fail=1; cat out; }
+grep -F 'become inacce' out || { fail=1; cat out; }
+grep -F 'has appeared' out || { fail=1; cat out; }
+grep '^X1$' out || { fail=1; cat out; }
+grep '^X2$' out || { fail=1; cat out; }
+rm -f target1 target2 out || framework_failure_
+
+# Note other symlink edge cases are currently just diagnosed
+# rather than being handled. I.e., if you specify a missing item,
+# or existing file that later change to a symlink, if inotify
+# is in use, you'll get a diagnostic saying that link will
+# no longer be tailed.
+
+Exit $fail
diff --git a/tests/tail-2/tail-c.sh b/tests/tail-2/tail-c.sh
new file mode 100755
index 0000000..ac35d56
--- /dev/null
+++ b/tests/tail-2/tail-c.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+# exercise tail -c
+
+# Copyright 2014-2016 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 <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ tail
+
+# Make sure it works on funny files in /proc and /sys.
+
+for file in /proc/version /sys/kernel/profiling; do
+ if test -r $file; then
+ cp -f $file copy &&
+ tail -c -1 copy > exp1 || framework_failure_
+
+ tail -c -1 $file > out1 || fail=1
+ compare exp1 out1 || fail=1
+ fi
+done
+
+Exit $fail
diff --git a/tests/tail-2/tail-n0f b/tests/tail-2/tail-n0f
deleted file mode 100755
index 298fca4..0000000
--- a/tests/tail-2/tail-n0f
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/bin/sh
-# Make sure that `tail -n0 -f' and `tail -c0 -f' sleep
-# rather than doing what amounted to a busy-wait.
-
-# Copyright (C) 2003, 2006 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 2 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, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.
-
-
-# This bug was fixed for 5.0.91
-# It skips the test if your system lacks a /proc/$pid/status
-# file, or if its contents don't look right.
-
-if test "$VERBOSE" = yes; then
- set -x
- tail --version
-fi
-
-sleep 2 &
-pid=$!
-sleep .5
-grep '^State:[ ]*[S]' /proc/$pid/status > /dev/null 2>&1 || \
- {
- echo "$0:/proc/$pid/status: missing or 'different': skipping this test" 1>&2
- (exit 77); exit 77
- }
-kill $pid
-
-pwd=`pwd`
-t0=`echo "$0"|sed 's,.*/,,'`.tmp; tmp=$t0/$$
-trap 'status=$?; cd "$pwd" && chmod -R u+rwx $t0 && rm -rf $t0 && exit $status' 0
-trap '(exit $?); exit $?' 1 2 13 15
-
-framework_failure=0
-mkdir -p $tmp || framework_failure=1
-cd $tmp || framework_failure=1
-touch empty || framework_failure=1
-echo anything > nonempty || framework_failure=1
-
-if test $framework_failure = 1; then
- echo "$0: failure in testing framework" 1>&2
- (exit 1); exit 1
-fi
-
-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
- set _ `sed -n '/^State:[ ]*\([^ ]\)/s//\1/p' /proc/$pid/status`
- shift # Remove the leading `_'.
- state=$1
- case $state in
- S*) ;;
- *) echo $0: process in unexpected state: $state 1>&2; fail=1 ;;
- esac
- kill $pid
- done
-done
-
-(exit $fail); exit $fail
diff --git a/tests/tail-2/tail-n0f.sh b/tests/tail-2/tail-n0f.sh
new file mode 100755
index 0000000..01b5986
--- /dev/null
+++ b/tests/tail-2/tail-n0f.sh
@@ -0,0 +1,62 @@
+#!/bin/sh
+# Make sure that 'tail -n0 -f' and 'tail -c0 -f' sleep
+# rather than doing what amounted to a busy-wait.
+
+# Copyright (C) 2003-2016 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 <http://www.gnu.org/licenses/>.
+
+# This bug was fixed for 5.0.91
+# It skips the test if your system lacks a /proc/$pid/status
+# file, or if its contents don't look right.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ tail
+
+require_proc_pid_status_
+
+touch empty || framework_failure_
+echo anything > nonempty || framework_failure_
+
+# First verify that -[nc]0 without -f, exit without reading
+touch unreadable || framework_failure_
+chmod 0 unreadable || framework_failure_
+tail -c0 unreadable || fail=1
+tail -n0 unreadable || fail=1
+
+# Terminate any background tail process
+cleanup_() { kill $pid 2>/dev/null && wait $pid; }
+
+for mode 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 $mode $file & pid=$!
+ tail_sleeping()
+ {
+ local delay="$1"; sleep $delay
+ state=$(get_process_status_ $pid)
+ case $state in
+ S*) ;;
+ *) return 1;;
+ esac
+ }
+ # Wait up to 1.5s for tail to sleep
+ retry_delay_ tail_sleeping .1 4 ||
+ { echo $0: process in unexpected state: $state >&2; fail=1; }
+ cleanup_
+ done
+ done
+done
+
+Exit $fail
diff --git a/tests/tail-2/truncate.sh b/tests/tail-2/truncate.sh
new file mode 100755
index 0000000..5b49ccc
--- /dev/null
+++ b/tests/tail-2/truncate.sh
@@ -0,0 +1,56 @@
+#!/bin/sh
+# Ensure all logs are output upon file truncation
+
+# Copyright (C) 2015-2016 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 <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ tail
+
+check_tail_output()
+{
+ local delay="$1"
+ grep "$tail_re" out > /dev/null ||
+ { sleep $delay; return 1; }
+}
+
+# Terminate any background tail process
+cleanup_() { kill $pid 2>/dev/null && wait $pid; }
+
+# Speedup the non inotify case
+fastpoll='-s.1 --max-unchanged-stats=1'
+
+for follow in '-f' '-F'; do
+ for mode in '' '---disable-inotify'; do
+ rm -f out
+ seq 10 > f || framework_failure_
+
+ tail $follow $mode $fastpoll f > out 2>&1 & pid=$!
+
+ # Wait up to 12.7s for tail to start
+ tail_re='^10$' retry_delay_ check_tail_output .1 7 ||
+ { cat out; fail=1; }
+
+ seq 11 15 > f || framework_failure_
+
+ # Wait up to 12.7s for new data
+ tail_re='^15$' retry_delay_ check_tail_output .1 7 ||
+ { cat out; fail=1; }
+
+ cleanup_
+ done
+done
+
+Exit $fail
diff --git a/tests/tail-2/wait.sh b/tests/tail-2/wait.sh
new file mode 100755
index 0000000..59f796a
--- /dev/null
+++ b/tests/tail-2/wait.sh
@@ -0,0 +1,96 @@
+#!/bin/sh
+# Make sure that 'tail -f' returns immediately if a file doesn't exist
+# while 'tail -F' waits for it to appear.
+
+# Copyright (C) 2003-2016 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 <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ tail
+
+grep '^#define HAVE_INOTIFY 1' "$CONFIG_HEADER" >/dev/null \
+ && HAVE_INOTIFY=1
+
+inotify_failed_re='inotify (resources exhausted|cannot be used)'
+
+touch here || framework_failure_
+{ touch unreadable && chmod a-r unreadable; } || framework_failure_
+
+# Terminate any background tail process
+cleanup_() { kill $pid 2>/dev/null && wait $pid; }
+
+# speedup non inotify case
+fastpoll='-s.1 --max-unchanged-stats=1'
+
+for mode in '' '---disable-inotify'; do
+ timeout 10 tail $fastpoll -f $mode not_here
+ test $? = 124 && fail=1
+
+ if test ! -r unreadable; then # can't test this when root
+ timeout 10 tail $fastpoll -f $mode unreadable
+ test $? = 124 && fail=1
+ fi
+
+ timeout .1 tail $fastpoll -f $mode here 2>tail.err
+ test $? = 124 || fail=1
+
+ # 'tail -F' must wait in any case.
+
+ timeout .1 tail $fastpoll -F $mode here 2>>tail.err
+ test $? = 124 || fail=1
+
+ if test ! -r unreadable; then # can't test this when root
+ timeout .1 tail $fastpoll -F $mode unreadable
+ test $? = 124 || fail=1
+ fi
+
+ timeout .1 tail $fastpoll -F $mode not_here
+ test $? = 124 || fail=1
+
+ grep -Ev "$inotify_failed_re" tail.err > x
+ mv x tail.err
+ compare /dev/null tail.err || fail=1
+ >tail.err
+done
+
+if test "$HAVE_INOTIFY" && test -z "$mode" && is_local_dir_ .; then
+ # Ensure -F never follows a descriptor after rename
+ # either with tiny or significant delays between operations
+ tail_F()
+ {
+ local delay="$1"
+
+ > k && > tail.out && > tail.err || framework_failure_
+ tail $fastpoll -F $mode k >tail.out 2>tail.err & pid=$!
+ sleep $delay
+ mv k l
+ sleep $delay
+ touch k
+ mv k l
+ sleep $delay
+ echo NO >> l
+ sleep $delay
+ cleanup_
+ rm -f k l
+
+ test -s tail.out \
+ && ! grep -E "$inotify_failed_re" tail.err >/dev/null
+ }
+
+ retry_delay_ tail_F 0 1 && { cat tail.out; fail=1; }
+ retry_delay_ tail_F .2 1 && { cat tail.out; fail=1; }
+fi
+
+Exit $fail