Hi, I'm adding an alternative entry point to the fwriteerror module. One that allows to ignore EBADF if it occurs only in the final fclose, i.e. if the file descriptor had not been written and was not connected from the beginning.
2006-09-29 Bruno Haible <[EMAIL PROTECTED]> * 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. diff -c -3 -r1.3 fwriteerror.h *** fwriteerror.h 14 May 2005 06:03:58 -0000 1.3 --- fwriteerror.h 29 Sep 2006 13:41:32 -0000 *************** *** 1,5 **** /* Detect write error on a stream. ! Copyright (C) 2003, 2005 Free Software Foundation, Inc. Written by Bruno Haible <[EMAIL PROTECTED]>, 2003. This program is free software; you can redistribute it and/or modify --- 1,5 ---- /* Detect write error on a stream. ! Copyright (C) 2003, 2005-2006 Free Software Foundation, Inc. Written by Bruno Haible <[EMAIL PROTECTED]>, 2003. This program is free software; you can redistribute it and/or modify *************** *** 49,51 **** --- 49,55 ---- 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); diff -c -3 -r1.6 fwriteerror.c *** fwriteerror.c 14 Sep 2006 14:18:36 -0000 1.6 --- fwriteerror.c 29 Sep 2006 13:41:32 -0000 *************** *** 24,37 **** #include <errno.h> #include <stdbool.h> ! int ! fwriteerror (FILE *fp) { /* State to allow multiple calls to fwriteerror (stdout). */ static bool stdout_closed = false; ! if (fp == stdout && stdout_closed) ! return 0; /* Need to 1. test the error indicator of the stream, --- 24,43 ---- #include <errno.h> #include <stdbool.h> ! 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) ! { ! 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,80 **** 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; ! } } ! /* 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 */ return 0; } --- 62,108 ---- goto close_preserving_errno; /* errno is set here */ /* Give up on errno. */ errno = 0; ! 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 */ ! } 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); }