changeset 15752:b86e9061a6d0

New module 'msvc-nothrow'. Makes _get_osfhandle safe on MSVC 9. * lib/msvc-nothrow.h: New file. * lib/msvc-nothrow.c: New file. * m4/msvc-nothrow.m4: New file. * modules/msvc-nothrow: New file. * lib/dup2.c: Include msvc-nothrow.h. (rpl_dup2): No need to protect _get_osfhandle call here. * lib/accept4.c: Include msvc-nothrow.h. * lib/error.c: Likewise. * lib/fcntl.c: Likewise. * lib/lseek.c: Likewise. * lib/nonblocking.c: Likewise. * lib/poll.c: Likewise. * lib/read.c: Likewise. * lib/select.c: Likewise. * lib/sockets.h: Likewise. * lib/sockets.c: Likewise. * lib/stdio-read.c: Likewise. * lib/stdio-write.c: Likewise. * lib/write.c: Likewise. * lib/w32sock.h: Likewise. * lib/w32spawn.h: Likewise. * lib/flock.c: Include msvc-nothrow.h instead of <io.h>. * lib/fsync.c: Likewise. * lib/isapipe.c: Likewise. * modules/dup2 (Depends-on): Add msvc-nothrow. * modules/accept4 (Depends-on): Likewise. * modules/error (Depends-on): Likewise. * modules/fcntl (Depends-on): Likewise. * modules/lseek (Depends-on): Likewise. * modules/nonblocking (Depends-on): Likewise. * modules/poll (Depends-on): Likewise. * modules/read (Depends-on): Likewise. * modules/select (Depends-on): Likewise. * modules/sockets (Depends-on): Likewise. * modules/sigpipe (Depends-on): Likewise. * modules/write (Depends-on): Likewise. * modules/accept (Depends-on): Likewise. * modules/bind (Depends-on): Likewise. * modules/connect (Depends-on): Likewise. * modules/gethostname (Depends-on): Likewise. * modules/getpeername (Depends-on): Likewise. * modules/getsockname (Depends-on): Likewise. * modules/getsockopt (Depends-on): Likewise. * modules/ioctl (Depends-on): Likewise. * modules/listen (Depends-on): Likewise. * modules/recv (Depends-on): Likewise. * modules/recvfrom (Depends-on): Likewise. * modules/send (Depends-on): Likewise. * modules/sendto (Depends-on): Likewise. * modules/setsockopt (Depends-on): Likewise. * modules/shutdown (Depends-on): Likewise. * modules/socket (Depends-on): Likewise. * modules/execute (Depends-on): Likewise. * modules/spawn-pipe (Depends-on): Likewise. * modules/flock (Depends-on): Likewise. * modules/fsync (Depends-on): Likewise. * modules/isapipe (Depends-on): Likewise. * tests/test-cloexec.c: Include msvc-nothrow.h. * tests/test-dup-safer.c: Likewise. * tests/test-dup2.c: Likewise. * tests/test-dup3.c: Likewise. * tests/test-fcntl.c: Likewise. * tests/test-pipe.c: Likewise. * tests/test-pipe2.c: Likewise. * modules/cloexec-tests (Depends-on): Add msvc-nothrow. * modules/unistd-safer-tests (Depends-on): Likewise. * modules/dup2-tests (Depends-on): Likewise. * modules/dup3-tests (Depends-on): Likewise. * modules/fcntl-tests (Depends-on): Likewise. * modules/pipe-posix-tests (Depends-on): Likewise. * modules/pipe2-tests (Depends-on): Likewise.
author Bruno Haible <bruno@clisp.org>
date Fri, 23 Sep 2011 21:38:44 +0200
parents 6cad6a3713b8
children ebd508fbaab8
files ChangeLog lib/accept4.c lib/dup2.c lib/error.c lib/fcntl.c lib/flock.c lib/fsync.c lib/isapipe.c lib/lseek.c lib/msvc-nothrow.c lib/msvc-nothrow.h lib/nonblocking.c lib/poll.c lib/read.c lib/select.c lib/sockets.c lib/sockets.h lib/stdio-read.c lib/stdio-write.c lib/w32sock.h lib/w32spawn.h lib/write.c m4/msvc-nothrow.m4 modules/accept modules/accept4 modules/bind modules/cloexec-tests modules/connect modules/dup2 modules/dup2-tests modules/dup3-tests modules/error modules/execute modules/fcntl modules/fcntl-tests modules/flock modules/fsync modules/gethostname modules/getpeername modules/getsockname modules/getsockopt modules/ioctl modules/isapipe modules/listen modules/lseek modules/msvc-nothrow modules/nonblocking modules/pipe-posix-tests modules/pipe2-tests modules/poll modules/read modules/recv modules/recvfrom modules/select modules/send modules/sendto modules/setsockopt modules/shutdown modules/sigpipe modules/socket modules/sockets modules/spawn-pipe modules/unistd-safer-tests modules/write tests/test-cloexec.c tests/test-dup-safer.c tests/test-dup2.c tests/test-dup3.c tests/test-fcntl.c tests/test-pipe.c tests/test-pipe2.c
diffstat 71 files changed, 305 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,78 @@
+2011-09-23  Bruno Haible  <bruno@clisp.org>
+
+	New module 'msvc-nothrow'. Makes _get_osfhandle safe on MSVC 9.
+	* lib/msvc-nothrow.h: New file.
+	* lib/msvc-nothrow.c: New file.
+	* m4/msvc-nothrow.m4: New file.
+	* modules/msvc-nothrow: New file.
+	* lib/dup2.c: Include msvc-nothrow.h.
+	(rpl_dup2): No need to protect _get_osfhandle call here.
+	* lib/accept4.c: Include msvc-nothrow.h.
+	* lib/error.c: Likewise.
+	* lib/fcntl.c: Likewise.
+	* lib/lseek.c: Likewise.
+	* lib/nonblocking.c: Likewise.
+	* lib/poll.c: Likewise.
+	* lib/read.c: Likewise.
+	* lib/select.c: Likewise.
+	* lib/sockets.h: Likewise.
+	* lib/sockets.c: Likewise.
+	* lib/stdio-read.c: Likewise.
+	* lib/stdio-write.c: Likewise.
+	* lib/write.c: Likewise.
+	* lib/w32sock.h: Likewise.
+	* lib/w32spawn.h: Likewise.
+	* lib/flock.c: Include msvc-nothrow.h instead of <io.h>.
+	* lib/fsync.c: Likewise.
+	* lib/isapipe.c: Likewise.
+	* modules/dup2 (Depends-on): Add msvc-nothrow.
+	* modules/accept4 (Depends-on): Likewise.
+	* modules/error (Depends-on): Likewise.
+	* modules/fcntl (Depends-on): Likewise.
+	* modules/lseek (Depends-on): Likewise.
+	* modules/nonblocking (Depends-on): Likewise.
+	* modules/poll (Depends-on): Likewise.
+	* modules/read (Depends-on): Likewise.
+	* modules/select (Depends-on): Likewise.
+	* modules/sockets (Depends-on): Likewise.
+	* modules/sigpipe (Depends-on): Likewise.
+	* modules/write (Depends-on): Likewise.
+	* modules/accept (Depends-on): Likewise.
+	* modules/bind (Depends-on): Likewise.
+	* modules/connect (Depends-on): Likewise.
+	* modules/gethostname (Depends-on): Likewise.
+	* modules/getpeername (Depends-on): Likewise.
+	* modules/getsockname (Depends-on): Likewise.
+	* modules/getsockopt (Depends-on): Likewise.
+	* modules/ioctl (Depends-on): Likewise.
+	* modules/listen (Depends-on): Likewise.
+	* modules/recv (Depends-on): Likewise.
+	* modules/recvfrom (Depends-on): Likewise.
+	* modules/send (Depends-on): Likewise.
+	* modules/sendto (Depends-on): Likewise.
+	* modules/setsockopt (Depends-on): Likewise.
+	* modules/shutdown (Depends-on): Likewise.
+	* modules/socket (Depends-on): Likewise.
+	* modules/execute (Depends-on): Likewise.
+	* modules/spawn-pipe (Depends-on): Likewise.
+	* modules/flock (Depends-on): Likewise.
+	* modules/fsync (Depends-on): Likewise.
+	* modules/isapipe (Depends-on): Likewise.
+	* tests/test-cloexec.c: Include msvc-nothrow.h.
+	* tests/test-dup-safer.c: Likewise.
+	* tests/test-dup2.c: Likewise.
+	* tests/test-dup3.c: Likewise.
+	* tests/test-fcntl.c: Likewise.
+	* tests/test-pipe.c: Likewise.
+	* tests/test-pipe2.c: Likewise.
+	* modules/cloexec-tests (Depends-on): Add msvc-nothrow.
+	* modules/unistd-safer-tests (Depends-on): Likewise.
+	* modules/dup2-tests (Depends-on): Likewise.
+	* modules/dup3-tests (Depends-on): Likewise.
+	* modules/fcntl-tests (Depends-on): Likewise.
+	* modules/pipe-posix-tests (Depends-on): Likewise.
+	* modules/pipe2-tests (Depends-on): Likewise.
+
 2011-09-23  Bruno Haible  <bruno@clisp.org>
 
 	dup2: Make code more maintainable.
