]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
wc: fix reading of /proc files on aarch64
authorPádraig Brady <P@draigBrady.com>
Wed, 1 Jul 2015 21:37:26 +0000 (22:37 +0100)
committerPádraig Brady <P@draigBrady.com>
Thu, 2 Jul 2015 02:53:59 +0000 (03:53 +0100)
tests/misc/wc-proc.sh fails when the page size is 64K

* src/wc.c (wc): The lseek adjustment should be based on st_blksize,
rather than on the internal buffer size.  This is significant on
aarch64 where st_blksize in /proc is the 64K (the page size) and
thus larger than the internal buffer.
* src/split.c (main): Even though the similar processing is done
on the internal buffer size, that's based on st_blksize and
so fine in this regard.  Add an assert to enforce this.
Avoid this path for the undocumented ---io-blksize option.

src/split.c
src/wc.c

index b6fe2ddefcd887b59e14da1d05c032249d44590f..35f2629ae5229a70e4b86eb12734d25d30b0e0d5 100644 (file)
@@ -1493,7 +1493,9 @@ main (int argc, char **argv)
 
   if (fstat (STDIN_FILENO, &in_stat_buf) != 0)
     error (EXIT_FAILURE, errno, "%s", infile);
-  if (in_blk_size == 0)
+
+  bool specified_buf_size = !! in_blk_size;
+  if (! specified_buf_size)
     in_blk_size = io_blksize (in_stat_buf);
 
   void *b = xmalloc (in_blk_size + 1 + page_size - 1);
@@ -1505,8 +1507,9 @@ main (int argc, char **argv)
       off_t input_offset = lseek (STDIN_FILENO, 0, SEEK_CUR);
       if (0 <= input_offset)
         {
-          if (usable_st_size (&in_stat_buf))
+          if (usable_st_size (&in_stat_buf) && ! specified_buf_size)
             {
+              assert (ST_BLKSIZE (in_stat_buf) <= in_blk_size);
               file_size = input_file_size (STDIN_FILENO, in_stat_buf.st_size,
                                            buf, in_blk_size);
               if (file_size < in_blk_size)
index eb7b5b69a0c4260661a8adadb34792fc79ec0dcf..9fbaee7bc1e1bb8eccabb832e01e3e381c3eb0ea 100644 (file)
--- a/src/wc.c
+++ b/src/wc.c
@@ -36,6 +36,7 @@
 #include "quotearg.h"
 #include "readtokens0.h"
 #include "safe-read.h"
+#include "stat-size.h"
 #include "xfreopen.h"
 
 #if !defined iswspace && !HAVE_ISWSPACE
@@ -238,14 +239,14 @@ wc (int fd, char const *file_x, struct fstatus *fstatus, off_t current_pos)
       if (0 < fstatus->failed)
         fstatus->failed = fstat (fd, &fstatus->st);
 
-      /* For sized files, seek to one buffer before EOF rather than to EOF.
+      /* For sized files, seek to one st_blksize before EOF rather than to EOF.
          This works better for files in proc-like file systems where
          the size is only approximate.  */
       if (! fstatus->failed && usable_st_size (&fstatus->st)
           && 0 <= fstatus->st.st_size)
         {
           size_t end_pos = fstatus->st.st_size;
-          off_t hi_pos = end_pos - end_pos % BUFFER_SIZE;
+          off_t hi_pos = end_pos - end_pos % (ST_BLKSIZE (fstatus->st) + 1);
           if (current_pos < 0)
             current_pos = lseek (fd, 0, SEEK_CUR);
           if (0 <= current_pos && current_pos < hi_pos