]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/glibc/glibc-recvmmsg.patch
Merge remote-tracking branch 'origin/next' into thirteen
[people/pmueller/ipfire-2.x.git] / src / patches / glibc / glibc-recvmmsg.patch
1 2010-05-21 Andreas Schwab <schwab@redhat.com>
2
3 * sysdeps/unix/sysv/linux/Makefile (sysdep_routines): Add recvmmsg
4 and internal_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.
9
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
15 endif
16
17 ifeq ($(subdir),socket)
18 -sysdep_routines += internal_accept4
19 +sysdep_routines += internal_accept4 recvmmsg internal_recvmmsg
20 endif
21
22 ifeq ($(subdir),misc)
23 Index: glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/internal_recvmmsg.S
24 ===================================================================
25 --- /dev/null
26 +++ glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/internal_recvmmsg.S
27 @@ -0,0 +1,14 @@
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
34 +# else
35 +# define __socket __internal_recvmmsg
36 +# endif
37 +# define NARGS 5
38 +# define NEED_CANCELLATION
39 +# define NO_WEAK_ALIAS
40 +# include <socket.S>
41 +#endif
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
46 @@ -547,3 +547,8 @@
47 #if __LINUX_KERNEL_VERSION >= 0x020620
48 # define __ASSUME_F_GETOWN_EX 1
49 #endif
50 +
51 +/* Support for the recvmmsg syscall was added in 2.6.33. */
52 +#if __LINUX_KERNEL_VERSION >= 0x020621
53 +# define __ASSUME_RECVMMSG 1
54 +#endif
55 Index: glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/recvmmsg.c
56 ===================================================================
57 --- /dev/null
58 +++ glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/recvmmsg.c
59 @@ -0,0 +1,100 @@
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.
63 +
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.
68 +
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.
73 +
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
77 + 02111-1307 USA. */
78 +
79 +#include <errno.h>
80 +#include <sys/socket.h>
81 +
82 +#include <sysdep-cancel.h>
83 +#include <sys/syscall.h>
84 +#include <kernel-features.h>
85 +
86 +
87 +#ifdef __NR_recvmmsg
88 +int
89 +recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
90 + const struct timespec *tmo)
91 +{
92 + if (SINGLE_THREAD_P)
93 + return INLINE_SYSCALL (recvmmsg, 5, fd, vmessages, vlen, flags, tmo);
94 +
95 + int oldtype = LIBC_CANCEL_ASYNC ();
96 +
97 + int result = INLINE_SYSCALL (recvmmsg, 5, fd, vmessages, vlen, flags, tmo);
98 +
99 + LIBC_CANCEL_RESET (oldtype);
100 +
101 + return result;
102 +}
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)
108 + attribute_hidden;
109 +
110 +static int have_recvmmsg;
111 +
112 +int
113 +recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
114 + const struct timespec *tmo)
115 +{
116 + if (__builtin_expect (have_recvmmsg >= 0, 1))
117 + {
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)
124 + {
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
128 + immediately. */
129 + ret = __internal_recvmmsg (-1, 0, 0, 0, 0);
130 + if (errno == EINVAL)
131 + {
132 + have_recvmmsg = -1;
133 + __set_errno (ENOSYS);
134 + }
135 + else
136 + {
137 + have_recvmmsg = 1;
138 + __set_errno (EINVAL);
139 + }
140 + return -1;
141 + }
142 + return ret;
143 + }
144 + __set_errno (ENOSYS);
145 + return -1;
146 +}
147 +# else
148 +/* When __ASSUME_RECVMMSG recvmmsg is defined in internal_recvmmsg.S. */
149 +# endif
150 +#else
151 +int
152 +recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
153 + const struct timespec *tmo)
154 +{
155 + __set_errno (ENOSYS);
156 + return -1;
157 +}
158 +stub_warning (recvmmsg)
159 +#endif
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
164 @@ -44,5 +44,6 @@
165 #define SOCKOP_sendmsg 16
166 #define SOCKOP_recvmsg 17
167 #define SOCKOP_accept4 18
168 +#define SOCKOP_recvmmsg 19
169
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