changeset 11398:2de4c4d41f01

Work around select() bug on Interix 3.5.
author Bruno Haible <bruno@clisp.org>
date Thu, 12 Mar 2009 11:46:05 +0100
parents bbd55a939862
children b661f47cf79b
files ChangeLog doc/posix-functions/select.texi lib/select.c lib/sys_select.in.h m4/select.m4 m4/sys_select_h.m4 modules/nanosleep modules/poll modules/select modules/sys_select
diffstat 10 files changed, 104 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,18 @@
 2009-03-12  Bruno Haible  <bruno@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 <mduft@gentoo.org>.
+
 	* lib/select.c: Renamed from lib/winsock-select.c.
 	* modules/select (Files): Add lib/select.c, remove
 	lib/winsock-select.c.
--- a/doc/posix-functions/select.texi
+++ b/doc/posix-functions/select.texi
@@ -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:
--- 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 <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
--- a/lib/sys_select.in.h
+++ b/lib/sys_select.in.h
@@ -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 *);
new file mode 100644
--- /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 <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
+])
--- 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_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])
 ])
--- a/modules/nanosleep
+++ b/modules/nanosleep
@@ -10,6 +10,7 @@
 extensions
 gettime
 multiarch
+select
 sigaction
 stdbool
 sys_select
--- a/modules/poll
+++ b/modules/poll
@@ -8,6 +8,7 @@
 
 Depends-on:
 alloca
+select
 sys_select
 sys_time
 errno
--- a/modules/select
+++ b/modules/select
@@ -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:
--- a/modules/sys_select
+++ b/modules/sys_select
@@ -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