]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/glibc/glibc-recvmmsg.patch
dhcpcd: fix delay after dhcp down.
[ipfire-2.x.git] / src / patches / glibc / glibc-recvmmsg.patch
CommitLineData
12788f63
MT
12010-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
10Index: 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)
23Index: 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
42Index: 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
55Index: 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
160Index: 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 */
171Index: 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