From fee8859750fecde7e1446a7dd82edf0389e51f31 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 30 Jul 2025 07:49:14 -0700 Subject: [PATCH] =?utf8?q?tail:=20don=E2=80=99t=20output=20more=20lines=20?= =?utf8?q?than=20requested?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit * src/tail.c (file_lines): Fix an unlikely bug where ‘tail -n N’ could output more than N lines if standard input is a largish regular file with large initial offset that starts with (say) N-1 lines after the initial offset, but grows to N+1 lines between the fstat and read calls. In this case ‘tail -n N’ now outputs N-1 lines, not N+1; that is, it pretends the file grew after ‘tail’ read it. That is better than outputting more than N lines. --- NEWS | 5 +++++ src/tail.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 615d7cb824..0bda0eae59 100644 --- a/NEWS +++ b/NEWS @@ -51,6 +51,11 @@ GNU coreutils NEWS -*- outline -*- stdbuf now works on AIX. Previously it would have been ineffective. [bug introduced with the stdbuf program in coreutils-7.5] + 'tail -n NUM' no longer can output more than NUM lines if stdin + is a largish regular file with a nonzero initial offset, and grows + while 'tail' is reading it. + [This bug was present in "the beginning".] + 'tail -f -n +NUM' no longer mishandles NUM values >= UINTMAX_MAX when the input is seekable. [bug introduced in coreutils-9.6] diff --git a/src/tail.c b/src/tail.c index 46dee32834..28d3317819 100644 --- a/src/tail.c +++ b/src/tail.c @@ -580,7 +580,7 @@ file_lines (char const *prettyname, int fd, struct stat const *sb, start_pos to the end. */ xlseek (fd, start_pos, SEEK_SET, prettyname); *read_pos = start_pos + dump_remainder (false, prettyname, fd, - end_pos); + end_pos - start_pos); goto free_buffer; } pos -= bufsize; -- 2.47.2