summaryrefslogtreecommitdiff
path: root/src/tee.c
diff options
context:
space:
mode:
authorPádraig Brady <P@draigBrady.com>2015-03-02 20:06:17 +0000
committerPádraig Brady <P@draigBrady.com>2015-03-04 13:24:21 +0000
commit5e9c277f995c517e4403c87e74b758d5b65004f2 (patch)
tree2ce8a8cfa4224d04c841c6ef21a2938078ab2107 /src/tee.c
parent69410690b8b9838b190c1eaf7d0fa9634e991903 (diff)
downloadcoreutils-5e9c277f995c517e4403c87e74b758d5b65004f2.tar.xz
tee: generalize the --write-error option to --output-error
Adjust commit v8.23-140-gfdd6ebf to add the --output-error option instead of --write-error, and treat open() errors like write() errors. * doc/coreutils.texi (tee invocation): s/write-error/output-error/. * src/tee.c (main): Exit on open() error if appropriate. * tests/misc/tee.sh: Add a case to test open() errors. * NEWS: Adjust for the more general output error behavior. Suggested by Bernhard Voelker.
Diffstat (limited to 'src/tee.c')
-rw-r--r--src/tee.c57
1 files changed, 28 insertions, 29 deletions
diff --git a/src/tee.c b/src/tee.c
index c163184cb..3c39a4ab3 100644
--- a/src/tee.c
+++ b/src/tee.c
@@ -44,37 +44,37 @@ static bool append;
/* If true, ignore interrupts. */
static bool ignore_interrupts;
-enum write_error
+enum output_error
{
- write_error_sigpipe, /* traditional behavior, sigpipe enabled. */
- write_error_warn, /* warn on EPIPE, but continue. */
- write_error_warn_nopipe, /* ignore EPIPE, continue. */
- write_error_exit, /* exit on any write error. */
- write_error_exit_nopipe /* exit on any write error except EPIPE. */
+ output_error_sigpipe, /* traditional behavior, sigpipe enabled. */
+ output_error_warn, /* warn on EPIPE, but continue. */
+ output_error_warn_nopipe, /* ignore EPIPE, continue. */
+ output_error_exit, /* exit on any output error. */
+ output_error_exit_nopipe /* exit on any output error except EPIPE. */
};
-static enum write_error write_error;
+static enum output_error output_error;
static struct option const long_options[] =
{
{"append", no_argument, NULL, 'a'},
{"ignore-interrupts", no_argument, NULL, 'i'},
- {"write-error", optional_argument, NULL, 'p'},
+ {"output-error", optional_argument, NULL, 'p'},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
};
-static char const *const write_error_args[] =
+static char const *const output_error_args[] =
{
"warn", "warn-nopipe", "exit", "exit-nopipe", NULL
};
-static enum write_error const write_error_types[] =
+static enum output_error const output_error_types[] =
{
- write_error_warn, write_error_warn_nopipe,
- write_error_exit, write_error_exit_nopipe
+ output_error_warn, output_error_warn_nopipe,
+ output_error_exit, output_error_exit_nopipe
};
-ARGMATCH_VERIFY (write_error_args, write_error_types);
+ARGMATCH_VERIFY (output_error_args, output_error_types);
void
usage (int status)
@@ -91,7 +91,7 @@ Copy standard input to each FILE, and also to standard output.\n\
-i, --ignore-interrupts ignore interrupt signals\n\
"), stdout);
fputs (_("\
- -p, --write-error[=MODE] behavior on write error. See MODE details below\n\
+ -p, --output-error[=MODE] behavior on write error. See MODE details below\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
@@ -103,7 +103,7 @@ MODE determines behavior with write errors on the outputs:\n\
'exit' exit on error writing to any output\n\
'exit-nopipe' exit on error writing to any output not a pipe\n\
The default MODE for the -p option is 'warn-nopipe'.\n\
-The default operation when --write-error is not specified, is to\n\
+The default operation when --output-error is not specified, is to\n\
exit immediately on error writing to a pipe, and diagnose errors\n\
writing to non pipe outputs.\n\
"), stdout);
@@ -143,10 +143,10 @@ main (int argc, char **argv)
case 'p':
if (optarg)
- write_error = XARGMATCH ("--write-error", optarg, write_error_args,
- write_error_types);
+ output_error = XARGMATCH ("--output-error", optarg,
+ output_error_args, output_error_types);
else
- write_error = write_error_warn_nopipe;
+ output_error = output_error_warn_nopipe;
break;
case_GETOPT_HELP_CHAR;
@@ -161,7 +161,7 @@ main (int argc, char **argv)
if (ignore_interrupts)
signal (SIGINT, SIG_IGN);
- if (write_error != write_error_sigpipe)
+ if (output_error != output_error_sigpipe)
signal (SIGPIPE, SIG_IGN);
/* Do *not* warn if tee is given no file arguments.
@@ -184,7 +184,7 @@ tee_files (int nfiles, const char **files)
size_t n_outputs = 0;
FILE **descriptors;
char buffer[BUFSIZ];
- ssize_t bytes_read;
+ ssize_t bytes_read = 0;
int i;
bool ok = true;
char const *mode_string =
@@ -219,7 +219,9 @@ tee_files (int nfiles, const char **files)
descriptors[i] = fopen (files[i], mode_string);
if (descriptors[i] == NULL)
{
- error (0, errno, "%s", files[i]);
+ error (output_error == output_error_exit
+ || output_error == output_error_exit_nopipe,
+ errno, "%s", files[i]);
ok = false;
}
else
@@ -229,7 +231,7 @@ tee_files (int nfiles, const char **files)
}
}
- while (1)
+ while (n_outputs)
{
bytes_read = read (0, buffer, sizeof buffer);
if (bytes_read < 0 && errno == EINTR)
@@ -244,14 +246,14 @@ tee_files (int nfiles, const char **files)
&& fwrite (buffer, bytes_read, 1, descriptors[i]) != 1)
{
int w_errno = errno;
- bool fail = errno != EPIPE || (write_error == write_error_exit
- || write_error == write_error_warn);
+ bool fail = errno != EPIPE || (output_error == output_error_exit
+ || output_error == output_error_warn);
if (descriptors[i] == stdout)
clearerr (stdout); /* Avoid redundant close_stdout diagnostic. */
if (fail)
{
- error (write_error == write_error_exit
- || write_error == write_error_exit_nopipe,
+ error (output_error == output_error_exit
+ || output_error == output_error_exit_nopipe,
w_errno, "%s", files[i]);
}
descriptors[i] = NULL;
@@ -259,9 +261,6 @@ tee_files (int nfiles, const char **files)
ok = false;
n_outputs--;
}
-
- if (n_outputs == 0)
- break;
}
if (bytes_read == -1)