From ea64fe0094765a9960dbe6d3e57dee870d3c2f6e Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Thu, 12 Mar 2009 11:46:05 +0100 Subject: [PATCH] Work around select() bug on Interix 3.5. --- ChangeLog | 13 +++++++++++ doc/posix-functions/select.texi | 3 +++ lib/select.c | 27 +++++++++++++++++++-- lib/sys_select.in.h | 4 ++-- m4/select.m4 | 52 +++++++++++++++++++++++++++++++++++++++++ m4/sys_select_h.m4 | 6 +++-- modules/nanosleep | 1 + modules/poll | 1 + modules/select | 6 ++--- modules/sys_select | 1 + 10 files changed, 104 insertions(+), 10 deletions(-) create mode 100644 m4/select.m4 diff --git a/ChangeLog b/ChangeLog index d6823fa03..e745bca91 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,18 @@ 2009-03-12 Bruno Haible + 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 . + * lib/select.c: Renamed from lib/winsock-select.c. * modules/select (Files): Add lib/select.c, remove lib/winsock-select.c. diff --git a/doc/posix-functions/select.texi b/doc/posix-functions/select.texi index a9aa263f0..0b52c27c0 100644 --- a/doc/posix-functions/select.texi +++ b/doc/posix-functions/select.texi @@ -15,6 +15,9 @@ file descriptors. @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: diff --git a/lib/select.c b/lib/select.c index 33e5f734f..8496c1501 100644 --- a/lib/select.c +++ b/lib/select.c @@ -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 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ +/* Native Win32. */ + #include #include #include @@ -420,4 +422,25 @@ rpl_select (int nfds, fd_set *rfds, fd_set *wfds, fd_set *xfds, return rc; } -#endif /* Native Win32. */ +#else /* ! Native Win32. */ + +#include + +#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 diff --git a/lib/sys_select.in.h b/lib/sys_select.in.h index 00e8b2e67..62cd1048b 100644 --- a/lib/sys_select.in.h +++ b/lib/sys_select.in.h @@ -1,5 +1,5 @@ /* Substitute for . - 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 @@ extern "C" { # 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 *); diff --git a/m4/select.m4 b/m4/select.m4 new file mode 100644 index 000000000..5397df02f --- /dev/null +++ b/m4/select.m4 @@ -0,0 +1,52 @@ +# 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 +#include +#if HAVE_SYS_SELECT_H +#include +#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 +]) diff --git a/m4/sys_select_h.m4 b/m4/sys_select_h.m4 index c537e7918..c48be2ce3 100644 --- a/m4/sys_select_h.m4 +++ b/m4/sys_select_h.m4 @@ -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_MODULE_INDICATOR], 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]) ]) diff --git a/modules/nanosleep b/modules/nanosleep index ef10653d9..a652e53c2 100644 --- a/modules/nanosleep +++ b/modules/nanosleep @@ -10,6 +10,7 @@ clock-time extensions gettime multiarch +select sigaction stdbool sys_select diff --git a/modules/poll b/modules/poll index 1d1c0fff9..b83cb2b0c 100644 --- a/modules/poll +++ b/modules/poll @@ -8,6 +8,7 @@ m4/poll.m4 Depends-on: alloca +select sys_select sys_time errno diff --git a/modules/select b/modules/select index 0e2a221b5..f7d9c7d0b 100644 --- a/modules/select +++ b/modules/select @@ -3,16 +3,14 @@ select() function: synchronous I/O multiplexing. 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: diff --git a/modules/sys_select b/modules/sys_select index c893e7cb8..e3a108aaf 100644 --- a/modules/sys_select +++ b/modules/sys_select @@ -30,6 +30,7 @@ sys/select.h: sys_select.in.h -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 -- 2.11.0