From 9347e00e6c9092517edc8e3aa101a6b76a92a99c Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Fri, 29 Sep 2006 13:44:52 +0000 Subject: [PATCH] New function fwriteerror_no_ebadf. --- lib/ChangeLog | 7 ++++++ lib/fwriteerror.c | 66 +++++++++++++++++++++++++++++++++++++++---------------- lib/fwriteerror.h | 6 ++++- 3 files changed, 59 insertions(+), 20 deletions(-) diff --git a/lib/ChangeLog b/lib/ChangeLog index 0738759c0..0b3f6c38d 100644 --- a/lib/ChangeLog +++ b/lib/ChangeLog @@ -1,3 +1,10 @@ +2006-09-29 Bruno Haible + + * 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 * strndup.h: Simplify the redefinition of strndup. diff --git a/lib/fwriteerror.c b/lib/fwriteerror.c index 4d4ad81b9..b3d6d2ae4 100644 --- a/lib/fwriteerror.c +++ b/lib/fwriteerror.c @@ -24,14 +24,20 @@ #include #include -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, @@ -56,25 +62,47 @@ fwriteerror (FILE *fp) 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); } diff --git a/lib/fwriteerror.h b/lib/fwriteerror.h index c823ef7f2..ebbe1be6c 100644 --- a/lib/fwriteerror.h +++ b/lib/fwriteerror.h @@ -1,5 +1,5 @@ /* 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 , 2003. This program is free software; you can redistribute it and/or modify @@ -49,3 +49,7 @@ 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); -- 2.11.0