This is the mail archive of the libc-hacker@sourceware.org mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Add accept4 on most architectures


Hi!

This patch adds accept4 support for powerpc{32,64}, s390{,x}, sh, etc.
Tested on powerpc, with --enable-kernel=2.6.9 as well as --enable-kernel=2.6.28
build and for the former also running on 2.6.18 kernel.

2009-05-22  Jakub Jelinek  <jakub@redhat.com>

	* sysdeps/unix/sysv/linux/accept4.c: Include kernel-features.h.
	(accept4): If __NR_accept4 is not defined, but __NR_socketcall
	is, either do nothing at all if __ASSUME_ACCEPT4, or
	call __internal_accept4 and handle EINVAL -> ENOSYS translation.
	* sysdeps/unix/sysv/linux/internal_accept4.S: New file.
	* sysdeps/unix/sysv/linux/i386/accept4.S (SOCKOP_accept4): Don't
	define.
	* sysdeps/unix/sysv/linux/i386/internal_accept4.S: New file.
	* sysdeps/unix/sysv/linux/Makefile (sysdep-routines): Add
	internal_accept4 in socket directory.

--- libc/sysdeps/unix/sysv/linux/internal_accept4.S.jj	2009-05-22 09:01:54.000000000 +0200
+++ libc/sysdeps/unix/sysv/linux/internal_accept4.S	2009-05-22 09:05:31.000000000 +0200
@@ -0,0 +1,14 @@
+#include <kernel-features.h>
+#include <sys/syscall.h>
+#if !defined __NR_accept4 && defined __NR_socketcall
+# define socket	accept4
+# ifdef __ASSUME_ACCEPT4
+#  define __socket accept4
+# else
+#  define __socket __internal_accept4
+# endif
+# define NARGS 4
+# define NEED_CANCELLATION
+# define NO_WEAK_ALIAS
+# include <socket.S>
+#endif
--- libc/sysdeps/unix/sysv/linux/i386/accept4.S.jj	2009-05-16 19:23:44.000000000 +0200
+++ libc/sysdeps/unix/sysv/linux/i386/accept4.S	2009-05-22 09:11:04.000000000 +0200
@@ -24,10 +24,6 @@
 #define EINVAL	22
 #define ENOSYS	38
 
-#ifndef SOCKOP_accept4
-# define SOCKOP_accept4 18
-#endif
-
 #ifdef __ASSUME_ACCEPT4
 # define errlabel SYSCALL_ERROR_LABEL
 #else
--- libc/sysdeps/unix/sysv/linux/i386/internal_accept4.S.jj	2009-05-22 09:10:30.000000000 +0200
+++ libc/sysdeps/unix/sysv/linux/i386/internal_accept4.S	2009-05-22 09:10:24.000000000 +0200
@@ -0,0 +1 @@
+/* Not needed, accept4.S has everything.  */
--- libc/sysdeps/unix/sysv/linux/Makefile.jj	2009-05-16 19:23:44.000000000 +0200
+++ libc/sysdeps/unix/sysv/linux/Makefile	2009-05-22 09:07:05.000000000 +0200
@@ -11,6 +11,10 @@ ifeq ($(subdir),malloc)
 CFLAGS-malloc.c += -DMORECORE_CLEARS=2
 endif
 
+ifeq ($(subdir),socket)
+sysdep_routines += internal_accept4
+endif
+
 ifeq ($(subdir),misc)
 sysdep_routines += sysctl clone llseek umount umount2 readahead \
 		   setfsuid setfsgid makedev epoll_pwait signalfd \
--- libc/sysdeps/unix/sysv/linux/accept4.c.jj	2009-05-22 08:47:29.000000000 +0200
+++ libc/sysdeps/unix/sysv/linux/accept4.c	2009-05-22 09:24:48.000000000 +0200
@@ -23,6 +23,7 @@
 
 #include <sysdep-cancel.h>
 #include <sys/syscall.h>
+#include <kernel-features.h>
 
 
 #ifdef __NR_accept4
@@ -41,6 +42,50 @@ accept4 (int fd, __SOCKADDR_ARG addr, so
 
   return result;
 }
+#elif defined __NR_socketcall
+# ifndef __ASSUME_ACCEPT4
+extern int __internal_accept4 (int fd, __SOCKADDR_ARG addr,
+			       socklen_t *addr_len, int flags)
+     attribute_hidden;
+
+static int have_accept4;
+
+int
+accept4 (int fd, __SOCKADDR_ARG addr, socklen_t *addr_len, int flags)
+{
+  if (__builtin_expect (have_accept4 >= 0, 1))
+    {
+      int ret = __internal_accept4 (fd, addr, addr_len, flags);
+      /* The kernel returns -EINVAL for unknown socket operations.
+	 We need to convert that error to an ENOSYS error.  */
+      if (__builtin_expect (ret < 0, 0)
+	  && have_accept4 == 0
+	  && errno == EINVAL)
+	{
+	  /* Try another call, this time with the FLAGS parameter
+	     cleared and an invalid file descriptor.  This call will not
+	     cause any harm and it will return immediately.  */
+	  ret = __internal_accept4 (-1, addr, addr_len, 0);
+	  if (errno == EINVAL)
+	    {
+	      have_accept4 = -1;
+	      __set_errno (ENOSYS);
+	    }
+	  else
+	    {
+	      have_accept4 = 1;
+	      __set_errno (EINVAL);
+	    }
+	  return -1;
+	}
+      return ret;
+    }
+  __set_errno (ENOSYS);
+  return -1;
+}
+# else
+/* When __ASSUME_ACCEPT4 accept4 is defined in internal_accept4.S.  */
+# endif
 #else
 int
 accept4 (int fd, __SOCKADDR_ARG addr, socklen_t *addr_len, int flags)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]