X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Ffclose.c;h=90ed653a0e536b5e8484ac1898096637c681854b;hb=a77413333408e54b8d6c4e19918098794cef4b4b;hp=c0dfa27e9fe0443ab22ac66beace09301d6e06c3;hpb=64a5e38bced6c8f5117efbed95cdfd8ca133ed54;p=gnulib.git diff --git a/lib/fclose.c b/lib/fclose.c index c0dfa27e9..90ed653a0 100644 --- a/lib/fclose.c +++ b/lib/fclose.c @@ -1,5 +1,5 @@ /* fclose replacement. - Copyright (C) 2008-2011 Free Software Foundation, Inc. + Copyright (C) 2008-2013 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -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); - if (result >= 0) + 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 */