maint: refactor to use read-file from gnulib
authorPádraig Brady <P@draigBrady.com>
Tue, 11 Jan 2011 19:30:28 +0000 (19:30 +0000)
committerPádraig Brady <P@draigBrady.com>
Fri, 14 Jan 2011 18:06:41 +0000 (18:06 +0000)
* bootstrap.conf: Add the read-file module
* src/ptx.c: Replace the original code which would
needlessly read SIZE_MAX bytes of files larger than this.
* src/shuf.c: Replace the original code.

bootstrap.conf
src/ptx.c
src/shuf.c

index d994f52..e62f720 100644 (file)
@@ -172,6 +172,7 @@ gnulib_modules="
   quotearg
   randint
   randperm
+  read-file
   readlink
   readtokens
   readtokens0
index 6465618..3ee14ff 100644 (file)
--- a/src/ptx.c
+++ b/src/ptx.c
@@ -29,6 +29,7 @@
 #include "fadvise.h"
 #include "quote.h"
 #include "quotearg.h"
+#include "read-file.h"
 #include "stdio--.h"
 #include "xstrtol.h"
 
    options.  Many of the "int" values below should be "size_t" or
    something else like that.  */
 
-/* Reallocation step when swallowing non regular files.  The value is not
-   the actual reallocation step, but its base two logarithm.  */
-#define SWALLOW_REALLOC_LOG 12
-
 /* Program options.  */
 
 enum Format
@@ -511,88 +508,21 @@ initialize_regex (void)
 static void
 swallow_file_in_memory (const char *file_name, BLOCK *block)
 {
-  int file_handle;             /* file descriptor number */
-  struct stat stat_block;      /* stat block for file */
-  size_t allocated_length;     /* allocated length of memory buffer */
   size_t used_length;          /* used length in memory buffer */
-  int read_length;             /* number of character gotten on last read */
 
   /* As special cases, a file name which is NULL or "-" indicates standard
      input, which is already opened.  In all other cases, open the file from
      its name.  */
   bool using_stdin = !file_name || !*file_name || STREQ (file_name, "-");
   if (using_stdin)
-    file_handle = STDIN_FILENO;
-  else
-    if ((file_handle = open (file_name, O_RDONLY)) < 0)
-      error (EXIT_FAILURE, errno, "%s", file_name);
-
-  /* If the file is a plain, regular file, allocate the memory buffer all at
-     once and swallow the file in one blow.  In other cases, read the file
-     repeatedly in smaller chunks until we have it all, reallocating memory
-     once in a while, as we go.  */
-
-  if (fstat (file_handle, &stat_block) < 0)
-    error (EXIT_FAILURE, errno, "%s", file_name);
-
-  if (S_ISREG (stat_block.st_mode))
-    {
-      size_t in_memory_size;
-
-      fdadvise (file_handle, 0, 0, FADVISE_SEQUENTIAL);
-
-      block->start = xmalloc ((size_t) stat_block.st_size);
-
-      if ((in_memory_size = read (file_handle,
-                                  block->start, (size_t) stat_block.st_size))
-          != stat_block.st_size)
-        {
-#if MSDOS
-          /* On MSDOS, in memory size may be smaller than the file
-             size, because of end of line conversions.  But it can
-             never be smaller than half the file size, because the
-             minimum is when all lines are empty and terminated by
-             CR+LF.  */
-          if (in_memory_size != (size_t)-1
-              && in_memory_size >= stat_block.st_size / 2)
-            block->start = xrealloc (block->start, in_memory_size);
-          else
-#endif /* not MSDOS */
-
-            error (EXIT_FAILURE, errno, "%s", file_name);
-        }
-      block->end = block->start + in_memory_size;
-    }
+    block->start = fread_file (stdin, &used_length);
   else
-    {
-      block->start = xmalloc ((size_t) 1 << SWALLOW_REALLOC_LOG);
-      used_length = 0;
-      allocated_length = (1 << SWALLOW_REALLOC_LOG);
-
-      while (read_length = read (file_handle,
-                                 block->start + used_length,
-                                 allocated_length - used_length),
-             read_length > 0)
-        {
-          used_length += read_length;
-          if (used_length == allocated_length)
-            {
-              allocated_length += (1 << SWALLOW_REALLOC_LOG);
-              block->start
-                = xrealloc (block->start, allocated_length);
-            }
-        }
-
-      if (read_length < 0)
-        error (EXIT_FAILURE, errno, "%s", file_name);
-
-      block->end = block->start + used_length;
-    }
+    block->start = read_file (file_name, &used_length);
 
-  /* Close the file, but only if it was not the standard input.  */
+  if (!block->start)
+    error (EXIT_FAILURE, errno, "%s", quote (using_stdin ? "-" : file_name));
 
-  if (! using_stdin && close (file_handle) != 0)
-    error (EXIT_FAILURE, errno, "%s", file_name);
+  block->end = block->start + used_length;
 }
 \f
 /* Sort and search routines.  */
