1 2010-05-21 Andreas Schwab <schwab@redhat.com>
3 * sysdeps/unix/sysv/linux/Makefile (sysdep_routines): Add recvmmsg
5 * sysdeps/unix/sysv/linux/recvmmsg.c: New file.
6 * sysdeps/unix/sysv/linux/internal_recvmmsg.S: New file.
7 * sysdeps/unix/sysv/linux/socketcall.h (SOCKOP_recvmmsg): Define.
8 * sysdeps/unix/sysv/linux/syscalls.list (recvmmsg): Remove.
10 Index: glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/Makefile
11 ===================================================================
12 --- glibc-2.12-2-gc4ccff1.orig/sysdeps/unix/sysv/linux/Makefile
13 +++ glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/Makefile
14 @@ -12,7 +12,7 @@ CFLAGS-malloc.c += -DMORECORE_CLEARS=2
17 ifeq ($(subdir),socket)
18 -sysdep_routines += internal_accept4
19 +sysdep_routines += internal_accept4 recvmmsg internal_recvmmsg
23 Index: glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/internal_recvmmsg.S
24 ===================================================================
26 +++ glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/internal_recvmmsg.S
28 +#include <kernel-features.h>
29 +#include <sys/syscall.h>
30 +#if !defined __NR_recvmmsg && defined __NR_socketcall
31 +# define socket recvmmsg
32 +# ifdef __ASSUME_RECVMMSG
33 +# define __socket recvmmsg
35 +# define __socket __internal_recvmmsg
38 +# define NEED_CANCELLATION
39 +# define NO_WEAK_ALIAS
42 Index: glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/kernel-features.h
43 ===================================================================
44 --- glibc-2.12-2-gc4ccff1.orig/sysdeps/unix/sysv/linux/kernel-features.h
45 +++ glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/kernel-features.h
47 #if __LINUX_KERNEL_VERSION >= 0x020620
48 # define __ASSUME_F_GETOWN_EX 1
51 +/* Support for the recvmmsg syscall was added in 2.6.33. */
52 +#if __LINUX_KERNEL_VERSION >= 0x020621
53 +# define __ASSUME_RECVMMSG 1
55 Index: glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/recvmmsg.c
56 ===================================================================
58 +++ glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/recvmmsg.c
60 +/* Copyright (C) 2010 Free Software Foundation, Inc.
61 + This file is part of the GNU C Library.
62 + Contributed by Andreas Schwab <schwab@redhat.com>, 2010.
64 + The GNU C Library is free software; you can redistribute it and/or
65 + modify it under the terms of the GNU Lesser General Public
66 + License as published by the Free Software Foundation; either
67 + version 2.1 of the License, or (at your option) any later version.
69 + The GNU C Library is distributed in the hope that it will be useful,
70 + but WITHOUT ANY WARRANTY; without even the implied warranty of
71 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
72 + Lesser General Public License for more details.
74 + You should have received a copy of the GNU Lesser General Public
75 + License along with the GNU C Library; if not, write to the Free
76 + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
80 +#include <sys/socket.h>
82 +#include <sysdep-cancel.h>
83 +#include <sys/syscall.h>
84 +#include <kernel-features.h>
89 +recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
90 + const struct timespec *tmo)
92 + if (SINGLE_THREAD_P)
93 + return INLINE_SYSCALL (recvmmsg, 5, fd, vmessages, vlen, flags, tmo);
95 + int oldtype = LIBC_CANCEL_ASYNC ();
97 + int result = INLINE_SYSCALL (recvmmsg, 5, fd, vmessages, vlen, flags, tmo);
99 + LIBC_CANCEL_RESET (oldtype);
103 +#elif defined __NR_socketcall
104 +# ifndef __ASSUME_RECVMMSG
105 +extern int __internal_recvmmsg (int fd, struct mmsghdr *vmessages,
106 + unsigned int vlen, int flags,
107 + const struct timespec *tmo)
110 +static int have_recvmmsg;
113 +recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
114 + const struct timespec *tmo)
116 + if (__builtin_expect (have_recvmmsg >= 0, 1))
118 + int ret = __internal_recvmmsg (fd, vmessages, vlen, flags, tmo);
119 + /* The kernel returns -EINVAL for unknown socket operations.
120 + We need to convert that error to an ENOSYS error. */
121 + if (__builtin_expect (ret < 0, 0)
122 + && have_recvmmsg == 0
123 + && errno == EINVAL)
125 + /* Try another call, this time with an invalid file
126 + descriptor and all other parameters cleared. This call
127 + will not cause any harm and it will return
129 + ret = __internal_recvmmsg (-1, 0, 0, 0, 0);
130 + if (errno == EINVAL)
132 + have_recvmmsg = -1;
133 + __set_errno (ENOSYS);
138 + __set_errno (EINVAL);
144 + __set_errno (ENOSYS);
148 +/* When __ASSUME_RECVMMSG recvmmsg is defined in internal_recvmmsg.S. */
152 +recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
153 + const struct timespec *tmo)
155 + __set_errno (ENOSYS);
158 +stub_warning (recvmmsg)
160 Index: glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/socketcall.h
161 ===================================================================
162 --- glibc-2.12-2-gc4ccff1.orig/sysdeps/unix/sysv/linux/socketcall.h
163 +++ glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/socketcall.h
165 #define SOCKOP_sendmsg 16
166 #define SOCKOP_recvmsg 17
167 #define SOCKOP_accept4 18
168 +#define SOCKOP_recvmmsg 19
170 #endif /* sys/socketcall.h */
171 Index: glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/syscalls.list
172 ===================================================================
173 --- glibc-2.12-2-gc4ccff1.orig/sysdeps/unix/sysv/linux/syscalls.list
174 +++ glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/syscalls.list
175 @@ -53,7 +53,6 @@ prctl EXTRA prctl i:iiiii __prctl prc
176 putpmsg - putpmsg i:ippii putpmsg
177 query_module EXTRA query_module i:sipip query_module
178 quotactl EXTRA quotactl i:isip quotactl
179 -recvmmsg EXTRA recvmmsg Ci:ipiip recvmmsg
180 remap_file_pages - remap_file_pages i:piiii __remap_file_pages remap_file_pages
181 sched_getp - sched_getparam i:ip __sched_getparam sched_getparam
182 sched_gets - sched_getscheduler i:i __sched_getscheduler sched_getscheduler