From: Bruno Haible Date: Sun, 25 Sep 2011 10:10:10 +0000 (+0200) Subject: fclose: Support for MSVC 9. X-Git-Tag: v0.1~1747 X-Git-Url: http://erislabs.net/gitweb/?a=commitdiff_plain;h=fd860ad1280680d2fb0dcf795579767e28a91d06;hp=936cef69b1e34a2f654de30577cce8bf6db461b5;p=gnulib.git 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. --- diff --git a/ChangeLog b/ChangeLog index c29708733..cf28a2fa8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-09-25 Bruno Haible + + 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 dup2: minor simplifications diff --git a/doc/posix-functions/fclose.texi b/doc/posix-functions/fclose.texi index 40a205289..3db9198da 100644 --- a/doc/posix-functions/fclose.texi +++ b/doc/posix-functions/fclose.texi @@ -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}. diff --git a/lib/fclose.c b/lib/fclose.c index 27f683658..3abe2e85c 100644 --- a/lib/fclose.c +++ b/lib/fclose.c @@ -23,12 +23,37 @@ #include #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 */ diff --git a/modules/fclose b/modules/fclose index 85f63fe44..3ceba909d 100644 --- a/modules/fclose +++ b/modules/fclose @@ -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