From 1e1dc4e82dd4f31b87440388614c3e4bccdd5f3c Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 22 May 2009 08:25:34 -0700 Subject: 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. --- sysdeps/unix/sysv/linux/accept4.c | 45 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'sysdeps/unix/sysv/linux/accept4.c') 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 #include +#include #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) -- cgit v1.2.3