# HG changeset patch # User Bruno Haible # Date 1269822459 -7200 # Node ID dbbdff0be05d11248cb74c02dd2b8ba95497c9ca # Parent c51ed659983a7d6360d64a07ba717b9c51812481 Fix ioctl's protoype on glibc systems. diff --git a/ChangeLog b/ChangeLog --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2010-03-28 Bruno Haible + + 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 . + 2010-03-28 Javier Villavicencio exclude: fix the case of globs vs. EXCLUDE_INCLUDE diff --git a/doc/posix-functions/ioctl.texi b/doc/posix-functions/ioctl.texi --- a/doc/posix-functions/ioctl.texi +++ b/doc/posix-functions/ioctl.texi @@ -12,6 +12,9 @@ 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: diff --git a/lib/ioctl.c b/lib/ioctl.c --- a/lib/ioctl.c +++ b/lib/ioctl.c @@ -23,12 +23,31 @@ #include -#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 +# include /* Get set_winsock_errno, FD_TO_SOCKET etc. */ -#include "w32sock.h" +# include "w32sock.h" int rpl_ioctl (int fd, int req, ...) @@ -49,3 +68,5 @@ return r; } + +#endif diff --git a/lib/sys_ioctl.in.h b/lib/sys_ioctl.in.h --- a/lib/sys_ioctl.in.h +++ b/lib/sys_ioctl.in.h @@ -44,7 +44,7 @@ /* 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 @@ -56,10 +56,8 @@ # 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@ diff --git a/m4/sys_ioctl_h.m4 b/m4/sys_ioctl_h.m4 --- a/m4/sys_ioctl_h.m4 +++ b/m4/sys_ioctl_h.m4 @@ -1,4 +1,4 @@ -# 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, @@ -67,4 +67,5 @@ 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]) ]) diff --git a/modules/ioctl b/modules/ioctl --- a/modules/ioctl +++ b/modules/ioctl @@ -11,6 +11,7 @@ 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 @@ -18,6 +19,26 @@ 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 ]], + [[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]) diff --git a/modules/sys_ioctl b/modules/sys_ioctl --- a/modules/sys_ioctl +++ b/modules/sys_ioctl @@ -31,6 +31,7 @@ -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; \