# HG changeset patch # User Bruno Haible # Date 1159537492 0 # Node ID de85bc61c2dc31c2f36731a8a452a2c043c5ceb3 # Parent 6fe5ab1621687cab7e1091448657f7e3d49a1734 New function fwriteerror_no_ebadf. diff --git a/lib/ChangeLog b/lib/ChangeLog --- 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 --- 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 @@ 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 (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 */ } - /* If we are closing stdout, don't attempt to do it later again. */ - if (fp == stdout) - stdout_closed = true; + return 0; - if (fclose (fp)) - return -1; /* errno is set here */ + 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; + } +} - return 0; +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 --- 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);