bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

fwriteerror: add support for ignoring EBADF in fclose


From: Bruno Haible
Subject: fwriteerror: add support for ignoring EBADF in fclose
Date: Fri, 29 Sep 2006 15:42:44 +0200
User-agent: KMail/1.9.1

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  <address@hidden>

        * 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 <address@hidden>, 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 <address@hidden>, 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);
  }
  
  




reply via email to

[Prev in Thread] Current Thread [Next in Thread]