From f93fc0b75a50d3ba8d4d69313e3c84ac0b62905b Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Wed, 3 Dec 2008 04:23:18 +0000 Subject: * socket/sys/socket.h: Declare accept4. * socket/accept4.c: New file. * sysdeps/unix/sysv/linux/accept4.c: New file. * sysdeps/unix/sysv/linux/i386/accept4.S: New file. * socket/Makefile (routines): Add accept4. * socket/Versions: Export accept4 with version GLIBC_2.10. * socket/paccept.c: Removed. * sysdeps/unix/sysv/linux/paccept.c: Removed. * sysdeps/unix/sysv/linux/i386/paccept.S: Removed. * Versions.def: Define GLIBC_2.10 for libc. * sysdeps/unix/sysv/linux/kernel-features.h: Define __ASSUME_ACCEPT4. * nscd/connections.c: Use accept4. * sysdeps/unix/sysv/linux/i386/socket.S: Fix comment. --- sysdeps/unix/sysv/linux/accept4.c | 54 +++++++++ sysdeps/unix/sysv/linux/i386/accept4.S | 183 ++++++++++++++++++++++++++++++ sysdeps/unix/sysv/linux/i386/paccept.S | 135 ---------------------- sysdeps/unix/sysv/linux/i386/socket.S | 4 +- sysdeps/unix/sysv/linux/kernel-features.h | 8 +- sysdeps/unix/sysv/linux/paccept.c | 54 --------- 6 files changed, 246 insertions(+), 192 deletions(-) create mode 100644 sysdeps/unix/sysv/linux/accept4.c create mode 100644 sysdeps/unix/sysv/linux/i386/accept4.S delete mode 100644 sysdeps/unix/sysv/linux/i386/paccept.S delete mode 100644 sysdeps/unix/sysv/linux/paccept.c (limited to 'sysdeps/unix') diff --git a/sysdeps/unix/sysv/linux/accept4.c b/sysdeps/unix/sysv/linux/accept4.c new file mode 100644 index 0000000..97f7b8c --- /dev/null +++ b/sysdeps/unix/sysv/linux/accept4.c @@ -0,0 +1,54 @@ +/* Copyright (C) 2008 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 2008. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include +#include + +#include +#include + +#define __NR_accept4 288 + + +#ifdef __NR_accept4 +int +accept4 (int fd, __SOCKADDR_ARG addr, socklen_t *addr_len, int flags) +{ + if (SINGLE_THREAD_P) + return INLINE_SYSCALL (accept4, 4, fd, addr.__sockaddr__, addr_len, flags); + + int oldtype = LIBC_CANCEL_ASYNC (); + + int result = INLINE_SYSCALL (accept4, 4, fd, addr.__sockaddr__, addr_len, + flags); + + LIBC_CANCEL_RESET (oldtype); + + return result; +} +#else +int +accept4 (int fd, __SOCKADDR_ARG addr, socklen_t *addr_len, int flags) +{ + __set_errno (ENOSYS); + return -1; +} +stub_warning (accept4) +#endif diff --git a/sysdeps/unix/sysv/linux/i386/accept4.S b/sysdeps/unix/sysv/linux/i386/accept4.S new file mode 100644 index 0000000..087ccc4 --- /dev/null +++ b/sysdeps/unix/sysv/linux/i386/accept4.S @@ -0,0 +1,183 @@ +/* Copyright (C) 1995-1998,2002,2003,2005, 2008 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include +#include +#include + +#define EINVAL 22 +#define ENOSYS 38 + +#ifndef SOCKOP_accept4 +# define SOCKOP_accept4 18 +#endif + +#ifdef __ASSUME_ACCEPT4 +# define errlabel SYSCALL_ERROR_LABEL +#else +# define errlabel .Lerr + .data +have_accept4: + .long 0 +#endif + + .text +/* The socket-oriented system calls are handled unusally in Linux/i386. + They are all gated through the single `socketcall' system call number. + `socketcall' takes two arguments: the first is the subcode, specifying + which socket function is being called; and the second is a pointer to + the arguments to the specific function. */ + +.globl __libc_accept4 +ENTRY (__libc_accept4) +#ifdef CENABLE + SINGLE_THREAD_P + jne 1f +#endif + + /* Save registers. */ + movl %ebx, %edx + cfi_register (3, 2) + + movl $SYS_ify(socketcall), %eax /* System call number in %eax. */ + + movl $SOCKOP_accept4, %ebx /* Subcode is first arg to syscall. */ + lea 4(%esp), %ecx /* Address of args is 2nd arg. */ + + /* Do the system call trap. */ + ENTER_KERNEL + + /* Restore registers. */ + movl %edx, %ebx + cfi_restore (3) + + /* %eax is < 0 if there was an error. */ + cmpl $-125, %eax + jae errlabel + + /* Successful; return the syscall's value. */ +L(pseudo_end): + ret + + +#ifdef CENABLE + /* We need one more register. */ +1: pushl %esi + cfi_adjust_cfa_offset(4) + + /* Enable asynchronous cancellation. */ + CENABLE + movl %eax, %esi + cfi_offset(6, -8) /* %esi */ + + /* Save registers. */ + movl %ebx, %edx + cfi_register (3, 2) + + movl $SYS_ify(socketcall), %eax /* System call number in %eax. */ + + movl $SOCKOP_accept4, %ebx /* Subcode is first arg to syscall. */ + lea 8(%esp), %ecx /* Address of args is 2nd arg. */ + + /* Do the system call trap. */ + ENTER_KERNEL + + /* Restore registers. */ + movl %edx, %ebx + cfi_restore (3) + + /* Restore the cancellation. */ + xchgl %esi, %eax + CDISABLE + + /* Restore registers. */ + movl %esi, %eax + popl %esi + cfi_restore (6) + cfi_adjust_cfa_offset(-4) + + /* %eax is < 0 if there was an error. */ + cmpl $-125, %eax + jae errlabel + + /* Successful; return the syscall's value. */ + ret +#endif + +#ifndef __ASSUME_ACCEPT4 + /* The kernel returns -EINVAL for unknown socket operations. + We need to convert that error to an ENOSYS error. */ +.Lerr: cmpl $-EINVAL, %eax + jne SYSCALL_ERROR_LABEL + + /* Save registers. */ + pushl %ebx + cfi_adjust_cfa_offset(4) + cfi_offset(ebx, -8) + +# ifdef PIC + SETUP_PIC_REG (dx) + addl $_GLOBAL_OFFSET_TABLE_, %edx + movl have_accept4@GOTOFF(%edx), %eax +# else + movl have_accept4, %eax +# endif + testl %eax, %eax + jne 1f + + /* 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. */ + movl $-1, 8(%esp) + movl $0, 20(%esp) + + movl $SYS_ify(socketcall), %eax /* System call number in %eax. */ + + movl $SOCKOP_accept4, %ebx /* Subcode is first arg to syscall. */ + lea 8(%esp), %ecx /* Address of args is 2nd arg. */ + + /* Do the system call trap. */ + ENTER_KERNEL + + cmpl $-EINVAL, %eax + movl $-1, %eax + je 3f + movl $1, %eax +3: +# ifdef PIC + movl %eax, have_accept4@GOTOFF(%edx) +# else + movl %eax, have_accept4 +# endif + + testl %eax, %eax + +1: movl $-EINVAL, %eax + jns 2f + movl $-ENOSYS, %eax + + /* Restore registers. */ +2: popl %ebx + cfi_restore (ebx) + + jmp SYSCALL_ERROR_LABEL +#endif +PSEUDO_END (__libc_accept4) + +weak_alias (__libc_accept4, accept4) diff --git a/sysdeps/unix/sysv/linux/i386/paccept.S b/sysdeps/unix/sysv/linux/i386/paccept.S deleted file mode 100644 index 02ad78d..0000000 --- a/sysdeps/unix/sysv/linux/i386/paccept.S +++ /dev/null @@ -1,135 +0,0 @@ -/* Copyright (C) 1995-1998,2002,2003,2005,2008 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include -#include -#include - -#define _NSIG 64 - -#define P(a, b) P2(a, b) -#define P2(a, b) a##b - - .text -/* The socket-oriented system calls are handled unusally in Linux. - They are all gated through the single `socketcall' system call number. - `socketcall' takes two arguments: the first is the subcode, specifying - which socket function is being called; and the second is a pointer to - the arguments to the specific function. */ - -ENTRY(do_paccept) -#ifdef SOCKOP_paccept - subl $6*4, %esp - cfi_adjust_cfa_offset(6*4) - - movl (%eax), %ecx - movl %ecx, (%esp) - movl 4(%eax), %ecx - movl %ecx, 4(%esp) - movl 8(%eax), %ecx - movl %ecx, 8(%esp) - movl 12(%eax), %ecx - movl %ecx, 12(%esp) - movl $(_NSIG / 8), 16(%esp) - movl 16(%eax), %ecx - movl %ecx, 20(%esp) - - movl $SYS_ify(socketcall), %eax /* System call number in %eax. */ - - movl $SOCKOP_paccept, %ebx /* Subcode is first arg to syscall. */ - movl %esp, %ecx /* Address of args is 2nd arg. */ - - /* Do the system call trap. */ - ENTER_KERNEL - - addl $6*4, %esp - cfi_adjust_cfa_offset(-6*4) - - /* %eax is < 0 if there was an error. */ - cmpl $-125, %eax - jae SYSCALL_ERROR_LABEL -#else - movl $-ENOSYS, %eax - jmp SYSCALL_ERROR_LABEL - - .section .gnu.glibc-stub.paccept - .previous - .section .gnu.warning.paccept - .string "warning: paccept is not implemented and will always fail" - .previous -#endif -L(pseudo_end): - ret -PSEUDO_END(do_paccept) - - - .globl paccept -ENTRY (paccept) -#ifdef CENABLE - SINGLE_THREAD_P - jne 1f -#endif - - /* Save registers. */ - movl %ebx, %edx - cfi_register (3, 2) - - lea 4(%esp), %eax - call do_paccept - - /* Restore registers. */ - movl %edx, %ebx - cfi_restore (3) - - ret - -#ifdef CENABLE - /* We need one more register. */ -1: pushl %esi - cfi_adjust_cfa_offset(4) - - /* Enable asynchronous cancellation. */ - CENABLE - movl %eax, %esi - cfi_offset(6, -8) /* %esi */ - - /* Save registers. */ - movl %ebx, %edx - cfi_register (3, 2) - - lea 8(%esp), %eax - call do_paccept - - /* Restore registers. */ - movl %edx, %ebx - cfi_restore (3) - - /* Restore the cancellation. */ - xchgl %esi, %eax - CDISABLE - - /* Restore registers. */ - movl %esi, %eax - popl %esi - cfi_restore (6) - cfi_adjust_cfa_offset(-4) - - /* Successful; return the syscall's value. */ - ret -#endif -PSEUDO_END (paccept) diff --git a/sysdeps/unix/sysv/linux/i386/socket.S b/sysdeps/unix/sysv/linux/i386/socket.S index 7c8ac29..889e5c7 100644 --- a/sysdeps/unix/sysv/linux/i386/socket.S +++ b/sysdeps/unix/sysv/linux/i386/socket.S @@ -1,4 +1,4 @@ -/* Copyright (C) 1995-1998,2002,2003,2005 Free Software Foundation, Inc. +/* Copyright (C) 1995-1998,2002,2003,2005,2008 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -24,7 +24,7 @@ #define P2(a, b) a##b .text -/* The socket-oriented system calls are handled unusally in Linux. +/* The socket-oriented system calls are handled unusally in Linux/i386. They are all gated through the single `socketcall' system call number. `socketcall' takes two arguments: the first is the subcode, specifying which socket function is being called; and the second is a pointer to diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h index 6031eae..900baf1 100644 --- a/sysdeps/unix/sysv/linux/kernel-features.h +++ b/sysdeps/unix/sysv/linux/kernel-features.h @@ -509,5 +509,11 @@ # define __ASSUME_SOCK_CLOEXEC 1 # define __ASSUME_IN_NONBLOCK 1 # define __ASSUME_PIPE2 1 -# define __ASSUME_PACCEPT 1 +#endif + +/* Support for the accept4 syscall was added in 2.6.28. */ +#if __LINUX_KERNEL_VERSION >= 0x02061b \ + && (defined __i386__ || defined __x86_64__ || defined __powerpc__ \ + || defined __ia64__ || defined __sparc__ || __s390__) +# define __ASSUME_ACCEPT4 1 #endif diff --git a/sysdeps/unix/sysv/linux/paccept.c b/sysdeps/unix/sysv/linux/paccept.c deleted file mode 100644 index cc2979c..0000000 --- a/sysdeps/unix/sysv/linux/paccept.c +++ /dev/null @@ -1,54 +0,0 @@ -/* Copyright (C) 2008 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 2008. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include -#include -#include - -#include -#include - -#ifdef __NR_paccept -int -paccept (int fd, __SOCKADDR_ARG addr, socklen_t *addr_len, - const __sigset_t *ss, int flags) -{ - if (SINGLE_THREAD_P) - return INLINE_SYSCALL (paccept, 6, fd, addr.__sockaddr__, addr_len, ss, - _NSIG / 8, flags); - - int oldtype = LIBC_CANCEL_ASYNC (); - - int result = INLINE_SYSCALL (paccept, 6, fd, addr.__sockaddr__, addr_len, ss, - _NSIG / 8, flags); - - LIBC_CANCEL_RESET (oldtype); - - return result; -} -#else -int -paccept (int fd, __SOCKADDR_ARG addr, socklen_t *addr_len, - const __sigset_t *ss, int flags) -{ - __set_errno (ENOSYS); - return -1; -stub_warning (epoll_pwait) -} -#endif -- cgit v1.1