+2010-03-28 Bruno Haible <bruno@clisp.org>
+
+ Fix ioctl's protoype on glibc systems.
+ * lib/sys_ioctl.in.h (ioctl): If REPLACE_IOCTL is 1, use a wrapper. Use
+ _GL_CXXALIAS_SYS, not _GL_CXXALIAS_SYS_CAST.
+ * lib/ioctl.c (rpl_ioctl) [HAVE_IOCTL]: New wrapper.
+ * modules/ioctl (configure.ac): Test whether ioctl has the POSIX
+ signature. If not, arrange to replace the ioctl function.
+ * m4/sys_ioctl_h.m4 (gl_SYS_IOCTL_H_DEFAULTS): Initialize
+ REPLACE_IOCTL.
+ * modules/sys_ioctl (Makefile.am): Substitute REPLACE_IOCTL.
+ * doc/posix-functions/ioctl.texi: Mention the glibc problem.
+ Reported by Ludovic Courtès <ludo@gnu.org>.
+
2010-03-28 Javier Villavicencio <the_paya@gentoo.org>
exclude: fix the case of globs vs. EXCLUDE_INCLUDE
On Windows platforms (excluding Cygwin), @code{ioctl} is called
@code{ioctlsocket}, and error codes for this function are not placed in
@code{errno}, and @code{WSAGetLastError} must be used instead.
+@item
+On glibc platforms, the second parameter is of type @code{unsigned long}
+rather than @code{int}.
@end itemize
Portability problems not fixed by Gnulib:
#include <stdarg.h>
-#define WIN32_LEAN_AND_MEAN
+#if HAVE_IOCTL
+
+/* Provide a wrapper with the POSIX prototype. */
+# undef ioctl
+int
+rpl_ioctl (int fd, int request, ... /* {void *,char *} arg */)
+{
+ void *buf;
+ va_list args;
+
+ va_start (args, request);
+ buf = va_arg (args, void *);
+ va_end (args);
+
+ return ioctl (fd, request, buf);
+}
+
+#else /* mingw */
+
+# define WIN32_LEAN_AND_MEAN
/* Get winsock2.h. */
-#include <sys/socket.h>
+# include <sys/socket.h>
/* Get set_winsock_errno, FD_TO_SOCKET etc. */
-#include "w32sock.h"
+# include "w32sock.h"
int
rpl_ioctl (int fd, int req, ...)
return r;
}
+
+#endif
/* Declare overridden functions. */
#if @GNULIB_IOCTL@
-# if @SYS_IOCTL_H_HAVE_WINSOCK2_H@
+# if @SYS_IOCTL_H_HAVE_WINSOCK2_H@ || @REPLACE_IOCTL@
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef ioctl
# define ioctl rpl_ioctl
# else
_GL_FUNCDECL_SYS (ioctl, int,
(int fd, int request, ... /* {void *,char *} arg */));
-/* Need to cast, because on glibc systems, the second parameter is
- unsigned long int request. */
-_GL_CXXALIAS_SYS_CAST (ioctl, int,
- (int fd, int request, ... /* {void *,char *} arg */));
+_GL_CXXALIAS_SYS (ioctl, int,
+ (int fd, int request, ... /* {void *,char *} arg */));
# endif
_GL_CXXALIASWARN (ioctl);
#elif @SYS_IOCTL_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS@
-# sys_ioctl_h.m4 serial 7
+# sys_ioctl_h.m4 serial 8
dnl Copyright (C) 2008-2010 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
SYS_IOCTL_H_HAVE_WINSOCK2_H=0; AC_SUBST([SYS_IOCTL_H_HAVE_WINSOCK2_H])
SYS_IOCTL_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS=0;
AC_SUBST([SYS_IOCTL_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS])
+ REPLACE_IOCTL=0; AC_SUBST([REPLACE_IOCTL])
])
errno
configure.ac:
+AC_REQUIRE([gl_SYS_IOCTL_H_DEFAULTS])
AC_REQUIRE([gl_HEADER_SYS_SOCKET])
if test "$ac_cv_header_winsock2_h" = yes; then
dnl Even if the 'socket' module is not used here, another part of the
dnl sockets to the ioctl() function. So enable the support for sockets.
AC_LIBOBJ([ioctl])
gl_REPLACE_SYS_IOCTL_H
+else
+ AC_CHECK_FUNCS([ioctl])
+ dnl On glibc systems, the second parameter is 'unsigned long int request',
+ dnl not 'int request'. We cannot simply cast the function pointer, but
+ dnl instead need a wrapper.
+ AC_CACHE_CHECK([for ioctl with POSIX signature],
+ [gl_cv_func_ioctl_posix_signature],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <sys/ioctl.h>]],
+ [[extern int ioctl (int, int, ...);]])
+ ],
+ [gl_cv_func_ioctl_posix_signature=yes],
+ [gl_cv_func_ioctl_posix_signature=no])
+ ])
+ if test $gl_cv_func_ioctl_posix_signature != yes; then
+ REPLACE_IOCTL=1
+ AC_LIBOBJ([ioctl])
+ gl_REPLACE_SYS_IOCTL_H
+ fi
fi
gl_SYS_IOCTL_MODULE_INDICATOR([ioctl])
-e 's|@''GNULIB_IOCTL''@|$(GNULIB_IOCTL)|g' \
-e 's|@''SYS_IOCTL_H_HAVE_WINSOCK2_H''@|$(SYS_IOCTL_H_HAVE_WINSOCK2_H)|g' \
-e 's|@''SYS_IOCTL_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS''@|$(SYS_IOCTL_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS)|g' \
+ -e 's|@''REPLACE_IOCTL''@|$(REPLACE_IOCTL)|g' \
-e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
-e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
< $(srcdir)/sys_ioctl.in.h; \