fclose: Support for MSVC 9.
authorBruno Haible <bruno@clisp.org>
Sun, 25 Sep 2011 10:10:10 +0000 (12:10 +0200)
committerBruno Haible <bruno@clisp.org>
Sun, 25 Sep 2011 10:10:10 +0000 (12:10 +0200)
* lib/fclose.c: Include msvc-inval.h.
(fclose_nothrow): New function.
(rpl_fclose): Use it.
* modules/fclose (Depends-on): Add msvc-inval.
* doc/posix-functions/fclose.texi: Mention the problem on MSVC.

ChangeLog
doc/posix-functions/fclose.texi
lib/fclose.c
modules/fclose

index c297087..cf28a2f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2011-09-25  Bruno Haible  <bruno@clisp.org>
+
+       fclose: Support for MSVC 9.
+       * lib/fclose.c: Include msvc-inval.h.
+       (fclose_nothrow): New function.
+       (rpl_fclose): Use it.
+       * modules/fclose (Depends-on): Add msvc-inval.
+       * doc/posix-functions/fclose.texi: Mention the problem on MSVC.
+
 2011-09-24  Paul Eggert  <eggert@cs.ucla.edu>
 
        dup2: minor simplifications
index 40a2052..3db9198 100644 (file)
@@ -13,6 +13,10 @@ On some platforms, this function fails to set the file position of a
 seekable input stream to the byte after the last one actually read:
 glibc 2.13, FreeBSD.
 @item
+This function crashes if the stream's file descriptor has already been
+closed on some platforms:
+MSVC 9.
+@item
 On Windows platforms (excluding Cygwin), @code{socket} and @code{accept}
 followed by @code{fdopen} do not return streams that can be closed by
 @code{fclose}.
index 27f6836..3abe2e8 100644 (file)
 #include <unistd.h>
 
 #include "freading.h"
+#include "msvc-inval.h"
+
+#undef fclose
+
+#if HAVE_MSVC_INVALID_PARAMETER_HANDLER
+static int
+fclose_nothrow (FILE *fp)
+{
+  int result;
+
+  TRY_MSVC_INVAL
+    {
+      result = fclose (fp);
+    }
+  CATCH_MSVC_INVAL
+    {
+      result = EOF;
+      errno = EBADF;
+    }
+  DONE_MSVC_INVAL;
+
+  return result;
+}
+#else
+# define fclose_nothrow fclose
+#endif
 
 /* Override fclose() to call the overridden fflush() or close().  */
 
 int
 rpl_fclose (FILE *fp)
-#undef fclose
 {
   int saved_errno = 0;
   int fd;
@@ -37,7 +62,7 @@ rpl_fclose (FILE *fp)
   /* Don't change behavior on memstreams.  */
   fd = fileno (fp);
   if (fd < 0)
-    return fclose (fp);
+    return fclose_nothrow (fp);
 
   /* We only need to flush the file if it is not reading or if it is
      seekable.  This only guarantees the file position of input files
@@ -55,7 +80,8 @@ rpl_fclose (FILE *fp)
   if (close (fd) < 0 && saved_errno == 0)
     saved_errno = errno;
 
-  fclose (fp); /* will fail with errno = EBADF, if we did not lose a race */
+  fclose_nothrow (fp); /* will fail with errno = EBADF,
+                          if we did not lose a race */
 
 #else /* !WINDOWS_SOCKETS */
   /* Call fclose() and invoke all hooks of the overridden close().  */
@@ -64,12 +90,12 @@ rpl_fclose (FILE *fp)
   /* Note about multithread-safety: There is a race condition here as well.
      Some other thread could open fd between our calls to fclose and
      _gl_unregister_fd.  */
-  result = fclose (fp);
+  result = fclose_nothrow (fp);
   if (result == 0)
     _gl_unregister_fd (fd);
 # else
   /* No race condition here.  */
-  result = fclose (fp);
+  result = fclose_nothrow (fp);
 # endif
 
 #endif /* !WINDOWS_SOCKETS */
index 85f63fe..3ceba90 100644 (file)
@@ -11,6 +11,7 @@ close           [test $REPLACE_FCLOSE = 1]
 fflush          [test $REPLACE_FCLOSE = 1]
 freading        [test $REPLACE_FCLOSE = 1]
 lseek           [test $REPLACE_FCLOSE = 1]
+msvc-inval      [test $REPLACE_FCLOSE = 1]
 
 configure.ac:
 gl_FUNC_FCLOSE