+2006-09-29 Bruno Haible <bruno@clisp.org>
+
+ * fwriteerror.h (fwriteerror_no_ebadf): New declaration.
+ * (do_fwriteerror): Renamed from fwriteerror. Add ignore_ebadf
+ argument. Set stdout_closed before testing for ferror, not after.
+ (fwriteerror, fwriteerror_no_ebadf): New functions.
+
2006-09-28 Bruno Haible <bruno@clisp.org>
* strndup.h: Simplify the redefinition of strndup.
#include <errno.h>
#include <stdbool.h>
-int
-fwriteerror (FILE *fp)
+static int
+do_fwriteerror (FILE *fp, bool ignore_ebadf)
{
/* State to allow multiple calls to fwriteerror (stdout). */
static bool stdout_closed = false;
- if (fp == stdout && stdout_closed)
- return 0;
+ if (fp == stdout)
+ {
+ if (stdout_closed)
+ return 0;
+
+ /* If we are closing stdout, don't attempt to do it later again. */
+ stdout_closed = true;
+ }
/* Need to
1. test the error indicator of the stream,
goto close_preserving_errno; /* errno is set here */
/* Give up on errno. */
errno = 0;
- close_preserving_errno:
- /* There's an error. Nevertheless call fclose(fp), for consistency
- with the other cases. */
- {
- int saved_errno = errno;
- fclose (fp);
- errno = saved_errno;
- return -1;
- }
+ goto close_preserving_errno;
}
- /* If we are closing stdout, don't attempt to do it later again. */
- if (fp == stdout)
- stdout_closed = true;
-
- if (fclose (fp))
- return -1; /* errno is set here */
+ if (ignore_ebadf)
+ {
+ /* We need an explicit fflush to tell whether some output was already
+ done on FP. */
+ if (fflush (fp))
+ goto close_preserving_errno; /* errno is set here */
+ if (fclose (fp) && errno != EBADF)
+ return -1; /* errno is set here */
+ }
+ else
+ {
+ if (fclose (fp))
+ return -1; /* errno is set here */
+ }
return 0;
+
+ close_preserving_errno:
+ /* There's an error. Nevertheless call fclose(fp), for consistency
+ with the other cases. */
+ {
+ int saved_errno = errno;
+ fclose (fp);
+ errno = saved_errno;
+ return -1;
+ }
+}
+
+int
+fwriteerror (FILE *fp)
+{
+ return do_fwriteerror (fp, false);
+}
+
+int
+fwriteerror_no_ebadf (FILE *fp)
+{
+ return do_fwriteerror (fp, true);
}
/* Detect write error on a stream.
- Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2005-2006 Free Software Foundation, Inc.
Written by Bruno Haible <bruno@clisp.org>, 2003.
This program is free software; you can redistribute it and/or modify
For any given stream FP other than stdout, fwriteerror (FP) may only be
called once. */
extern int fwriteerror (FILE *fp);
+
+/* Likewise, but don't consider it an error if FP has an invalid file
+ descriptor and no output was done to FP. */
+extern int fwriteerror_no_ebadf (FILE *fp);