Simon Josefsson wrote: > > It seems that another solution would be to > > detect this problem, and to replace select if the system's select > > doesn't work.
Good point. Using 0 as nfd argument is common; try searching for " = select (0, " on http://www.google.com/codesearch/. > I haven't studied the spec enough to say That's easy to do: <http://www.opengroup.org/onlinepubs/9699919799/functions/select.html> says: "The nfds argument specifies the range of descriptors to be tested. The first nfds descriptors shall be checked in each set; that is, the descriptors from zero through nfds-1 in the descriptor sets shall be examined." In other words, there is no requirement that nfds be > 0. nfds = 0 is valid. > However, technically the configure-time test would have > to be one that runs a binary, to determine if select fails > like that. and that's ugly... Sure it will be a test with AC_TRY_RUN. What is ugly about it? For cross-compiling we can use AC_CANONICAL_HOST and dispatch on that, as usual. Here is a series of two proposed patches to provide a workaround. Simon, is that OK to commit? 2009-03-12 Bruno Haible <br...@clisp.org> * lib/select.c: Renamed from lib/winsock-select.c. * modules/select (Files): Add lib/select.c, remove lib/winsock-select.c. (configure.ac): Update. --- modules/select.orig 2009-03-12 10:56:00.000000000 +0100 +++ modules/select 2009-03-12 10:54:05.000000000 +0100 @@ -2,7 +2,7 @@ select() function: synchronous I/O multiplexing. Files: -lib/winsock-select.c +lib/select.c Depends-on: alloca @@ -11,7 +11,7 @@ configure.ac: AC_REQUIRE([gl_HEADER_SYS_SELECT]) if test "$ac_cv_header_winsock2_h" = yes; then - AC_LIBOBJ([winsock-select]) + AC_LIBOBJ([select]) fi gl_SYS_SELECT_MODULE_INDICATOR([select]) 2009-03-12 Bruno Haible <br...@clisp.org> Work around select() bug on Interix 3.5. * lib/sys_select.in.h (select): Also replace if REPLACE_SELECT is 1. * lib/select.c (rpl_select): Add an implementation for Unix platforms. * m4/select.m4: New file. * m4/sys_select_h.m4 (gl_SYS_SELECT_H_DEFAULTS): Initialize REPLACE_SELECT. * modules/sys_select (Makefile.am): Substitute REPLACE_SELECT. * modules/select (Files): Add m4/select.m4. (configure.ac): Move conditional to m4/select.m4. Invoke gl_FUNC_SELECT. * modules/nanosleep (Depends-on): Add select. * modules/poll (Depends-on): Likewise. * doc/posix-functions/select.texi: Mention the Interix bug. Reported by Markus Duft <md...@gentoo.org>. --- lib/sys_select.in.h.orig 2009-03-12 11:36:40.000000000 +0100 +++ lib/sys_select.in.h 2009-03-12 11:20:28.000000000 +0100 @@ -1,5 +1,5 @@ /* Substitute for <sys/select.h>. - Copyright (C) 2007-2008 Free Software Foundation, Inc. + Copyright (C) 2007-2009 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 @@ -66,7 +66,7 @@ # endif # if @GNULIB_SELECT@ -# if @HAVE_WINSOCK2_H@ +# if @HAVE_WINSOCK2_H@ || @REPLACE_SELECT@ # undef select # define select rpl_select extern int rpl_select (int, fd_set *, fd_set *, fd_set *, struct timeval *); --- lib/select.c.orig 2009-03-12 11:36:40.000000000 +0100 +++ lib/select.c 2009-03-12 11:18:27.000000000 +0100 @@ -1,7 +1,7 @@ /* Emulation for select(2) Contributed by Paolo Bonzini. - Copyright 2008 Free Software Foundation, Inc. + Copyright 2008-2009 Free Software Foundation, Inc. This file is part of gnulib. @@ -23,6 +23,8 @@ #include <alloca.h> #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ +/* Native Win32. */ + #include <sys/types.h> #include <stdbool.h> #include <errno.h> @@ -420,4 +422,25 @@ return rc; } -#endif /* Native Win32. */ +#else /* ! Native Win32. */ + +#include <sys/select.h> + +#undef select + +int +rpl_select (int nfds, fd_set *rfds, fd_set *wfds, fd_set *xfds, + struct timeval *timeout) +{ + /* Interix 3.5 has a bug: it does not support nfds == 0. */ + if (nfds == 0) + { + nfds = 1; + rfds = NULL; + wfds = NULL; + xfds = NULL; + } + return select (nfds, rfds, wfds, xfds, timeout); +} + +#endif ================================ m4/select.m4 ================================ # select.m4 serial 1 dnl Copyright (C) 2009 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_FUNC_SELECT], [ AC_REQUIRE([gl_HEADER_SYS_SELECT]) AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles if test "$ac_cv_header_winsock2_h" = yes; then AC_LIBOBJ([select]) else dnl On Interix 3.5, select(0, NULL, NULL, NULL, timeout) fails with error dnl EFAULT. AC_CHECK_HEADERS_ONCE([sys/select.h]) AC_CACHE_CHECK([whether select supports a 0 argument], [gl_cv_func_select_supports0], [ AC_TRY_RUN([ #include <sys/types.h> #include <sys/time.h> #if HAVE_SYS_SELECT_H #include <sys/select.h> #endif int main () { struct timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = 5; return select (0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &timeout) < 0; }], [gl_cv_func_select_supports0=yes], [gl_cv_func_select_supports0=no], [ changequote(,)dnl case "$host_os" in # Guess no on Interix. interix*) gl_cv_func_select_supports0="guessing no";; # Guess yes otherwise. *) gl_cv_func_select_supports0="guessing yes";; esac changequote([,])dnl ]) ]) case "$gl_cv_func_select_supports0" in *yes) ;; *) REPLACE_SELECT=1 AC_LIBOBJ([select]) ;; esac fi ]) ============================================================================== --- m4/sys_select_h.m4.orig 2009-03-12 11:36:40.000000000 +0100 +++ m4/sys_select_h.m4 2009-03-12 11:21:53.000000000 +0100 @@ -1,5 +1,5 @@ -# sys_select_h.m4 serial 6 -dnl Copyright (C) 2006-2008 Free Software Foundation, Inc. +# sys_select_h.m4 serial 7 +dnl Copyright (C) 2006-2009 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. @@ -42,4 +42,6 @@ AC_DEFUN([gl_SYS_SELECT_H_DEFAULTS], [ GNULIB_SELECT=0; AC_SUBST([GNULIB_SELECT]) + dnl Assume proper GNU behavior unless another module says otherwise. + REPLACE_SELECT=0; AC_SUBST([REPLACE_SELECT]) ]) --- modules/sys_select.orig 2009-03-12 11:36:40.000000000 +0100 +++ modules/sys_select 2009-03-12 11:20:56.000000000 +0100 @@ -30,6 +30,7 @@ -e 's|@''HAVE_SYS_SELECT_H''@|$(HAVE_SYS_SELECT_H)|g' \ -e 's|@''GNULIB_SELECT''@|$(GNULIB_SELECT)|g' \ -e 's|@''HAVE_WINSOCK2_H''@|$(HAVE_WINSOCK2_H)|g' \ + -e 's|@''REPLACE_SELECT''@|$(REPLACE_SELECT)|g' \ -e '/definition of GL_LINK_WARNING/r $(LINK_WARNING_H)' \ < $(srcdir)/sys_select.in.h; \ } > $...@-t --- modules/select.orig 2009-03-12 11:36:40.000000000 +0100 +++ modules/select 2009-03-12 11:16:24.000000000 +0100 @@ -3,16 +3,14 @@ Files: lib/select.c +m4/select.m4 Depends-on: alloca sys_select configure.ac: -AC_REQUIRE([gl_HEADER_SYS_SELECT]) -if test "$ac_cv_header_winsock2_h" = yes; then - AC_LIBOBJ([select]) -fi +gl_FUNC_SELECT gl_SYS_SELECT_MODULE_INDICATOR([select]) Makefile.am: --- modules/nanosleep.orig 2009-03-12 11:36:40.000000000 +0100 +++ modules/nanosleep 2009-03-12 11:09:26.000000000 +0100 @@ -10,6 +10,7 @@ extensions gettime multiarch +select sigaction stdbool sys_select --- modules/poll.orig 2009-03-12 11:36:40.000000000 +0100 +++ modules/poll 2009-03-12 11:09:13.000000000 +0100 @@ -8,6 +8,7 @@ Depends-on: alloca +select sys_select sys_time errno --- doc/posix-functions/select.texi.orig 2009-03-12 11:36:40.000000000 +0100 +++ doc/posix-functions/select.texi 2009-03-12 11:14:32.000000000 +0100 @@ -15,6 +15,9 @@ @item On Windows platforms (excluding Cygwin), error codes for @code{accept} are not placed in @code{errno}, and @code{WSAGetLastError} must be used instead. +...@item +This function fails when the @code{nfds} argument is 0 on some platforms: +Interix 3.5. @end itemize Portability problems not fixed by Gnulib: