Tolerate declared but missing accept4 syscall.
authorBruno Haible <bruno@clisp.org>
Tue, 25 Aug 2009 00:26:18 +0000 (02:26 +0200)
committerBruno Haible <bruno@clisp.org>
Tue, 25 Aug 2009 00:26:18 +0000 (02:26 +0200)
ChangeLog
lib/accept4.c
lib/sys_socket.in.h
m4/accept4.m4
modules/accept4

index 9628960..501fba7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2009-08-24  Bruno Haible  <bruno@clisp.org>
+
+       Tolerate declared but missing accept4 syscall.
+       * lib/accept4.c (accept4): Invoke original accept4 function first, if
+       available.
+       * lib/sys_socket.in.h (accept4): If the function is already present,
+       override it.
+       * m4/accept4.m4 (gl_FUNC_ACCEPT4): Remove AC_LIBOBJ invocation.
+       * modules/accept4 (Makefile.am): Compile accept4.c always.
+       Reported by Paolo Bonzini and Eric Blake.
+
 2009-08-23  Bruno Haible  <bruno@clisp.org>
 
        New module 'accept4'.
index 1203d9a..fbcb609 100644 (file)
@@ -33,6 +33,26 @@ accept4 (int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags)
 {
   int fd;
 
+#if HAVE_ACCEPT4
+# undef accept4
+  /* Try the system call first, if it exists.  (We may be running with a glibc
+     that has the function but with an older kernel that lacks it.)  */
+  {
+    /* Cache the information whether the system call really exists.  */
+    static int have_accept4_really; /* 0 = unknown, 1 = yes, -1 = no */
+    if (have_accept4_really >= 0)
+      {
+       int result = accept4 (sockfd, addr, addrlen, flags);
+       if (!(result < 0 && errno == ENOSYS))
+         {
+           have_accept4_really = 1;
+           return result;
+         }
+       have_accept4_really = -1;
+      }
+  }
+#endif
+
   /* Check the supported flags.  */
   if ((flags & ~(SOCK_CLOEXEC | O_TEXT | O_BINARY)) != 0)
     {
index c4df33f..e3f6d6c 100644 (file)
@@ -428,15 +428,16 @@ extern "C" {
 #endif
 
 #if @GNULIB_ACCEPT4@
-# if !@HAVE_ACCEPT4@
 /* Accept a connection on a socket, with specific opening flags.
    The flags are a bitmask, possibly including O_CLOEXEC (defined in <fcntl.h>)
    and O_TEXT, O_BINARY (defined in "binary-io.h").
    See also the Linux man page at
    <http://www.kernel.org/doc/man-pages/online/pages/man2/accept4.2.html>.  */
+# if @HAVE_ACCEPT4@
+#  define accept4 rpl_accept4
+# endif
 extern int accept4 (int sockfd, struct sockaddr *addr, socklen_t *addrlen,
                    int flags);
-# endif
 #elif defined GNULIB_POSIXCHECK
 # undef accept4
 # define accept4(s,a,l,f) \
index 6828c92..5040b44 100644 (file)
@@ -1,4 +1,4 @@
-# accept4.m4 serial 1
+# accept4.m4 serial 2
 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,
@@ -14,6 +14,5 @@ AC_DEFUN([gl_FUNC_ACCEPT4],
   AC_CHECK_FUNCS_ONCE([accept4])
   if test $ac_cv_func_accept4 != yes; then
     HAVE_ACCEPT4=0
-    AC_LIBOBJ([accept4])
   fi
 ])
index 3be5757..d13127e 100644 (file)
@@ -17,6 +17,7 @@ gl_FUNC_ACCEPT4
 gl_SYS_SOCKET_MODULE_INDICATOR([accept4])
 
 Makefile.am:
+lib_SOURCES += accept4.c
 
 Include:
 <sys/socket.h>