summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPádraig Brady <P@draigBrady.com>2011-01-11 19:30:28 +0000
committerPádraig Brady <P@draigBrady.com>2011-01-14 18:06:41 +0000
commiteab97b3075060f027189f6592df9488a276a6732 (patch)
tree1e21f44905792aed27acdf5fc8d481b1146ee4f7 /src
parente1aaf8903db97f3240b1551fd6936ccdc652dfc8 (diff)
downloadcoreutils-eab97b3075060f027189f6592df9488a276a6732.tar.xz
maint: refactor to use read-file from gnulib
* 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.
Diffstat (limited to 'src')
-rw-r--r--src/ptx.c82
-rw-r--r--src/shuf.c48
2 files changed, 11 insertions, 119 deletions
diff --git a/src/ptx.c b/src/ptx.c
index 646561842..3ee14ffb1 100644
--- 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"
@@ -62,10 +63,6 @@
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;
}
/* Sort and search routines. */
diff --git a/src/shuf.c b/src/shuf.c
index 1d2261ee0..300bca6c8 100644
--- a/src/shuf.c
+++ b/src/shuf.c
@@ -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);