]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
head: fix processing of non-seekable input as seekable
authorPádraig Brady <P@draigBrady.com>
Mon, 28 Nov 2016 17:11:18 +0000 (17:11 +0000)
committerPádraig Brady <P@draigBrady.com>
Mon, 28 Nov 2016 18:36:32 +0000 (18:36 +0000)
* src/head.c (elide_tail_bytes_file): Ensure we don't use
st_size unless we've previously used seek() to determine
the CURRENT_POS in the seekable file.
This was seen to cause issue on FreeBSD 11 when the pipe
buffer was filled with `yes | head --lines=-0`, in which
case st_size was 64KiB while ST_BLKSIZE() was 4KiB.
Reported by Assaf Gordon.

NEWS
src/head.c

diff --git a/NEWS b/NEWS
index e88e932145d61d15a14cba3056bac17683c6a8c5..ea84a4dba452b26fcbc027644add341cd79ade3e 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -25,6 +25,10 @@ GNU coreutils NEWS                                    -*- outline -*-
   factor again outputs immediately when numbers are input interactively.
   [bug introduced in coreutils-8.24]
 
+  head no longer tries to process non-seekable input as seekable,
+  which resulted in failures on FreeBSD 11 at least.
+  [bug introduced in coreutils-8.24]
+
   install -DZ and mkdir -pZ now set default SELinux context correctly even if
   two or more directories nested in each other are created and each of them
   defaults to a different SELinux context.
index 21ace70b415f3e7a6a1673f005a214fad037ef3c..756c978c61073431ccd54c9c10ee7dfb96fa1486 100644 (file)
@@ -465,7 +465,7 @@ elide_tail_bytes_file (const char *filename, int fd, uintmax_t n_elide,
                        struct stat const *st, off_t current_pos)
 {
   off_t size = st->st_size;
-  if (presume_input_pipe || size <= ST_BLKSIZE (*st))
+  if (presume_input_pipe || current_pos < 0 || size <= ST_BLKSIZE (*st))
     return elide_tail_bytes_pipe (filename, fd, n_elide, current_pos);
   else
     {
@@ -754,7 +754,7 @@ elide_tail_lines_file (const char *filename, int fd, uintmax_t n_elide,
                        struct stat const *st, off_t current_pos)
 {
   off_t size = st->st_size;
-  if (presume_input_pipe || size <= ST_BLKSIZE (*st))
+  if (presume_input_pipe || current_pos < 0 || size <= ST_BLKSIZE (*st))
     return elide_tail_lines_pipe (filename, fd, n_elide, current_pos);
   else
     {