From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 13396 invoked by alias); 22 May 2009 09:15:10 -0000 Received: (qmail 13370 invoked by uid 22791); 22 May 2009 09:15:09 -0000 X-SWARE-Spam-Status: No, hits=-2.3 required=5.0 tests=AWL,BAYES_00 X-Spam-Check-By: sourceware.org Received: from sunsite.ms.mff.cuni.cz (HELO sunsite.mff.cuni.cz) (195.113.15.26) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 22 May 2009 09:15:03 +0000 Received: from sunsite.mff.cuni.cz (localhost [127.0.0.1]) by sunsite.mff.cuni.cz (8.14.3/8.14.3) with ESMTP id n4M9DvZf010023; Fri, 22 May 2009 11:13:57 +0200 Received: (from jakub@localhost) by sunsite.mff.cuni.cz (8.14.3/8.14.3/Submit) id n4M9DuLm010022; Fri, 22 May 2009 11:13:56 +0200 Date: Fri, 22 May 2009 09:15:00 -0000 From: Jakub Jelinek To: Ulrich Drepper Cc: libc-hacker@sources.redhat.com Subject: [PATCH] Add accept4 on most architectures Message-ID: <20090522091356.GA30565@sunsite.ms.mff.cuni.cz> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.19 (2009-01-05) Mailing-List: contact libc-hacker-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-hacker-owner@sourceware.org X-SW-Source: 2009-05/txt/msg00012.txt.bz2 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 * 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 +#include +#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 +#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 #include +#include #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)