summaryrefslogtreecommitdiff
path: root/src/cat.c
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2016-01-20 10:55:18 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2016-01-20 10:55:18 +0000
commit70e9163c9c18e995515598085cb824e554eb7ae7 (patch)
treea42dc8b2a6c031354bf31472de888bfc8a060132 /src/cat.c
parentcbf5993c43f49281173f185863577d86bfac6eae (diff)
downloadcoreutils-tarball-master.tar.gz
Diffstat (limited to 'src/cat.c')
-rw-r--r--src/cat.c827
1 files changed, 403 insertions, 424 deletions
diff --git a/src/cat.c b/src/cat.c
index 90a73c2..8c39244 100644
--- a/src/cat.c
+++ b/src/cat.c
@@ -1,10 +1,10 @@
/* cat -- concatenate files and print on the standard output.
- Copyright (C) 88, 90, 91, 1995-2006 Free Software Foundation, Inc.
+ Copyright (C) 1988-2016 Free Software Foundation, Inc.
- This program is free software; you can redistribute it and/or modify
+ This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -12,8 +12,7 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* Differences from the Unix cat:
* Always unbuffered, -u is ignored.
@@ -31,28 +30,22 @@
#if HAVE_STROPTS_H
# include <stropts.h>
#endif
-#if HAVE_SYS_IOCTL_H
-# include <sys/ioctl.h>
-#endif
+#include <sys/ioctl.h>
#include "system.h"
+#include "ioblksize.h"
#include "error.h"
+#include "fadvise.h"
#include "full-write.h"
-#include "getpagesize.h"
-#include "quote.h"
#include "safe-read.h"
+#include "xfreopen.h"
-/* The official name of this program (e.g., no `g' prefix). */
+/* The official name of this program (e.g., no 'g' prefix). */
#define PROGRAM_NAME "cat"
-#define AUTHORS "Torbjorn Granlund", "Richard M. Stallman"
-
-/* Undefine, to avoid warning about redefinition on some systems. */
-#undef max
-#define max(h,i) ((h) > (i) ? (h) : (i))
-
-/* Name under which this program was invoked. */
-char *program_name;
+#define AUTHORS \
+ proper_name_utf8 ("Torbjorn Granlund", "Torbj\303\266rn Granlund"), \
+ proper_name ("Richard M. Stallman")
/* Name of input file. May be "-". */
static char const *infile;
@@ -71,40 +64,44 @@ static char line_buf[LINE_COUNTER_BUF_LEN] =
'\t', '\0'
};
-/* Position in `line_buf' where printing starts. This will not change
+/* Position in 'line_buf' where printing starts. This will not change
unless the number of lines is larger than 999999. */
static char *line_num_print = line_buf + LINE_COUNTER_BUF_LEN - 8;
-/* Position of the first digit in `line_buf'. */
+/* Position of the first digit in 'line_buf'. */
static char *line_num_start = line_buf + LINE_COUNTER_BUF_LEN - 3;
-/* Position of the last digit in `line_buf'. */
+/* Position of the last digit in 'line_buf'. */
static char *line_num_end = line_buf + LINE_COUNTER_BUF_LEN - 3;
-/* Preserves the `cat' function's local `newlines' between invocations. */
+/* Preserves the 'cat' function's local 'newlines' between invocations. */
static int newlines2 = 0;
void
usage (int status)
{
if (status != EXIT_SUCCESS)
- fprintf (stderr, _("Try `%s --help' for more information.\n"),
- program_name);
+ emit_try_help ();
else
{
printf (_("\
-Usage: %s [OPTION] [FILE]...\n\
+Usage: %s [OPTION]... [FILE]...\n\
"),
- program_name);
+ program_name);
+ fputs (_("\
+Concatenate FILE(s) to standard output.\n\
+"), stdout);
+
+ emit_stdin_note ();
+
fputs (_("\
-Concatenate FILE(s), or standard input, to standard output.\n\
\n\
-A, --show-all equivalent to -vET\n\
- -b, --number-nonblank number nonblank output lines\n\
+ -b, --number-nonblank number nonempty output lines, overrides -n\n\
-e equivalent to -vE\n\
-E, --show-ends display $ at end of each line\n\
-n, --number number all output lines\n\
- -s, --squeeze-blank never more than one single blank line\n\
+ -s, --squeeze-blank suppress repeated empty output lines\n\
"), stdout);
fputs (_("\
-t equivalent to -vT\n\
@@ -114,18 +111,14 @@ Concatenate FILE(s), or standard input, to standard output.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- fputs (_("\
-\n\
-With no FILE, or when FILE is -, read standard input.\n\
-"), stdout);
printf (_("\
\n\
Examples:\n\
%s f - g Output f's contents, then standard input, then g's contents.\n\
%s Copy standard input to standard output.\n\
"),
- program_name, program_name);
- printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
+ program_name, program_name);
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -139,7 +132,7 @@ next_line_num (void)
do
{
if ((*endp)++ < '9')
- return;
+ return;
*endp-- = '0';
}
while (endp >= line_num_start);
@@ -151,7 +144,7 @@ next_line_num (void)
line_num_print--;
}
-/* Plain cat. Copies the file behind `input_desc' to STDOUT_FILENO.
+/* Plain cat. Copies the file behind 'input_desc' to STDOUT_FILENO.
Return true if successful. */
static bool
@@ -168,29 +161,29 @@ simple_cat (
/* Loop until the end of the file. */
- for (;;)
+ while (true)
{
/* Read a block of input. */
n_read = safe_read (input_desc, buf, bufsize);
if (n_read == SAFE_READ_ERROR)
- {
- error (0, errno, "%s", infile);
- return false;
- }
+ {
+ error (0, errno, "%s", quotef (infile));
+ return false;
+ }
/* End of this file? */
if (n_read == 0)
- return true;
+ return true;
/* Write this block out. */
{
- /* The following is ok, since we know that 0 < n_read. */
- size_t n = n_read;
- if (full_write (STDOUT_FILENO, buf, n) != n)
- error (EXIT_FAILURE, errno, _("write error"));
+ /* The following is ok, since we know that 0 < n_read. */
+ size_t n = n_read;
+ if (full_write (STDOUT_FILENO, buf, n) != n)
+ error (EXIT_FAILURE, errno, _("write error"));
}
}
}
@@ -246,7 +239,7 @@ cat (
/* Pointer to the next character in the input buffer. */
char *bpin;
- /* Pointer to the first non-valid byte in the input buffer, i.e. the
+ /* Pointer to the first non-valid byte in the input buffer, i.e., the
current end of the buffer. */
char *eob;
@@ -277,230 +270,231 @@ cat (
bpout = outbuf;
- for (;;)
+ while (true)
{
do
- {
- /* Write if there are at least OUTSIZE bytes in OUTBUF. */
-
- if (outbuf + outsize <= bpout)
- {
- char *wp = outbuf;
- size_t remaining_bytes;
- do
- {
- if (full_write (STDOUT_FILENO, wp, outsize) != outsize)
- error (EXIT_FAILURE, errno, _("write error"));
- wp += outsize;
- remaining_bytes = bpout - wp;
- }
- while (outsize <= remaining_bytes);
-
- /* Move the remaining bytes to the beginning of the
- buffer. */
-
- memmove (outbuf, wp, remaining_bytes);
- bpout = outbuf + remaining_bytes;
- }
-
- /* Is INBUF empty? */
-
- if (bpin > eob)
- {
- bool input_pending = false;
+ {
+ /* Write if there are at least OUTSIZE bytes in OUTBUF. */
+
+ if (outbuf + outsize <= bpout)
+ {
+ char *wp = outbuf;
+ size_t remaining_bytes;
+ do
+ {
+ if (full_write (STDOUT_FILENO, wp, outsize) != outsize)
+ error (EXIT_FAILURE, errno, _("write error"));
+ wp += outsize;
+ remaining_bytes = bpout - wp;
+ }
+ while (outsize <= remaining_bytes);
+
+ /* Move the remaining bytes to the beginning of the
+ buffer. */
+
+ memmove (outbuf, wp, remaining_bytes);
+ bpout = outbuf + remaining_bytes;
+ }
+
+ /* Is INBUF empty? */
+
+ if (bpin > eob)
+ {
+ bool input_pending = false;
#ifdef FIONREAD
- int n_to_read = 0;
-
- /* Is there any input to read immediately?
- If not, we are about to wait,
- so write all buffered output before waiting. */
-
- if (use_fionread
- && ioctl (input_desc, FIONREAD, &n_to_read) < 0)
- {
- /* Ultrix returns EOPNOTSUPP on NFS;
- HP-UX returns ENOTTY on pipes.
- SunOS returns EINVAL and
- More/BSD returns ENODEV on special files
- like /dev/null.
- Irix-5 returns ENOSYS on pipes. */
- if (errno == EOPNOTSUPP || errno == ENOTTY
- || errno == EINVAL || errno == ENODEV
- || errno == ENOSYS)
- use_fionread = false;
- else
- {
- error (0, errno, _("cannot do ioctl on %s"), quote (infile));
- newlines2 = newlines;
- return false;
- }
- }
- if (n_to_read != 0)
- input_pending = true;
+ int n_to_read = 0;
+
+ /* Is there any input to read immediately?
+ If not, we are about to wait,
+ so write all buffered output before waiting. */
+
+ if (use_fionread
+ && ioctl (input_desc, FIONREAD, &n_to_read) < 0)
+ {
+ /* Ultrix returns EOPNOTSUPP on NFS;
+ HP-UX returns ENOTTY on pipes.
+ SunOS returns EINVAL and
+ More/BSD returns ENODEV on special files
+ like /dev/null.
+ Irix-5 returns ENOSYS on pipes. */
+ if (errno == EOPNOTSUPP || errno == ENOTTY
+ || errno == EINVAL || errno == ENODEV
+ || errno == ENOSYS)
+ use_fionread = false;
+ else
+ {
+ error (0, errno, _("cannot do ioctl on %s"),
+ quoteaf (infile));
+ newlines2 = newlines;
+ return false;
+ }
+ }
+ if (n_to_read != 0)
+ input_pending = true;
#endif
- if (input_pending)
- write_pending (outbuf, &bpout);
-
- /* Read more input into INBUF. */
-
- n_read = safe_read (input_desc, inbuf, insize);
- if (n_read == SAFE_READ_ERROR)
- {
- error (0, errno, "%s", infile);
- write_pending (outbuf, &bpout);
- newlines2 = newlines;
- return false;
- }
- if (n_read == 0)
- {
- write_pending (outbuf, &bpout);
- newlines2 = newlines;
- return true;
- }
-
- /* Update the pointers and insert a sentinel at the buffer
- end. */
-
- bpin = inbuf;
- eob = bpin + n_read;
- *eob = '\n';
- }
- else
- {
- /* It was a real (not a sentinel) newline. */
-
- /* Was the last line empty?
- (i.e. have two or more consecutive newlines been read?) */
-
- if (++newlines > 0)
- {
- if (newlines >= 2)
- {
- /* Limit this to 2 here. Otherwise, with lots of
- consecutive newlines, the counter could wrap
- around at INT_MAX. */
- newlines = 2;
-
- /* Are multiple adjacent empty lines to be substituted
- by single ditto (-s), and this was the second empty
- line? */
- if (squeeze_blank)
- {
- ch = *bpin++;
- continue;
- }
- }
-
- /* Are line numbers to be written at empty lines (-n)? */
-
- if (number & !number_nonblank)
- {
- next_line_num ();
- bpout = stpcpy (bpout, line_num_print);
- }
- }
-
- /* Output a currency symbol if requested (-e). */
-
- if (show_ends)
- *bpout++ = '$';
-
- /* Output the newline. */
-
- *bpout++ = '\n';
- }
- ch = *bpin++;
- }
+ if (!input_pending)
+ write_pending (outbuf, &bpout);
+
+ /* Read more input into INBUF. */
+
+ n_read = safe_read (input_desc, inbuf, insize);
+ if (n_read == SAFE_READ_ERROR)
+ {
+ error (0, errno, "%s", quotef (infile));
+ write_pending (outbuf, &bpout);
+ newlines2 = newlines;
+ return false;
+ }
+ if (n_read == 0)
+ {
+ write_pending (outbuf, &bpout);
+ newlines2 = newlines;
+ return true;
+ }
+
+ /* Update the pointers and insert a sentinel at the buffer
+ end. */
+
+ bpin = inbuf;
+ eob = bpin + n_read;
+ *eob = '\n';
+ }
+ else
+ {
+ /* It was a real (not a sentinel) newline. */
+
+ /* Was the last line empty?
+ (i.e., have two or more consecutive newlines been read?) */
+
+ if (++newlines > 0)
+ {
+ if (newlines >= 2)
+ {
+ /* Limit this to 2 here. Otherwise, with lots of
+ consecutive newlines, the counter could wrap
+ around at INT_MAX. */
+ newlines = 2;
+
+ /* Are multiple adjacent empty lines to be substituted
+ by single ditto (-s), and this was the second empty
+ line? */
+ if (squeeze_blank)
+ {
+ ch = *bpin++;
+ continue;
+ }
+ }
+
+ /* Are line numbers to be written at empty lines (-n)? */
+
+ if (number && !number_nonblank)
+ {
+ next_line_num ();
+ bpout = stpcpy (bpout, line_num_print);
+ }
+ }
+
+ /* Output a currency symbol if requested (-e). */
+
+ if (show_ends)
+ *bpout++ = '$';
+
+ /* Output the newline. */
+
+ *bpout++ = '\n';
+ }
+ ch = *bpin++;
+ }
while (ch == '\n');
/* Are we at the beginning of a line, and line numbers are requested? */
if (newlines >= 0 && number)
- {
- next_line_num ();
- bpout = stpcpy (bpout, line_num_print);
- }
+ {
+ next_line_num ();
+ bpout = stpcpy (bpout, line_num_print);
+ }
/* Here CH cannot contain a newline character. */
/* The loops below continue until a newline character is found,
- which means that the buffer is empty or that a proper newline
- has been found. */
+ which means that the buffer is empty or that a proper newline
+ has been found. */
- /* If quoting, i.e. at least one of -v, -e, or -t specified,
- scan for chars that need conversion. */
+ /* If quoting, i.e., at least one of -v, -e, or -t specified,
+ scan for chars that need conversion. */
if (show_nonprinting)
- {
- for (;;)
- {
- if (ch >= 32)
- {
- if (ch < 127)
- *bpout++ = ch;
- else if (ch == 127)
- {
- *bpout++ = '^';
- *bpout++ = '?';
- }
- else
- {
- *bpout++ = 'M';
- *bpout++ = '-';
- if (ch >= 128 + 32)
- {
- if (ch < 128 + 127)
- *bpout++ = ch - 128;
- else
- {
- *bpout++ = '^';
- *bpout++ = '?';
- }
- }
- else
- {
- *bpout++ = '^';
- *bpout++ = ch - 128 + 64;
- }
- }
- }
- else if (ch == '\t' && !show_tabs)
- *bpout++ = '\t';
- else if (ch == '\n')
- {
- newlines = -1;
- break;
- }
- else
- {
- *bpout++ = '^';
- *bpout++ = ch + 64;
- }
-
- ch = *bpin++;
- }
- }
+ {
+ while (true)
+ {
+ if (ch >= 32)
+ {
+ if (ch < 127)
+ *bpout++ = ch;
+ else if (ch == 127)
+ {
+ *bpout++ = '^';
+ *bpout++ = '?';
+ }
+ else
+ {
+ *bpout++ = 'M';
+ *bpout++ = '-';
+ if (ch >= 128 + 32)
+ {
+ if (ch < 128 + 127)
+ *bpout++ = ch - 128;
+ else
+ {
+ *bpout++ = '^';
+ *bpout++ = '?';
+ }
+ }
+ else
+ {
+ *bpout++ = '^';
+ *bpout++ = ch - 128 + 64;
+ }
+ }
+ }
+ else if (ch == '\t' && !show_tabs)
+ *bpout++ = '\t';
+ else if (ch == '\n')
+ {
+ newlines = -1;
+ break;
+ }
+ else
+ {
+ *bpout++ = '^';
+ *bpout++ = ch + 64;
+ }
+
+ ch = *bpin++;
+ }
+ }
else
- {
- /* Not quoting, neither of -v, -e, or -t specified. */
- for (;;)
- {
- if (ch == '\t' && show_tabs)
- {
- *bpout++ = '^';
- *bpout++ = ch + 64;
- }
- else if (ch != '\n')
- *bpout++ = ch;
- else
- {
- newlines = -1;
- break;
- }
-
- ch = *bpin++;
- }
- }
+ {
+ /* Not quoting, neither of -v, -e, or -t specified. */
+ while (true)
+ {
+ if (ch == '\t' && show_tabs)
+ {
+ *bpout++ = '^';
+ *bpout++ = ch + 64;
+ }
+ else if (ch != '\n')
+ *bpout++ = ch;
+ else
+ {
+ newlines = -1;
+ break;
+ }
+
+ ch = *bpin++;
+ }
+ }
}
}
@@ -533,8 +527,8 @@ main (int argc, char **argv)
/* I-node number of the output. */
ino_t out_ino;
- /* True if the output file should not be the same as any input file. */
- bool check_redirection = true;
+ /* True if the output is a regular file. */
+ bool out_isreg;
/* Nonzero if we have ever read standard input. */
bool have_read_stdin = false;
@@ -565,7 +559,7 @@ main (int argc, char **argv)
};
initialize_main (&argc, &argv);
- program_name = argv[0];
+ set_program_name (argv[0]);
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
@@ -579,62 +573,62 @@ main (int argc, char **argv)
/* Parse command line options. */
while ((c = getopt_long (argc, argv, "benstuvAET", long_options, NULL))
- != -1)
+ != -1)
{
switch (c)
- {
- case 'b':
- number = true;
- number_nonblank = true;
- break;
-
- case 'e':
- show_ends = true;
- show_nonprinting = true;
- break;
-
- case 'n':
- number = true;
- break;
-
- case 's':
- squeeze_blank = true;
- break;
-
- case 't':
- show_tabs = true;
- show_nonprinting = true;
- break;
-
- case 'u':
- /* We provide the -u feature unconditionally. */
- break;
-
- case 'v':
- show_nonprinting = true;
- break;
-
- case 'A':
- show_nonprinting = true;
- show_ends = true;
- show_tabs = true;
- break;
-
- case 'E':
- show_ends = true;
- break;
-
- case 'T':
- show_tabs = true;
- break;
-
- case_GETOPT_HELP_CHAR;
-
- case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
-
- default:
- usage (EXIT_FAILURE);
- }
+ {
+ case 'b':
+ number = true;
+ number_nonblank = true;
+ break;
+
+ case 'e':
+ show_ends = true;
+ show_nonprinting = true;
+ break;
+
+ case 'n':
+ number = true;
+ break;
+
+ case 's':
+ squeeze_blank = true;
+ break;
+
+ case 't':
+ show_tabs = true;
+ show_nonprinting = true;
+ break;
+
+ case 'u':
+ /* We provide the -u feature unconditionally. */
+ break;
+
+ case 'v':
+ show_nonprinting = true;
+ break;
+
+ case 'A':
+ show_nonprinting = true;
+ show_ends = true;
+ show_tabs = true;
+ break;
+
+ case 'E':
+ show_ends = true;
+ break;
+
+ case 'T':
+ show_tabs = true;
+ break;
+
+ case_GETOPT_HELP_CHAR;
+
+ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
+
+ default:
+ usage (EXIT_FAILURE);
+ }
}
/* Get device, i-node number, and optimal blocksize of output. */
@@ -642,32 +636,16 @@ main (int argc, char **argv)
if (fstat (STDOUT_FILENO, &stat_buf) < 0)
error (EXIT_FAILURE, errno, _("standard output"));
- outsize = ST_BLKSIZE (stat_buf);
- /* Input file can be output file for non-regular files.
- fstat on pipes returns S_IFSOCK on some systems, S_IFIFO
- on others, so the checking should not be done for those types,
- and to allow things like cat < /dev/tty > /dev/tty, checking
- is not done for device files either. */
-
- if (S_ISREG (stat_buf.st_mode))
- {
- out_dev = stat_buf.st_dev;
- out_ino = stat_buf.st_ino;
- }
- else
- {
- check_redirection = false;
-#ifdef lint /* Suppress `used before initialized' warning. */
- out_dev = 0;
- out_ino = 0;
-#endif
- }
+ outsize = io_blksize (stat_buf);
+ out_dev = stat_buf.st_dev;
+ out_ino = stat_buf.st_ino;
+ out_isreg = S_ISREG (stat_buf.st_mode) != 0;
- if (! (number | show_ends | squeeze_blank))
+ if (! (number || show_ends || squeeze_blank))
{
file_open_mode |= O_BINARY;
if (O_BINARY && ! isatty (STDOUT_FILENO))
- freopen (NULL, "wb", stdout);
+ xfreopen (NULL, "wb", stdout);
}
/* Check if any of the input files are the same as the output file. */
@@ -680,109 +658,110 @@ main (int argc, char **argv)
do
{
if (argind < argc)
- infile = argv[argind];
+ infile = argv[argind];
if (STREQ (infile, "-"))
- {
- have_read_stdin = true;
- input_desc = STDIN_FILENO;
- if ((file_open_mode & O_BINARY) && ! isatty (STDIN_FILENO))
- freopen (NULL, "rb", stdin);
- }
+ {
+ have_read_stdin = true;
+ input_desc = STDIN_FILENO;
+ if ((file_open_mode & O_BINARY) && ! isatty (STDIN_FILENO))
+ xfreopen (NULL, "rb", stdin);
+ }
else
- {
- input_desc = open (infile, file_open_mode);
- if (input_desc < 0)
- {
- error (0, errno, "%s", infile);
- ok = false;
- continue;
- }
- }
+ {
+ input_desc = open (infile, file_open_mode);
+ if (input_desc < 0)
+ {
+ error (0, errno, "%s", quotef (infile));
+ ok = false;
+ continue;
+ }
+ }
if (fstat (input_desc, &stat_buf) < 0)
- {
- error (0, errno, "%s", infile);
- ok = false;
- goto contin;
- }
- insize = ST_BLKSIZE (stat_buf);
-
- /* Compare the device and i-node numbers of this input file with
- the corresponding values of the (output file associated with)
- stdout, and skip this input file if they coincide. Input
- files cannot be redirected to themselves. */
-
- if (check_redirection
- && stat_buf.st_dev == out_dev && stat_buf.st_ino == out_ino
- && (input_desc != STDIN_FILENO))
- {
- error (0, 0, _("%s: input file is output file"), infile);
- ok = false;
- goto contin;
- }
-
- /* Select which version of `cat' to use. If any format-oriented
- options were given use `cat'; otherwise use `simple_cat'. */
-
- if (! (number | show_ends | show_nonprinting
- | show_tabs | squeeze_blank))
- {
- insize = max (insize, outsize);
- inbuf = xmalloc (insize + page_size - 1);
-
- ok &= simple_cat (ptr_align (inbuf, page_size), insize);
- }
+ {
+ error (0, errno, "%s", quotef (infile));
+ ok = false;
+ goto contin;
+ }
+ insize = io_blksize (stat_buf);
+
+ fdadvise (input_desc, 0, 0, FADVISE_SEQUENTIAL);
+
+ /* Don't copy a nonempty regular file to itself, as that would
+ merely exhaust the output device. It's better to catch this
+ error earlier rather than later. */
+
+ if (out_isreg
+ && stat_buf.st_dev == out_dev && stat_buf.st_ino == out_ino
+ && lseek (input_desc, 0, SEEK_CUR) < stat_buf.st_size)
+ {
+ error (0, 0, _("%s: input file is output file"), quotef (infile));
+ ok = false;
+ goto contin;
+ }
+
+ /* Select which version of 'cat' to use. If any format-oriented
+ options were given use 'cat'; otherwise use 'simple_cat'. */
+
+ if (! (number || show_ends || show_nonprinting
+ || show_tabs || squeeze_blank))
+ {
+ insize = MAX (insize, outsize);
+ inbuf = xmalloc (insize + page_size - 1);
+
+ ok &= simple_cat (ptr_align (inbuf, page_size), insize);
+ }
else
- {
- inbuf = xmalloc (insize + 1 + page_size - 1);
-
- /* Why are
- (OUTSIZE - 1 + INSIZE * 4 + LINE_COUNTER_BUF_LEN + PAGE_SIZE - 1)
- bytes allocated for the output buffer?
-
- A test whether output needs to be written is done when the input
- buffer empties or when a newline appears in the input. After
- output is written, at most (OUTSIZE - 1) bytes will remain in the
- buffer. Now INSIZE bytes of input is read. Each input character
- may grow by a factor of 4 (by the prepending of M-^). If all
- characters do, and no newlines appear in this block of input, we
- will have at most (OUTSIZE - 1 + INSIZE * 4) bytes in the buffer.
- If the last character in the preceding block of input was a
- newline, a line number may be written (according to the given
- options) as the first thing in the output buffer. (Done after the
- new input is read, but before processing of the input begins.)
- A line number requires seldom more than LINE_COUNTER_BUF_LEN
- positions.
-
- Align the output buffer to a page size boundary, for efficency on
- some paging implementations, so add PAGE_SIZE - 1 bytes to the
- request to make room for the alignment. */
-
- outbuf = xmalloc (outsize - 1 + insize * 4 + LINE_COUNTER_BUF_LEN
- + page_size - 1);
-
- ok &= cat (ptr_align (inbuf, page_size), insize,
- ptr_align (outbuf, page_size), outsize, show_nonprinting,
- show_tabs, number, number_nonblank, show_ends,
- squeeze_blank);
-
- free (outbuf);
- }
+ {
+ inbuf = xmalloc (insize + 1 + page_size - 1);
+
+ /* Why are
+ (OUTSIZE - 1 + INSIZE * 4 + LINE_COUNTER_BUF_LEN + PAGE_SIZE - 1)
+ bytes allocated for the output buffer?
+
+ A test whether output needs to be written is done when the input
+ buffer empties or when a newline appears in the input. After
+ output is written, at most (OUTSIZE - 1) bytes will remain in the
+ buffer. Now INSIZE bytes of input is read. Each input character
+ may grow by a factor of 4 (by the prepending of M-^). If all
+ characters do, and no newlines appear in this block of input, we
+ will have at most (OUTSIZE - 1 + INSIZE * 4) bytes in the buffer.
+ If the last character in the preceding block of input was a
+ newline, a line number may be written (according to the given
+ options) as the first thing in the output buffer. (Done after the
+ new input is read, but before processing of the input begins.)
+ A line number requires seldom more than LINE_COUNTER_BUF_LEN
+ positions.
+
+ Align the output buffer to a page size boundary, for efficiency
+ on some paging implementations, so add PAGE_SIZE - 1 bytes to the
+ request to make room for the alignment. */
+
+ outbuf = xmalloc (outsize - 1 + insize * 4 + LINE_COUNTER_BUF_LEN
+ + page_size - 1);
+
+ ok &= cat (ptr_align (inbuf, page_size), insize,
+ ptr_align (outbuf, page_size), outsize, show_nonprinting,
+ show_tabs, number, number_nonblank, show_ends,
+ squeeze_blank);
+
+ free (outbuf);
+ }
free (inbuf);
contin:
if (!STREQ (infile, "-") && close (input_desc) < 0)
- {
- error (0, errno, "%s", infile);
- ok = false;
- }
+ {
+ error (0, errno, "%s", quotef (infile));
+ ok = false;
+ }
}
while (++argind < argc);
if (have_read_stdin && close (STDIN_FILENO) < 0)
error (EXIT_FAILURE, errno, _("closing standard input"));
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}