1
0
mirror of git://git.sv.gnu.org/coreutils.git synced 2026-07-26 10:39:01 +02:00

(close_stdout): Don't fail just because stdout was

closed initially, since some programs don't write to stdout in the
normal course of operation (other than --version and --help), and
we don't want this function to make e.g. `cp 1 2 >&-' fail.
But do fail if it was closed and someone has tried to write to it.
E.g., printf 'foo' >&-
This commit is contained in:
Jim Meyering
2004-11-14 00:20:01 +00:00
parent d417dd764f
commit f094ac4413
+19 -6
View File
@@ -24,6 +24,7 @@
#include "closeout.h"
#include <stdio.h>
#include <stdbool.h>
#include <errno.h>
#include "gettext.h"
@@ -32,6 +33,7 @@
#include "error.h"
#include "exitfail.h"
#include "quotearg.h"
#include "__fpending.h"
#if USE_UNLOCKED_IO
# include "unlocked-io.h"
@@ -71,14 +73,25 @@ close_stdout_set_file_name (const char *file)
void
close_stdout (void)
{
int e = ferror (stdout) ? 0 : -1;
bool prev_fail = ferror (stdout);
bool none_pending = (0 == __fpending (stdout));
bool fclose_fail = fclose (stdout);
if (fclose (stdout) != 0)
e = errno;
if (0 <= e)
if (prev_fail || fclose_fail)
{
char const *write_error = _("write error");
int e = fclose_fail ? errno : 0;
char const *write_error;
/* If ferror returned zero, no data remains to be flushed, and we'd
otherwise fail with EBADF due to a failed fclose, then assume that
it's ok to ignore the fclose failure. That can happen when a
program like cp is invoked like this `cp a b >&-' (i.e., with
stdout closed) and doesn't generate any output (hence no previous
error and nothing to be flushed). */
if (e == EBADF && !prev_fail && none_pending)
return;
write_error = _("write error");
if (file_name)
error (exit_failure, e, "%s: %s", quotearg_colon (file_name),
write_error);