]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
tail: fix tailing larger number of lines in regular files
authorHannes Braun <hannes@hannesbraun.net>
Wed, 24 Sep 2025 19:20:49 +0000 (21:20 +0200)
committerPádraig Brady <P@draigBrady.com>
Wed, 24 Sep 2025 21:37:18 +0000 (22:37 +0100)
* src/tail.c (file_lines): Seek to the previous block instead of the
beginning (or a little before) of the block that was just scanned.
Otherwise, the same block is read and scanned (at least partially)
again. This bug was introduced by commit v9.7-219-g976f8abc1.
* tests/tail/basic-seek.sh: Add a new test.
* tests/local.mk: Reference the new test.
* NEWS: mention the bug fix.

NEWS
src/tail.c
tests/local.mk
tests/tail/basic-seek.sh [new file with mode: 0755]

diff --git a/NEWS b/NEWS
index 7a1a73113e839f010aa6c734e6f07da68827b953..dc1d26879327761d35499815776477771758edd4 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,10 @@ GNU coreutils NEWS                                    -*- outline -*-
   `basenc --base58` would not operate correctly with input > 15561475 bytes.
   [bug introduced with --base58 in coreutils-9.8]
 
+  'tail' outputs the correct number of lines again for non-small -n values.
+  Previously it may have output too few lines.
+  [bug introduced in coreutils-9.8]
+
 
 * Noteworthy changes in release 9.8 (2025-09-22) [stable]
 
index b8bef1d91cdb6cde2b666b6c1575376e075eaeb8..c7779c77dfe4cf5a672a265b6e796c7153590170 100644 (file)
@@ -596,7 +596,7 @@ file_lines (char const *prettyname, int fd, struct stat const *sb,
           goto free_buffer;
         }
 
-      pos = xlseek (fd, -bufsize, SEEK_CUR, prettyname);
+      pos = xlseek (fd, -(bufsize + bytes_read), SEEK_CUR, prettyname);
       bytes_read = read (fd, buffer, bufsize);
       if (bytes_read < 0)
         {
index ff5727f74533cd04877e53ba5caefa442402bdce..9663ee2da1d9fbd58da6153627c80d5183728bd8 100644 (file)
@@ -179,6 +179,7 @@ all_tests =                                 \
   tests/tty/tty-eof.pl                         \
   tests/misc/read-errors.sh                    \
   tests/misc/write-errors.sh                   \
+  tests/tail/basic-seek.sh                     \
   tests/tail/inotify-hash-abuse.sh             \
   tests/tail/inotify-hash-abuse2.sh            \
   tests/tail/F-vs-missing.sh                   \
diff --git a/tests/tail/basic-seek.sh b/tests/tail/basic-seek.sh
new file mode 100755 (executable)
index 0000000..307ed66
--- /dev/null
@@ -0,0 +1,28 @@
+#!/bin/sh
+# Verify that tail works when seeking within a file
+
+# Copyright (C) 2025 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 <https://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ tail
+
+yes '=================================' |
+  head -n1K > file.in || framework_failure_
+
+# This returned 139 in coreutils v9.8
+test $(tail -n200 file.in | wc -l) = 200 || fail=1
+
+Exit $fail