Require --retry to continue to track files upon rename.
We already unfollowed a file if it was renamed
to another file system (unlinked), so this makes the behavior
consistent if renaming to a file in the same file system.
I.e. --follow=name without --retry, means unfollow if the
name is unlinked or moved, so this change ensures that
behavior for all rename cases.
Related commits:
v8.0-121-g3b997a9bc,
v8.23-161-gd313a0b24
* src/tail.c (tail_forever_notify): Remove watch for a renamed file
if --retry is not specified.
* tests/tail/F-vs-rename.sh: Related test cleanup.
* tests/tail/follow-name.sh: Add a test case.
* NEWS: Mention the bug fix.
Fixes https://bugs.gnu.org/74653
'shuf' generates more-random output when the output is small.
[bug introduced in coreutils-8.6]
+ `tail --follow=name` no longer waits indefinitely for watched
+ file names that are moved elsewhere within the same file system.
+ [bug introduced in coreutils-8.24]
+
'tail -c 4096 /dev/zero' no longer loops forever.
[This bug was present in "the beginning".]
if (ev->mask & (IN_ATTRIB | IN_DELETE | IN_DELETE_SELF | IN_MOVE_SELF))
{
/* Note for IN_MOVE_SELF (the file we're watching has
- been clobbered via a rename) we leave the watch
+ been clobbered via a rename) without --retry we leave the watch
in place since it may still be part of the set
of watched names. */
- if (ev->mask & IN_DELETE_SELF)
+ if (ev->mask & IN_DELETE_SELF
+ || (!reopen_inaccessible_files && (ev->mask & IN_MOVE_SELF)))
{
inotify_rm_watch (wd, fspec->wd);
hash_remove (wd_to_name, fspec);
{ cat out; fail=1; }
# Wait up to 12.7s for "x" to be displayed:
file='b' data='x' retry_delay_ check_tail_output .1 7 ||
- { echo "$0: b: unexpected delay?"; cat out; fail=1; }
+ { echo "$0: b: unexpected delay 1?"; cat out; fail=1; }
echo x2 > 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 "$0: a: unexpected delay 2?"; cat out; fail=1; }
# Wait up to 12.7s for "x2" to be displayed:
file='a' data='x2' retry_delay_ check_tail_output .1 7 ||
- { echo "$0: a: unexpected delay 2?"; cat out; fail=1; }
+ { echo "$0: a: unexpected delay 3?"; cat out; fail=1; }
echo y >> b
# Wait up to 12.7s for "y" to appear in the output:
file='b' data='y' retry_delay_ check_tail_output .1 7 ||
- { echo "$0: b: unexpected delay 2?"; cat out; fail=1; }
+ { echo "$0: b: unexpected delay 4?"; cat out; fail=1; }
echo z >> a
# Wait up to 12.7s for "z" to appear in the output:
file='a' data='z' retry_delay_ check_tail_output .1 7 ||
- { echo "$0: a: unexpected delay 3?"; cat out; fail=1; }
+ { echo "$0: a: unexpected delay 5?"; cat out; fail=1; }
cleanup_
done
tail: cannot open 'no-such' for reading: No such file or directory
tail: no files remaining
EOF
-
returns_ 1 timeout 10 tail --follow=name no-such > out 2> err || 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
+# Between coreutils 8.34 and 9.5 inclusive, tail would have
+# waited indefinitely when a file was moved to the same file system
+cleanup_() { kill $pid 2>/dev/null && wait $pid; }
+touch file || framework_failure_
+timeout 10 tail --follow=name file & pid=$!
+sleep .1 # Usually in inotify loop here
+mv file file.unfollow || framework_failure_
+wait $pid
+test $? = 1 || fail=1
+
Exit $fail