index 1d2261e..300bca6 100644 (file)
@@ -29,6 +29,7 @@
 #include "quotearg.h"
 #include "randint.h"
 #include "randperm.h"
+#include "read-file.h"
 #include "stdio--.h"
 #include "xstrtol.h"
 
@@ -147,52 +148,14 @@ read_input (FILE *in, char eolbyte, char ***pline)
 {
   char *p;
   char *buf = NULL;
+  size_t used;
   char *lim;
-  size_t alloc = 0;
-  size_t used = 0;
-  size_t next_alloc = (1 << 13) + 1;
-  size_t bytes_to_read;
-  size_t nread;
   char **line;
   size_t i;
   size_t n_lines;
-  int fread_errno;
-  struct stat instat;
 
-  if (fstat (fileno (in), &instat) == 0 && S_ISREG (instat.st_mode))
-    {
-      off_t file_size = instat.st_size;
-      off_t current_offset = ftello (in);
-      if (0 <= current_offset)
-        {
-          off_t remaining_size =
-            (current_offset < file_size ? file_size - current_offset : 0);
-          if (SIZE_MAX - 2 < remaining_size)
-            xalloc_die ();
-          next_alloc = remaining_size + 2;
-        }
-    }
-
-  do
-    {
-      if (alloc <= used + 1)
-        {
-          if (alloc == SIZE_MAX)
-            xalloc_die ();
-          alloc = next_alloc;
-          next_alloc = alloc * 2;
-          if (next_alloc < alloc)
-            next_alloc = SIZE_MAX;
-          buf = xrealloc (buf, alloc);
-        }
-
-      bytes_to_read = alloc - used - 1;
-      nread = fread (buf + used, sizeof (char), bytes_to_read, in);
-      used += nread;
-    }
-  while (nread == bytes_to_read);
-
-  fread_errno = errno;
+  if (!(buf = fread_file (in, &used)))
+    error (EXIT_FAILURE, errno, _("read error"));
 
   if (used && buf[used - 1] != eolbyte)
     buf[used++] = eolbyte;
@@ -209,7 +172,6 @@ read_input (FILE *in, char eolbyte, char ***pline)
   for (i = 1; i <= n_lines; i++)
     line[i] = p = next_line (p, eolbyte, lim - p);
 
-  errno = fread_errno;
   return n_lines;
 }
 
@@ -396,7 +358,7 @@ main (int argc, char **argv)
      doesn't have to worry about opening something other than
      stdin.  */
   if (! (echo || input_numbers_option_used (lo_input, hi_input))
-      && (ferror (stdin) || fclose (stdin) != 0))
+      && (fclose (stdin) != 0))
     error (EXIT_FAILURE, errno, _("read error"));
 
   permutation = randperm_new (randint_source, head_lines, n_lines);