+2011-09-23 Bruno Haible <bruno@clisp.org>
+
+ read: Support for MSVC 9.
+ * lib/unistd.in.h (read): Replace also when GNULIB_UNISTD_H_NONBLOCKING
+ is not 1.
+ * lib/read.c (read_nothrow): New function.
+ (rpl_read): Define also when GNULIB_NONBLOCKING is not 1. Use
+ read_nothrow.
+ * m4/read.m4 (gl_FUNC_READ): Replace read if the platform has an
+ invalid parameter handler.
+ (gl_PREREQ_READ): New macro.
+ * modules/read (Depends-on): Add msvc-inval.
+ (configure.ac): Invoke gl_PREREQ_READ.
+ * doc/posix-functions/read.texi: Mention the problem on MSVC.
+
2011-09-23 Bruno Haible <bruno@clisp.org>
close: Support for MSVC 9.
Portability problems fixed by Gnulib module @code{stdio}, together with module @code{nonblocking}:
@itemize
@item
+This function crashes when invoked with invalid arguments on some platforms:
+MSVC 9.
+@item
When reading from a non-blocking pipe whose buffer is empty, this function
fails with @code{errno} being set to @code{EINVAL} instead of @code{EAGAIN} on
some platforms:
/* Specification. */
#include <unistd.h>
-/* Replace this function only if module 'nonblocking' is requested. */
-#if GNULIB_NONBLOCKING
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
-# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+# include <errno.h>
+# include <io.h>
-# include <errno.h>
-# include <io.h>
+# define WIN32_LEAN_AND_MEAN /* avoid including junk */
+# include <windows.h>
-# define WIN32_LEAN_AND_MEAN /* avoid including junk */
-# include <windows.h>
+# include "msvc-inval.h"
+# include "msvc-nothrow.h"
-# include "msvc-nothrow.h"
+# undef read
+
+# if HAVE_MSVC_INVALID_PARAMETER_HANDLER
+static inline int
+read_nothrow (int fd, void *buf, size_t count)
+{
+ int result;
+
+ TRY_MSVC_INVAL
+ {
+ result = read (fd, buf, count);
+ }
+ CATCH_MSVC_INVAL
+ {
+ result = -1;
+ errno = EBADF;
+ }
+ DONE_MSVC_INVAL;
+
+ return result;
+}
+# else
+# define read_nothrow read
+# endif
ssize_t
rpl_read (int fd, void *buf, size_t count)
-#undef read
{
- ssize_t ret = read (fd, buf, count);
+ ssize_t ret = read_nothrow (fd, buf, count);
+# if GNULIB_NONBLOCKING
if (ret < 0
&& GetLastError () == ERROR_NO_DATA)
{
errno = EAGAIN;
}
}
+# endif
+
return ret;
}
-# endif
#endif
/* Read up to COUNT bytes from file descriptor FD into the buffer starting
at BUF. See the POSIX:2008 specification
<http://pubs.opengroup.org/onlinepubs/9699919799/functions/read.html>. */
-# if @REPLACE_READ@ && @GNULIB_UNISTD_H_NONBLOCKING@
+# if @REPLACE_READ@
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef read
# define read rpl_read
-# read.m4 serial 2
+# read.m4 serial 3
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,
AC_DEFUN([gl_FUNC_READ],
[
AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
+ AC_REQUIRE([gl_MSVC_INVAL])
+ if test $HAVE_MSVC_INVALID_PARAMETER_HANDLER = 1; then
+ REPLACE_READ=1
+ fi
dnl This ifdef is just an optimization, to avoid performing a configure
dnl check whose result is not used. It does not make the test of
dnl GNULIB_UNISTD_H_NONBLOCKING or GNULIB_NONBLOCKING redundant.
fi
])
])
+
+# Prerequisites of lib/read.c.
+AC_DEFUN([gl_PREREQ_READ],
+[
+ AC_REQUIRE([AC_C_INLINE])
+])
Depends-on:
unistd
+msvc-inval [test $REPLACE_READ = 1]
msvc-nothrow [test $REPLACE_READ = 1]
configure.ac:
gl_FUNC_READ
if test $REPLACE_READ = 1; then
AC_LIBOBJ([read])
+ gl_PREREQ_READ
fi
gl_UNISTD_MODULE_INDICATOR([read])