From 2f4cad8d89b656684e8829b2e164070515d4d34b Mon Sep 17 00:00:00 2001 From: joseph Date: Tue, 21 Jun 2011 15:01:41 +0000 Subject: Merge changes between r14014 and r14127 from /fsf/trunk. git-svn-id: svn://svn.eglibc.org/trunk@14282 7b3dc134-2b1b-0410-93df-9e9f96275f8d --- libc/sysdeps/unix/sysv/linux/Makefile | 3 +- libc/sysdeps/unix/sysv/linux/Versions | 4 + libc/sysdeps/unix/sysv/linux/bits/sched.h | 10 ++- libc/sysdeps/unix/sysv/linux/bits/siginfo.h | 4 +- libc/sysdeps/unix/sysv/linux/bits/socket.h | 9 +- libc/sysdeps/unix/sysv/linux/dl-osinfo.h | 2 +- libc/sysdeps/unix/sysv/linux/ia64/bits/siginfo.h | 4 +- libc/sysdeps/unix/sysv/linux/internal_sendmmsg.S | 14 ++++ libc/sysdeps/unix/sysv/linux/kernel-features.h | 5 ++ libc/sysdeps/unix/sysv/linux/s390/bits/siginfo.h | 4 +- libc/sysdeps/unix/sysv/linux/sendmmsg.c | 96 ++++++++++++++++++++++ libc/sysdeps/unix/sysv/linux/socketcall.h | 3 +- libc/sysdeps/unix/sysv/linux/sparc/bits/siginfo.h | 4 +- libc/sysdeps/unix/sysv/linux/syscalls.list | 2 + libc/sysdeps/unix/sysv/linux/x86_64/init-first.c | 22 ++++- libc/sysdeps/unix/sysv/linux/x86_64/sched_getcpu.S | 7 +- libc/sysdeps/unix/sysv/linux/x86_64/time.S | 7 +- 17 files changed, 182 insertions(+), 18 deletions(-) create mode 100644 libc/sysdeps/unix/sysv/linux/internal_sendmmsg.S create mode 100644 libc/sysdeps/unix/sysv/linux/sendmmsg.c (limited to 'libc/sysdeps/unix') diff --git a/libc/sysdeps/unix/sysv/linux/Makefile b/libc/sysdeps/unix/sysv/linux/Makefile index 4e69d22f4..55e92c7b4 100644 --- a/libc/sysdeps/unix/sysv/linux/Makefile +++ b/libc/sysdeps/unix/sysv/linux/Makefile @@ -12,7 +12,8 @@ CFLAGS-malloc.c += -DMORECORE_CLEARS=2 endif ifeq ($(subdir),socket) -sysdep_routines += internal_accept4 recvmmsg internal_recvmmsg +sysdep_routines += internal_accept4 recvmmsg internal_recvmmsg sendmmsg \ + internal_sendmmsg endif ifeq ($(subdir),misc) diff --git a/libc/sysdeps/unix/sysv/linux/Versions b/libc/sysdeps/unix/sysv/linux/Versions index 29099dc5c..3a3e8e8c2 100644 --- a/libc/sysdeps/unix/sysv/linux/Versions +++ b/libc/sysdeps/unix/sysv/linux/Versions @@ -158,6 +158,10 @@ libc { clock_adjtime; name_to_handle_at; open_by_handle_at; + + setns; + + sendmmsg; } GLIBC_PRIVATE { # functions used in other libraries diff --git a/libc/sysdeps/unix/sysv/linux/bits/sched.h b/libc/sysdeps/unix/sysv/linux/bits/sched.h index 8ba9eed6f..b222fb211 100644 --- a/libc/sysdeps/unix/sysv/linux/bits/sched.h +++ b/libc/sysdeps/unix/sysv/linux/bits/sched.h @@ -1,6 +1,6 @@ /* Definitions of constants and data structure for POSIX 1003.1b-1993 scheduling interface. - Copyright (C) 1996-1999,2001-2003,2005,2006,2007,2008,2009 + Copyright (C) 1996-1999,2001-2003,2005,2006,2007,2008,2009,2011 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -37,7 +37,7 @@ # define SCHED_RESET_ON_FORK 0x40000000 #endif -#ifdef __USE_MISC +#ifdef __USE_GNU /* Cloning flags. */ # define CSIGNAL 0x000000ff /* Signal mask to be sent at exit. */ # define CLONE_VM 0x00000100 /* Set if VM shared between processes. */ @@ -78,7 +78,7 @@ struct sched_param __BEGIN_DECLS -#ifdef __USE_MISC +#ifdef __USE_GNU /* Clone current process. */ extern int clone (int (*__fn) (void *__arg), void *__child_stack, int __flags, void *__arg, ...) __THROW; @@ -88,8 +88,12 @@ extern int unshare (int __flags) __THROW; /* Get index of currently used CPU. */ extern int sched_getcpu (void) __THROW; + +/* Switch process to namespace of type NSTYPE indicated by FD. */ +extern int setns (int __fd, int __nstype) __THROW; #endif + __END_DECLS #endif /* need schedparam */ diff --git a/libc/sysdeps/unix/sysv/linux/bits/siginfo.h b/libc/sysdeps/unix/sysv/linux/bits/siginfo.h index 4ce319dc9..d3dd4c21d 100644 --- a/libc/sysdeps/unix/sysv/linux/bits/siginfo.h +++ b/libc/sysdeps/unix/sysv/linux/bits/siginfo.h @@ -1,5 +1,5 @@ /* siginfo_t, sigevent and constants. Linux version. - Copyright (C) 1997-2002, 2003 Free Software Foundation, Inc. + Copyright (C) 1997-2002, 2003, 2011 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 @@ -142,7 +142,7 @@ enum # define SI_TIMER SI_TIMER SI_QUEUE, /* Sent by sigqueue. */ # define SI_QUEUE SI_QUEUE - SI_USER, /* Sent by kill, sigsend, raise. */ + SI_USER, /* Sent by kill, sigsend. */ # define SI_USER SI_USER SI_KERNEL = 0x80 /* Send by kernel. */ #define SI_KERNEL SI_KERNEL diff --git a/libc/sysdeps/unix/sysv/linux/bits/socket.h b/libc/sysdeps/unix/sysv/linux/bits/socket.h index 637375791..96d9fed03 100644 --- a/libc/sysdeps/unix/sysv/linux/bits/socket.h +++ b/libc/sysdeps/unix/sysv/linux/bits/socket.h @@ -421,7 +421,7 @@ struct linger __BEGIN_DECLS -/* Receive a message as described by MESSAGE from socket FD. +/* Receive up to VLEN messages as described by VMESSAGES from socket FD. Returns the number of bytes read or -1 for errors. This function is a cancellation point and therefore not marked with @@ -430,6 +430,13 @@ extern int recvmmsg (int __fd, struct mmsghdr *__vmessages, unsigned int __vlen, int __flags, __const struct timespec *__tmo); +/* Send a VLEN messages as described by VMESSAGES to socket FD. + Return the number of datagrams successfully written or -1 for errors. +This function is a cancellation point and therefore not marked with + __THROW. */ +extern int sendmmsg (int __fd, struct mmsghdr *__vmessages, + unsigned int __vlen, int __flags); + __END_DECLS #endif /* bits/socket.h */ diff --git a/libc/sysdeps/unix/sysv/linux/dl-osinfo.h b/libc/sysdeps/unix/sysv/linux/dl-osinfo.h index eb7fedc07..28fce4f8e 100644 --- a/libc/sysdeps/unix/sysv/linux/dl-osinfo.h +++ b/libc/sysdeps/unix/sysv/linux/dl-osinfo.h @@ -81,7 +81,7 @@ _dl_setup_stack_chk_guard (void *dl_random) { ssize_t reslen = read_not_cancel (fd, ret.bytes + 1, filllen); close_not_cancel_no_status (fd); - if (reslen == (ssize_) filllen) + if (reslen == (ssize_t) filllen) return ret.num; } # endif diff --git a/libc/sysdeps/unix/sysv/linux/ia64/bits/siginfo.h b/libc/sysdeps/unix/sysv/linux/ia64/bits/siginfo.h index 240ebbc9e..fea5af7fb 100644 --- a/libc/sysdeps/unix/sysv/linux/ia64/bits/siginfo.h +++ b/libc/sysdeps/unix/sysv/linux/ia64/bits/siginfo.h @@ -1,5 +1,5 @@ /* siginfo_t, sigevent and constants. Linux/ia64 version. - Copyright (C) 2000-2004, 2009 Free Software Foundation, Inc. + Copyright (C) 2000-2004, 2009, 2011 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by David Mosberger-Tang . @@ -146,7 +146,7 @@ enum # define SI_TIMER SI_TIMER SI_QUEUE, /* Sent by sigqueue. */ # define SI_QUEUE SI_QUEUE - SI_USER, /* Sent by kill, sigsend, raise. */ + SI_USER, /* Sent by kill, sigsend. */ # define SI_USER SI_USER SI_KERNEL = 0x80 /* Send by kernel. */ #define SI_KERNEL SI_KERNEL diff --git a/libc/sysdeps/unix/sysv/linux/internal_sendmmsg.S b/libc/sysdeps/unix/sysv/linux/internal_sendmmsg.S new file mode 100644 index 000000000..f5152c9f1 --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/internal_sendmmsg.S @@ -0,0 +1,14 @@ +#include +#include +#if !defined __NR_sendmmsg && defined __NR_socketcall +# define socket sendmmsg +# ifdef __ASSUME_SENDMMSG +# define __socket sendmmsg +# else +# define __socket __internal_sendmmsg +# endif +# define NARGS 4 +# define NEED_CANCELLATION +# define NO_WEAK_ALIAS +# include +#endif diff --git a/libc/sysdeps/unix/sysv/linux/kernel-features.h b/libc/sysdeps/unix/sysv/linux/kernel-features.h index d78f1015d..d91f581a9 100644 --- a/libc/sysdeps/unix/sysv/linux/kernel-features.h +++ b/libc/sysdeps/unix/sysv/linux/kernel-features.h @@ -541,3 +541,8 @@ #if __LINUX_KERNEL_VERSION >= 0x020624 # define __ASSUME_PRLIMIT64 1 #endif + +/* sendmmsg is available in 2.6.39. */ +#if __LINUX_KERNEL_VERSION >= 0x020627 +# define __ASSUME_SENDMMSG 1 +#endif diff --git a/libc/sysdeps/unix/sysv/linux/s390/bits/siginfo.h b/libc/sysdeps/unix/sysv/linux/s390/bits/siginfo.h index 55b3f88c0..70d91b470 100644 --- a/libc/sysdeps/unix/sysv/linux/s390/bits/siginfo.h +++ b/libc/sysdeps/unix/sysv/linux/s390/bits/siginfo.h @@ -1,5 +1,5 @@ /* siginfo_t, sigevent and constants. S/390 version. - Copyright (C) 2001, 2002, 2003, 2009 Free Software Foundation, Inc. + Copyright (C) 2001, 2002, 2003, 2009, 2011 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 @@ -144,7 +144,7 @@ enum # define SI_TIMER SI_TIMER SI_QUEUE, /* Sent by sigqueue. */ # define SI_QUEUE SI_QUEUE - SI_USER, /* Sent by kill, sigsend, raise. */ + SI_USER, /* Sent by kill, sigsend. */ # define SI_USER SI_USER SI_KERNEL = 0x80 /* Send by kernel. */ #define SI_KERNEL SI_KERNEL diff --git a/libc/sysdeps/unix/sysv/linux/sendmmsg.c b/libc/sysdeps/unix/sysv/linux/sendmmsg.c new file mode 100644 index 000000000..d8099878a --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/sendmmsg.c @@ -0,0 +1,96 @@ +/* Copyright (C) 2011 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 2011. + + 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_sendmmsg +int +sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags) +{ + if (SINGLE_THREAD_P) + return INLINE_SYSCALL (sendmmsg, 4, fd, vmessages, vlen, flags); + + int oldtype = LIBC_CANCEL_ASYNC (); + + int result = INLINE_SYSCALL (sendmmsg, 4, fd, vmessages, vlen, flags); + + LIBC_CANCEL_RESET (oldtype); + + return result; +} +#elif defined __NR_socketcall +# ifndef __ASSUME_SENDMMSG +extern int __internal_sendmmsg (int fd, struct mmsghdr *vmessages, + unsigned int vlen, int flags) + attribute_hidden; + +static int have_sendmmsg; + +int +sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags) +{ + if (__builtin_expect (have_sendmmsg >= 0, 1)) + { + int ret = __internal_sendmmsg (fd, vmessages, vlen, 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_sendmmsg == 0 + && errno == EINVAL) + { + /* Try another call, this time with an invalid file + descriptor and all other parameters cleared. This call + will not cause any harm and it will return + immediately. */ + ret = __internal_sendmmsg (-1, 0, 0, 0); + if (errno == EINVAL) + { + have_sendmmsg = -1; + __set_errno (ENOSYS); + } + else + { + have_sendmmsg = 1; + __set_errno (EINVAL); + } + return -1; + } + return ret; + } + __set_errno (ENOSYS); + return -1; +} +# else +/* When __ASSUME_SENDMMSG sendmmsg is defined in internal_sendmmsg.S. */ +# endif +#else +int +sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags) +{ + __set_errno (ENOSYS); + return -1; +} +stub_warning (sendmmsg) +#endif diff --git a/libc/sysdeps/unix/sysv/linux/socketcall.h b/libc/sysdeps/unix/sysv/linux/socketcall.h index bab4e4a51..73d4cb9de 100644 --- a/libc/sysdeps/unix/sysv/linux/socketcall.h +++ b/libc/sysdeps/unix/sysv/linux/socketcall.h @@ -1,5 +1,5 @@ /* ID for functions called via socketcall system call. - Copyright (C) 1995, 1996, 2008, 2009 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 2008, 2009, 2011 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 @@ -45,5 +45,6 @@ #define SOCKOP_recvmsg 17 #define SOCKOP_accept4 18 #define SOCKOP_recvmmsg 19 +#define SOCKOP_sendmmsg 20 #endif /* sys/socketcall.h */ diff --git a/libc/sysdeps/unix/sysv/linux/sparc/bits/siginfo.h b/libc/sysdeps/unix/sysv/linux/sparc/bits/siginfo.h index c0f98f607..aeba3fb35 100644 --- a/libc/sysdeps/unix/sysv/linux/sparc/bits/siginfo.h +++ b/libc/sysdeps/unix/sysv/linux/sparc/bits/siginfo.h @@ -1,5 +1,5 @@ /* siginfo_t, sigevent and constants. Linux/SPARC version. - Copyright (C) 1997-2002, 2003 Free Software Foundation, Inc. + Copyright (C) 1997-2002, 2003, 2011 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 @@ -144,7 +144,7 @@ enum # define SI_TIMER SI_TIMER SI_QUEUE, /* Sent by sigqueue. */ # define SI_QUEUE SI_QUEUE - SI_USER, /* Sent by kill, sigsend, raise. */ + SI_USER, /* Sent by kill, sigsend. */ # define SI_USER SI_USER SI_KERNEL = 0x80 /* Send by kernel. */ #define SI_KERNEL SI_KERNEL diff --git a/libc/sysdeps/unix/sysv/linux/syscalls.list b/libc/sysdeps/unix/sysv/linux/syscalls.list index 051303f07..2bed9e99e 100644 --- a/libc/sysdeps/unix/sysv/linux/syscalls.list +++ b/libc/sysdeps/unix/sysv/linux/syscalls.list @@ -107,3 +107,5 @@ fanotify_init EXTRA fanotify_init i:ii fanotify_init name_to_handle_at EXTRA name_to_handle_at i:isppi name_to_handle_at open_by_handle_at EXTRA open_by_handle_at Ci:ipi open_by_handle_at + +setns EXTRA setns i:ii setns diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/init-first.c b/libc/sysdeps/unix/sysv/linux/x86_64/init-first.c index ead7dbcc3..e676f623e 100644 --- a/libc/sysdeps/unix/sysv/linux/x86_64/init-first.c +++ b/libc/sysdeps/unix/sysv/linux/x86_64/init-first.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2007 Free Software Foundation, Inc. +/* Copyright (C) 2007, 2011 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 @@ -26,6 +26,10 @@ long int (*__vdso_clock_gettime) (clockid_t, struct timespec *) __attribute__ ((nocommon)); strong_alias (__vdso_clock_gettime, __GI___vdso_clock_gettime attribute_hidden) +long int (*__vdso_getcpu) (unsigned *, unsigned *, void *); + +long int (*__vdso_time) (time_t *) attribute_hidden; + static inline void _libc_vdso_platform_setup (void) @@ -43,6 +47,22 @@ _libc_vdso_platform_setup (void) p = _dl_vdso_vsym ("clock_gettime", &linux26); PTR_MANGLE (p); __GI___vdso_clock_gettime = p; + + p = _dl_vdso_vsym ("getcpu", &linux26); + /* If the vDSO is not available we fall back on the old vsyscall. */ +#define VSYSCALL_ADDR_vgetcpu 0xffffffffff600800 + if (p == NULL) + p = (void *) VSYSCALL_ADDR_vgetcpu; + PTR_MANGLE (p); + __vdso_getcpu = p; + + p = _dl_vdso_vsym ("time", &linux26); + /* If the vDSO is not available we fall back on the old vsyscall. */ +#define VSYSCALL_ADDR_vtime 0xffffffffff600400 + if (p == NULL) + p = (void *) VSYSCALL_ADDR_vtime; + PTR_MANGLE (p); + __vdso_time = p; } # define VDSO_SETUP _libc_vdso_platform_setup diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/sched_getcpu.S b/libc/sysdeps/unix/sysv/linux/x86_64/sched_getcpu.S index a95099062..8ec7d3fcd 100644 --- a/libc/sysdeps/unix/sysv/linux/x86_64/sched_getcpu.S +++ b/libc/sysdeps/unix/sysv/linux/x86_64/sched_getcpu.S @@ -1,4 +1,4 @@ -/* Copyright (C) 2007 Free Software Foundation, Inc. +/* Copyright (C) 2007, 2011 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 @@ -35,7 +35,12 @@ ENTRY (sched_getcpu) movl $VGETCPU_CACHE_OFFSET, %edx addq %fs:0, %rdx +#ifdef SHARED + movq __vdso_getcpu(%rip), %rax + PTR_DEMANGLE (%rax) +#else movq $VSYSCALL_ADDR_vgetcpu, %rax +#endif callq *%rax cmpq $-4095, %rax diff --git a/libc/sysdeps/unix/sysv/linux/x86_64/time.S b/libc/sysdeps/unix/sysv/linux/x86_64/time.S index e3f326876..66d7498ce 100644 --- a/libc/sysdeps/unix/sysv/linux/x86_64/time.S +++ b/libc/sysdeps/unix/sysv/linux/x86_64/time.S @@ -1,4 +1,4 @@ -/* Copyright (C) 2001,02, 2003 Free Software Foundation, Inc. +/* Copyright (C) 2001,02, 2003, 2011 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 @@ -32,7 +32,12 @@ ENTRY (time) sub $0x8, %rsp cfi_adjust_cfa_offset(8) +#ifdef SHARED + movq __vdso_time(%rip), %rax + PTR_DEMANGLE (%rax) +#else movq $VSYSCALL_ADDR_vtime, %rax +#endif callq *%rax add $0x8, %rsp -- cgit v1.2.3