--- a/lib/accept4.c
+++ b/lib/accept4.c
@@ -23,6 +23,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include "binary-io.h"
+#include "msvc-nothrow.h"
 
 #ifndef SOCK_CLOEXEC
 # define SOCK_CLOEXEC 0
--- a/lib/dup2.c
+++ b/lib/dup2.c
@@ -29,6 +29,8 @@
 /* Get declarations of the Win32 API functions.  */
 # define WIN32_LEAN_AND_MEAN
 # include <windows.h>
+/* Get _get_osfhandle.  */
+# include "msvc-nothrow.h"
 #endif
 
 #include "msvc-inval.h"
@@ -70,19 +72,7 @@
      future dup2 calls will hang.  */
   if (fd == desired_fd)
     {
-      HANDLE handle;
-
-      TRY_MSVC_INVAL
-        {
-          handle = (HANDLE) _get_osfhandle (fd);
-        }
-      CATCH_MSVC_INVAL
-        {
-          handle = INVALID_HANDLE_VALUE;
-        }
-      DONE_MSVC_INVAL;
-
-      if (handle == INVALID_HANDLE_VALUE)
+      if ((HANDLE) _get_osfhandle (fd) == INVALID_HANDLE_VALUE)
         {
           errno = EBADF;
           return -1;
--- a/lib/error.c
+++ b/lib/error.c
@@ -92,6 +92,8 @@
 /* Get declarations of the Win32 API functions.  */
 #  define WIN32_LEAN_AND_MEAN
 #  include <windows.h>
+/* Get _get_osfhandle.  */
+#  include "msvc-nothrow.h"
 # endif
 
 /* The gnulib override of fcntl is not needed in this file.  */
--- a/lib/fcntl.c
+++ b/lib/fcntl.c
@@ -37,6 +37,9 @@
 # define WIN32_LEAN_AND_MEAN
 # include <windows.h>
 
+/* Get _get_osfhandle.  */
+# include "msvc-nothrow.h"
+
 /* Upper bound on getdtablesize().  See lib/getdtablesize.c.  */
 # define OPEN_MAX_MAX 0x10000
 
--- a/lib/flock.c
+++ b/lib/flock.c
@@ -26,15 +26,15 @@
 
 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
 
-/* _get_osfhandle */
-# include <io.h>
-
 /* LockFileEx */
 # define WIN32_LEAN_AND_MEAN
 # include <windows.h>
 
 # include <errno.h>
 
+/* _get_osfhandle */
+# include "msvc-nothrow.h"
+
 /* Determine the current size of a file.  Because the other braindead
  * APIs we'll call need lower/upper 32 bit pairs, keep the file size
  * like that too.
--- a/lib/fsync.c
+++ b/lib/fsync.c
@@ -27,15 +27,15 @@
 
 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
 
-/* _get_osfhandle */
-# include <io.h>
-
 /* FlushFileBuffers */
 # define WIN32_LEAN_AND_MEAN
 # include <windows.h>
 
 # include <errno.h>
 
+/* Get _get_osfhandle.  */
+# include "msvc-nothrow.h"
+
 int
 fsync (int fd)
 {
--- a/lib/isapipe.c
+++ b/lib/isapipe.c
@@ -26,12 +26,12 @@
 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
 /* Windows platforms.  */
 
-/* Get _get_osfhandle.  */
-# include <io.h>
-
 /* Get GetFileType.  */
 # include <windows.h>
 
+/* Get _get_osfhandle.  */
+# include "msvc-nothrow.h"
+
 int
 isapipe (int fd)
 {
--- a/lib/lseek.c
+++ b/lib/lseek.c
@@ -24,6 +24,8 @@
 /* Windows platforms.  */
 /* Get GetFileType.  */
 # include <windows.h>
+/* Get _get_osfhandle.  */
+# include "msvc-nothrow.h"
 #else
 # include <sys/stat.h>
 #endif
new file mode 100644
--- /dev/null
+++ b/lib/msvc-nothrow.c
@@ -0,0 +1,50 @@
+/* Wrappers that don't throw invalid parameter notifications
+   with MSVC runtime libraries.
+   Copyright (C) 2011 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
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along
+   with this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include "msvc-nothrow.h"
+
+/* Get declarations of the Win32 API functions.  */
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#include "msvc-inval.h"
+
+#undef _get_osfhandle
+
+#if HAVE_MSVC_INVALID_PARAMETER_HANDLER
+intptr_t
+_gl_nothrow_get_osfhandle (int fd)
+{
+  intptr_t result;
+
+  TRY_MSVC_INVAL
+    {
+      result = _get_osfhandle (fd);
+    }
+  CATCH_MSVC_INVAL
+    {
+      result = INVALID_HANDLE_VALUE;
+    }
+  DONE_MSVC_INVAL;
+
+  return result;
+}
+#endif
new file mode 100644
--- /dev/null
+++ b/lib/msvc-nothrow.h
@@ -0,0 +1,44 @@
+/* Wrappers that don't throw invalid parameter notifications
+   with MSVC runtime libraries.
+   Copyright (C) 2011 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
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along
+   with this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#ifndef _MSVC_NOTHROW_H
+#define _MSVC_NOTHROW_H
+
+/* With MSVC runtime libraries with the "invalid parameter handler" concept,
+   functions like fprintf(), dup2(), or close() crash when the caller passes
+   an invalid argument.  But POSIX wants error codes (such as EINVAL or EBADF)
+   instead.
+   This file defines wrappers that turn such an invalid parameter notification
+   into an error code.  */
+
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+
+/* Get original declaration of _get_osfhandle.  */
+# include <io.h>
+
+# if HAVE_MSVC_INVALID_PARAMETER_HANDLER
+
+/* Override _get_osfhandle.  */
+extern intptr_t _gl_nothrow_get_osfhandle (int fd);
+#  define _get_osfhandle _gl_nothrow_get_osfhandle
+
+# endif
+
+#endif
+
+#endif /* _MSVC_NOTHROW_H */
--- a/lib/nonblocking.c
+++ b/lib/nonblocking.c
@@ -32,6 +32,8 @@
 # define WIN32_LEAN_AND_MEAN
 # include <windows.h>
 
+# include "msvc-nothrow.h"
+
 int
 get_nonblocking_flag (int desc)
 {
--- a/lib/poll.c
+++ b/lib/poll.c
@@ -43,6 +43,7 @@
 # include <io.h>
 # include <stdio.h>
 # include <conio.h>
+# include "msvc-nothrow.h"
 #else
 # include <sys/time.h>
 # include <sys/socket.h>
--- a/lib/read.c
+++ b/lib/read.c
@@ -31,6 +31,8 @@
 #  define WIN32_LEAN_AND_MEAN  /* avoid including junk */
 #  include <windows.h>
 
+#  include "msvc-nothrow.h"
+
 ssize_t
 rpl_read (int fd, void *buf, size_t count)
 #undef read
--- a/lib/select.c
+++ b/lib/select.c
@@ -37,6 +37,8 @@
 #include <conio.h>
 #include <time.h>
 
+#include "msvc-nothrow.h"
+
 struct bitset {
   unsigned char in[FD_SETSIZE / CHAR_BIT];
   unsigned char out[FD_SETSIZE / CHAR_BIT];
--- a/lib/sockets.c
+++ b/lib/sockets.c
@@ -28,6 +28,7 @@
 # include <sys/socket.h>
 
 # include "fd-hook.h"
+# include "msvc-nothrow.h"
 
 /* Get set_winsock_errno, FD_TO_SOCKET etc. */
 # include "w32sock.h"
--- a/lib/sockets.h
+++ b/lib/sockets.h
@@ -36,6 +36,8 @@
 
 #include <sys/socket.h>
 
+#include "msvc-nothrow.h"
+
 static inline SOCKET
 gl_fd_to_handle (int fd)
 {
--- a/lib/stdio-read.c
+++ b/lib/stdio-read.c
@@ -37,6 +37,8 @@
 #  define WIN32_LEAN_AND_MEAN  /* avoid including junk */
 #  include <windows.h>
 
+#  include "msvc-nothrow.h"
+
 #  define CALL_WITH_ERRNO_FIX(RETTYPE, EXPRESSION, FAILED) \
   if (ferror (stream))                                                        \
     return (EXPRESSION);                                                      \
--- a/lib/stdio-write.c
+++ b/lib/stdio-write.c
@@ -39,6 +39,8 @@
 #  define WIN32_LEAN_AND_MEAN  /* avoid including junk */
 #  include <windows.h>
 
+#  include "msvc-nothrow.h"
+
 #  if GNULIB_NONBLOCKING
 #   define CLEAR_ERRNO \
       errno = 0;
--- a/lib/w32sock.h
+++ b/lib/w32sock.h
@@ -22,9 +22,12 @@
 /* Get O_RDWR and O_BINARY.  */
 #include <fcntl.h>
 
-/* Get _get_osfhandle() and _open_osfhandle().  */
+/* Get _open_osfhandle().  */
 #include <io.h>
 
+/* Get _get_osfhandle().  */
+#include "msvc-nothrow.h"
+
 #define FD_TO_SOCKET(fd)   ((SOCKET) _get_osfhandle ((fd)))
 #define SOCKET_TO_FD(fh)   (_open_osfhandle ((long) (fh), O_RDWR | O_BINARY))
 
--- a/lib/w32spawn.h
+++ b/lib/w32spawn.h
@@ -19,7 +19,7 @@
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
 
-/* Get _get_osfhandle() and _open_osfhandle().  */
+/* Get _open_osfhandle().  */
 #include <io.h>
 
 #include <stdbool.h>
@@ -27,6 +27,9 @@
 #include <unistd.h>
 #include <errno.h>
 
+/* Get _get_osfhandle().  */
+#include "msvc-nothrow.h"
+
 #include "cloexec.h"
 #include "xalloc.h"
 
--- a/lib/write.c
+++ b/lib/write.c
@@ -38,6 +38,8 @@
 #  define WIN32_LEAN_AND_MEAN  /* avoid including junk */
 #  include <windows.h>
 
+#  include "msvc-nothrow.h"
+
 ssize_t
 rpl_write (int fd, const void *buf, size_t count)
 #undef write
new file mode 100644
--- /dev/null
+++ b/m4/msvc-nothrow.m4
@@ -0,0 +1,10 @@
+# msvc-nothrow.m4 serial 1
+dnl Copyright (C) 2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_MSVC_NOTHROW],
+[
+  AC_REQUIRE([gl_MSVC_INVAL])
+])
--- a/modules/accept
+++ b/modules/accept
@@ -9,6 +9,7 @@
 sys_socket
 socketlib
 errno           [test "$ac_cv_header_winsock2_h" = yes]
+msvc-nothrow    [test "$ac_cv_header_winsock2_h" = yes]
 
 configure.ac:
 AC_REQUIRE([gl_HEADER_SYS_SOCKET])
--- a/modules/accept4
+++ b/modules/accept4
@@ -12,6 +12,7 @@
 fcntl-h
 binary-io
 extensions
+msvc-nothrow
 
 configure.ac:
 gl_FUNC_ACCEPT4
--- a/modules/bind
+++ b/modules/bind
@@ -9,6 +9,7 @@
 sys_socket
 socketlib
 errno           [test "$ac_cv_header_winsock2_h" = yes]
+msvc-nothrow    [test "$ac_cv_header_winsock2_h" = yes]
 
 configure.ac:
 AC_REQUIRE([gl_HEADER_SYS_SOCKET])
--- a/modules/cloexec-tests
+++ b/modules/cloexec-tests
@@ -4,6 +4,7 @@
 
 Depends-on:
 binary-io
+msvc-nothrow
 
 configure.ac:
 
--- a/modules/connect
+++ b/modules/connect
@@ -9,6 +9,7 @@
 sys_socket
 socketlib
 errno           [test "$ac_cv_header_winsock2_h" = yes]
+msvc-nothrow    [test "$ac_cv_header_winsock2_h" = yes]
 
 configure.ac:
 AC_REQUIRE([gl_HEADER_SYS_SOCKET])
--- a/modules/dup2
+++ b/modules/dup2
@@ -9,6 +9,7 @@
 unistd
 dup2-obsolete
 msvc-inval      [test $HAVE_DUP2 = 0 || test $REPLACE_DUP2 = 1]
+msvc-nothrow    [test $HAVE_DUP2 = 0 || test $REPLACE_DUP2 = 1]
 
 configure.ac:
 gl_FUNC_DUP2
--- a/modules/dup2-tests
+++ b/modules/dup2-tests
@@ -5,6 +5,7 @@
 
 Depends-on:
 binary-io
+msvc-nothrow
 open
 
 configure.ac:
--- a/modules/dup3-tests
+++ b/modules/dup3-tests
@@ -4,6 +4,7 @@
 tests/macros.h
 
 Depends-on:
+msvc-nothrow
 open
 
 configure.ac:
--- a/modules/error
+++ b/modules/error
@@ -14,6 +14,7 @@
 Depends-on:
 strerror        [test $ac_cv_lib_error_at_line = no]
 unistd          [test $ac_cv_lib_error_at_line = no]
+msvc-nothrow    [test $ac_cv_lib_error_at_line = no]
 
 configure.ac:
 gl_ERROR
--- a/modules/execute
+++ b/modules/execute
@@ -14,6 +14,7 @@
 fatal-signal
 wait-process
 gettext-h
+msvc-nothrow
 spawn
 posix_spawnp
 posix_spawn_file_actions_init
--- a/modules/fcntl
+++ b/modules/fcntl
@@ -10,6 +10,7 @@
 extensions
 dup2            [test $HAVE_FCNTL = 0 || test $REPLACE_FCNTL = 1]
 getdtablesize   [test $HAVE_FCNTL = 0 || test $REPLACE_FCNTL = 1]
+msvc-nothrow    [test $HAVE_FCNTL = 0 || test $REPLACE_FCNTL = 1]
 
 configure.ac:
 gl_FUNC_FCNTL
--- a/modules/fcntl-tests
+++ b/modules/fcntl-tests
@@ -6,6 +6,7 @@
 Depends-on:
 binary-io
 getdtablesize
+msvc-nothrow
 stdbool
 
 configure.ac:
--- a/modules/flock
+++ b/modules/flock
@@ -7,6 +7,7 @@
 
 Depends-on:
 sys_file
+msvc-nothrow    [test $HAVE_FLOCK = 0]
 
 configure.ac:
 gl_FUNC_FLOCK
--- a/modules/fsync
+++ b/modules/fsync
@@ -7,6 +7,7 @@
 
 Depends-on:
 unistd
+msvc-nothrow    [test $HAVE_FSYNC = 0]
 
 configure.ac:
 gl_FUNC_FSYNC
--- a/modules/gethostname
+++ b/modules/gethostname
@@ -11,6 +11,7 @@
 sys_socket      [test $HAVE_GETHOSTNAME = 0]
 errno           [test $HAVE_GETHOSTNAME = 0]
 sockets         [test $HAVE_GETHOSTNAME = 0]
+msvc-nothrow    [test $HAVE_GETHOSTNAME = 0]
 
 configure.ac:
 gl_FUNC_GETHOSTNAME
--- a/modules/getpeername
+++ b/modules/getpeername
@@ -10,6 +10,7 @@
 sys_socket
 socketlib
 errno           [test "$ac_cv_header_winsock2_h" = yes]
+msvc-nothrow    [test "$ac_cv_header_winsock2_h" = yes]
 
 configure.ac:
 AC_REQUIRE([gl_HEADER_SYS_SOCKET])
--- a/modules/getsockname
+++ b/modules/getsockname
@@ -10,6 +10,7 @@
 sys_socket
 socketlib
 errno           [test "$ac_cv_header_winsock2_h" = yes]
+msvc-nothrow    [test "$ac_cv_header_winsock2_h" = yes]
 
 configure.ac:
 AC_REQUIRE([gl_HEADER_SYS_SOCKET])
--- a/modules/getsockopt
+++ b/modules/getsockopt
@@ -10,6 +10,7 @@
 socketlib
 sys_time        [test "$ac_cv_header_winsock2_h" = yes]
 errno           [test "$ac_cv_header_winsock2_h" = yes]
+msvc-nothrow    [test "$ac_cv_header_winsock2_h" = yes]
 
 configure.ac:
 AC_REQUIRE([gl_HEADER_SYS_SOCKET])
--- a/modules/ioctl
+++ b/modules/ioctl
@@ -11,6 +11,7 @@
 sys_socket      [test $HAVE_IOCTL = 0 || test $REPLACE_IOCTL = 1]
 errno           [test $HAVE_IOCTL = 0 || test $REPLACE_IOCTL = 1]
 fd-hook         [test $HAVE_IOCTL = 0 || test $REPLACE_IOCTL = 1]
+msvc-nothrow    [test $HAVE_IOCTL = 0 || test $REPLACE_IOCTL = 1]
 
 configure.ac:
 gl_FUNC_IOCTL
--- a/modules/isapipe
+++ b/modules/isapipe
@@ -10,6 +10,7 @@
 stdbool         [test $HAVE_ISAPIPE = 0]
 sys_stat        [test $HAVE_ISAPIPE = 0]
 unistd          [test $HAVE_ISAPIPE = 0]
+msvc-nothrow    [test $HAVE_ISAPIPE = 0]
 
 configure.ac:
 gl_ISAPIPE
--- a/modules/listen
+++ b/modules/listen
@@ -9,6 +9,7 @@
 sys_socket
 socketlib
 errno           [test "$ac_cv_header_winsock2_h" = yes]
+msvc-nothrow    [test "$ac_cv_header_winsock2_h" = yes]
 
 configure.ac:
 AC_REQUIRE([gl_HEADER_SYS_SOCKET])
--- a/modules/lseek
+++ b/modules/lseek
@@ -8,6 +8,7 @@
 Depends-on:
 unistd
 largefile
+msvc-nothrow    [test $REPLACE_LSEEK = 1]
 
 configure.ac:
 gl_FUNC_LSEEK
new file mode 100644
--- /dev/null
+++ b/modules/msvc-nothrow
@@ -0,0 +1,28 @@
+Description:
+wrappers that don't throw invalid parameter notifications with MSVC runtime
+libraries
+
+Files:
+lib/msvc-nothrow.h
+lib/msvc-nothrow.c
+m4/msvc-nothrow.m4
+
+Depends-on:
+msvc-inval
+
+configure.ac:
+gl_MSVC_NOTHROW
+if test $HAVE_MSVC_INVALID_PARAMETER_HANDLER = 1; then
+  AC_LIBOBJ([msvc-nothrow])
+fi
+
+Makefile.am:
+
+Include:
+"msvc-nothrow.h"
+
+License:
+LGPLv2+
+
+Maintainer:
+Bruno Haible
--- a/modules/nonblocking
+++ b/modules/nonblocking
@@ -12,6 +12,7 @@
 Depends-on:
 fcntl-h
 ioctl
+msvc-nothrow
 stdbool
 stdio
 sys_socket
--- a/modules/pipe-posix-tests
+++ b/modules/pipe-posix-tests
@@ -6,6 +6,7 @@
 Depends-on:
 stdbool
 binary-io
+msvc-nothrow
 
 configure.ac:
 
--- a/modules/pipe2-tests
+++ b/modules/pipe2-tests
@@ -5,6 +5,7 @@
 
 Depends-on:
 stdbool
+msvc-nothrow
 
 configure.ac:
 
--- a/modules/poll
+++ b/modules/poll
@@ -12,6 +12,7 @@
 sys_select      [test $HAVE_POLL = 0 || test $REPLACE_POLL = 1]
 sys_time        [test $HAVE_POLL = 0 || test $REPLACE_POLL = 1]
 errno           [test $HAVE_POLL = 0 || test $REPLACE_POLL = 1]
+msvc-nothrow    [test $HAVE_POLL = 0 || test $REPLACE_POLL = 1]
 
 configure.ac:
 gl_FUNC_POLL
--- a/modules/read
+++ b/modules/read
@@ -7,6 +7,7 @@
 
 Depends-on:
 unistd
+msvc-nothrow    [test $REPLACE_READ = 1]
 
 configure.ac:
 gl_FUNC_READ
--- a/modules/recv
+++ b/modules/recv
@@ -9,6 +9,7 @@
 sys_socket
 socketlib
 errno           [test "$ac_cv_header_winsock2_h" = yes]
+msvc-nothrow    [test "$ac_cv_header_winsock2_h" = yes]
 
 configure.ac:
 AC_REQUIRE([gl_HEADER_SYS_SOCKET])
--- a/modules/recvfrom
+++ b/modules/recvfrom
@@ -10,6 +10,7 @@
 socketlib
 errno           [test "$ac_cv_header_winsock2_h" = yes]
 getpeername     [test "$ac_cv_header_winsock2_h" = yes]
+msvc-nothrow    [test "$ac_cv_header_winsock2_h" = yes]
 
 configure.ac:
 AC_REQUIRE([gl_HEADER_SYS_SOCKET])
--- a/modules/select
+++ b/modules/select
@@ -9,6 +9,7 @@
 sys_select
 alloca          [test $REPLACE_SELECT = 1]
 sockets         [test $REPLACE_SELECT = 1]
+msvc-nothrow    [test $REPLACE_SELECT = 1]
 
 configure.ac:
 gl_FUNC_SELECT
--- a/modules/send
+++ b/modules/send
@@ -9,6 +9,7 @@
 sys_socket
 socketlib
 errno           [test "$ac_cv_header_winsock2_h" = yes]
+msvc-nothrow    [test "$ac_cv_header_winsock2_h" = yes]
 
 configure.ac:
 AC_REQUIRE([gl_HEADER_SYS_SOCKET])
--- a/modules/sendto
+++ b/modules/sendto
@@ -9,6 +9,7 @@
 sys_socket
 socketlib
 errno           [test "$ac_cv_header_winsock2_h" = yes]
+msvc-nothrow    [test "$ac_cv_header_winsock2_h" = yes]
 
 configure.ac:
 AC_REQUIRE([gl_HEADER_SYS_SOCKET])
--- a/modules/setsockopt
+++ b/modules/setsockopt
@@ -10,6 +10,7 @@
 socketlib
 sys_time        [test "$ac_cv_header_winsock2_h" = yes]
 errno           [test "$ac_cv_header_winsock2_h" = yes]
+msvc-nothrow    [test "$ac_cv_header_winsock2_h" = yes]
 
 configure.ac:
 AC_REQUIRE([gl_HEADER_SYS_SOCKET])
--- a/modules/shutdown
+++ b/modules/shutdown
@@ -9,6 +9,7 @@
 sys_socket
 socketlib
 errno           [test "$ac_cv_header_winsock2_h" = yes]
+msvc-nothrow    [test "$ac_cv_header_winsock2_h" = yes]
 
 configure.ac:
 AC_REQUIRE([gl_HEADER_SYS_SOCKET])
--- a/modules/sigpipe
+++ b/modules/sigpipe
@@ -12,6 +12,7 @@
 m4/asm-underscore.m4
 
 Depends-on:
+msvc-nothrow
 raise
 signal
 sigprocmask
--- a/modules/socket
+++ b/modules/socket
@@ -10,6 +10,7 @@
 socketlib
 errno           [test "$ac_cv_header_winsock2_h" = yes]
 sockets         [test "$ac_cv_header_winsock2_h" = yes]
+msvc-nothrow    [test "$ac_cv_header_winsock2_h" = yes]
 
 configure.ac:
 AC_REQUIRE([gl_HEADER_SYS_SOCKET])
--- a/modules/sockets
+++ b/modules/sockets
@@ -11,6 +11,7 @@
 socketlib
 sys_socket
 fd-hook
+msvc-nothrow
 
 configure.ac:
 gl_SOCKETS
--- a/modules/spawn-pipe
+++ b/modules/spawn-pipe
@@ -14,6 +14,7 @@
 error
 fatal-signal
 gettext-h
+msvc-nothrow
 open
 pipe2
 pipe2-safer
--- a/modules/unistd-safer-tests
+++ b/modules/unistd-safer-tests
@@ -6,6 +6,7 @@
 binary-io
 cloexec
 fd-safer-flag
+msvc-nothrow
 stdbool
 
 configure.ac:
--- a/modules/write
+++ b/modules/write
@@ -8,6 +8,7 @@
 Depends-on:
 unistd
 raise           [test $REPLACE_WRITE = 1]
+msvc-nothrow    [test $REPLACE_WRITE = 1]
 
 configure.ac:
 gl_FUNC_WRITE
--- a/tests/test-cloexec.c
+++ b/tests/test-cloexec.c
@@ -28,6 +28,8 @@
 /* Get declarations of the Win32 API functions.  */
 # define WIN32_LEAN_AND_MEAN
 # include <windows.h>
+/* Get _get_osfhandle.  */
+# include "msvc-nothrow.h"
 #endif
 
 #include "binary-io.h"
--- a/tests/test-dup-safer.c
+++ b/tests/test-dup-safer.c
@@ -32,6 +32,8 @@
 /* Get declarations of the Win32 API functions.  */
 # define WIN32_LEAN_AND_MEAN
 # include <windows.h>
+/* Get _get_osfhandle.  */
+# include "msvc-nothrow.h"
 #endif
 
 #if !O_BINARY
--- a/tests/test-dup2.c
+++ b/tests/test-dup2.c
@@ -36,6 +36,8 @@
 /* Get declarations of the Win32 API functions.  */
 # define WIN32_LEAN_AND_MEAN
 # include <windows.h>
+/* Get _get_osfhandle.  */
+# include "msvc-nothrow.h"
 #endif
 
 #include "macros.h"
--- a/tests/test-dup3.c
+++ b/tests/test-dup3.c
@@ -32,6 +32,8 @@
 /* Get declarations of the Win32 API functions.  */
 # define WIN32_LEAN_AND_MEAN
 # include <windows.h>
+/* Get _get_osfhandle.  */
+# include "msvc-nothrow.h"
 #endif
 
 #include "binary-io.h"
--- a/tests/test-fcntl.c
+++ b/tests/test-fcntl.c
@@ -34,6 +34,8 @@
 /* Get declarations of the Win32 API functions.  */
 # define WIN32_LEAN_AND_MEAN
 # include <windows.h>
+/* Get _get_osfhandle.  */
+# include "msvc-nothrow.h"
 #endif
 
 #include "binary-io.h"
--- a/tests/test-pipe.c
+++ b/tests/test-pipe.c
@@ -29,6 +29,8 @@
 /* Get declarations of the Win32 API functions.  */
 # define WIN32_LEAN_AND_MEAN
 # include <windows.h>
+/* Get _get_osfhandle.  */
+# include "msvc-nothrow.h"
 #endif
 
 #include "binary-io.h"
--- a/tests/test-pipe2.c
+++ b/tests/test-pipe2.c
@@ -29,6 +29,8 @@
 /* Get declarations of the Win32 API functions.  */
 # define WIN32_LEAN_AND_MEAN
 # include <windows.h>
+/* Get _get_osfhandle.  */
+# include "msvc-nothrow.h"
 #endif
 
 #include "binary-io.h"