diff options
author | Jakub Jelinek <jakub@redhat.com> | 2009-05-22 08:25:34 -0700 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2009-05-22 08:25:34 -0700 |
commit | 1e1dc4e82dd4f31b87440388614c3e4bccdd5f3c (patch) | |
tree | 2222fa67e02e1b84f967a05a297794e83b21821e | |
parent | be6b2e5cf302f984d8f405c0d40e7a3979c47bc3 (diff) | |
download | glibc-1e1dc4e82dd4f31b87440388614c3e4bccdd5f3c.tar glibc-1e1dc4e82dd4f31b87440388614c3e4bccdd5f3c.tar.gz glibc-1e1dc4e82dd4f31b87440388614c3e4bccdd5f3c.tar.bz2 glibc-1e1dc4e82dd4f31b87440388614c3e4bccdd5f3c.zip |
Implement accept4 for more archs using socketcall.
So far accept4 was only supported on archs using socketcall for x86.
This patch adds support for the remaining archs.
-rw-r--r-- | ChangeLog | 13 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/Makefile | 4 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/accept4.c | 45 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/i386/accept4.S | 4 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/internal_accept4.S | 14 |
5 files changed, 76 insertions, 4 deletions
@@ -1,3 +1,16 @@ +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. + 2009-05-20 H.J. Lu <hongjiu.lu@intel.com> * sysdeps/ia64/configure.in: New file. diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index 170c042dd1..cee5d29255 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -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 \ diff --git a/sysdeps/unix/sysv/linux/accept4.c b/sysdeps/unix/sysv/linux/accept4.c index 4be710f76d..9ef9f479b0 100644 --- a/sysdeps/unix/sysv/linux/accept4.c +++ b/sysdeps/unix/sysv/linux/accept4.c @@ -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, socklen_t *addr_len, int flags) 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) diff --git a/sysdeps/unix/sysv/linux/i386/accept4.S b/sysdeps/unix/sysv/linux/i386/accept4.S index 087ccc456f..1d05eff7f7 100644 --- a/sysdeps/unix/sysv/linux/i386/accept4.S +++ b/sysdeps/unix/sysv/linux/i386/accept4.S @@ -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 diff --git a/sysdeps/unix/sysv/linux/internal_accept4.S b/sysdeps/unix/sysv/linux/internal_accept4.S new file mode 100644 index 0000000000..ffc553624c --- /dev/null +++ b/sysdeps/unix/sysv/linux/internal_accept4.S @@ -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 |