glibc/sysdeps/unix/sysv/linux/recvmmsg.c

111 lines
3.3 KiB
C
Raw Normal View History

/* Copyright (C) 2010-2016 Free Software Foundation, Inc.
2010-05-21 12:11:28 -07:00
This file is part of the GNU C Library.
Contributed by Andreas Schwab <schwab@redhat.com>, 2010.
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, see
<http://www.gnu.org/licenses/>. */
2010-05-21 12:11:28 -07:00
#include <sys/socket.h>
network: recvmmsg and sendmmsg standard compliance (BZ#16919) POSIX specifies that both msghdr::msg_iovlen and msghdr::msg_controllen to be of size int and socklen_t respectively, however Linux implements it as a size_t. So for 64-bits architecture where sizeof of size_t is larger than socklen_t, both sendmmsg and recvmmsg need to adjust the mmsghdr::msg_hdr internal fields before issuing the syscall itself. This patch fixes it by operating on the padding if it the case. For recvmmsg, the most straightfoward case, only zero padding the fields is suffice. However, for sendmmsg, where adjusting the buffer is out of the contract (since it may point to a read-only data), the function is rewritten to use sendmsg instead (which from previous patch allocates a temporary msghdr to operate on). Also for 64-bit ports that requires it, a new recvmmsg and sendmmsg compat version is created (which uses size_t for both cmsghdr::cmsg_len and internal Tested on x86_64, i686, aarch64, armhf, and powerpc64le. * sysdeps/unix/sysv/linux/Makefile [$(subdir) = socket] (sysdep_routines): Add oldrecvmmsg and oldsendmmsg. * sysdeps/unix/sysv/linux/aarch64/libc.abilist: Add recvmmsg and sendmmsg. * sysdeps/unix/sysv/linux/alpha/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/ia64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist: Likewise. * sysdeps/sysv/linux/powerpc/powerpc64/libc-le.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/x86_64/64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/oldrecvmmsg.c: New file. * sysdeps/unix/sysv/linux/oldsendmmsg.c: Likewise. * sysdeps/unix/sysv/linux/recvmmsg.c (__recvmmsg): Adjust msghdr iovlen and controllen fields to adjust to POSIX specification. * sysdeps/unix/sysv/linux/sendmmsg.c (__sendmmsg): Likewise.
2016-03-17 09:52:17 -03:00
#include <socketcall.h>
2010-05-21 12:11:28 -07:00
#include <sysdep-cancel.h>
network: recvmmsg and sendmmsg standard compliance (BZ#16919) POSIX specifies that both msghdr::msg_iovlen and msghdr::msg_controllen to be of size int and socklen_t respectively, however Linux implements it as a size_t. So for 64-bits architecture where sizeof of size_t is larger than socklen_t, both sendmmsg and recvmmsg need to adjust the mmsghdr::msg_hdr internal fields before issuing the syscall itself. This patch fixes it by operating on the padding if it the case. For recvmmsg, the most straightfoward case, only zero padding the fields is suffice. However, for sendmmsg, where adjusting the buffer is out of the contract (since it may point to a read-only data), the function is rewritten to use sendmsg instead (which from previous patch allocates a temporary msghdr to operate on). Also for 64-bit ports that requires it, a new recvmmsg and sendmmsg compat version is created (which uses size_t for both cmsghdr::cmsg_len and internal Tested on x86_64, i686, aarch64, armhf, and powerpc64le. * sysdeps/unix/sysv/linux/Makefile [$(subdir) = socket] (sysdep_routines): Add oldrecvmmsg and oldsendmmsg. * sysdeps/unix/sysv/linux/aarch64/libc.abilist: Add recvmmsg and sendmmsg. * sysdeps/unix/sysv/linux/alpha/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/ia64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist: Likewise. * sysdeps/sysv/linux/powerpc/powerpc64/libc-le.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/x86_64/64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/oldrecvmmsg.c: New file. * sysdeps/unix/sysv/linux/oldsendmmsg.c: Likewise. * sysdeps/unix/sysv/linux/recvmmsg.c (__recvmmsg): Adjust msghdr iovlen and controllen fields to adjust to POSIX specification. * sysdeps/unix/sysv/linux/sendmmsg.c (__sendmmsg): Likewise.
2016-03-17 09:52:17 -03:00
#include <shlib-compat.h>
2010-05-21 12:11:28 -07:00
Fix __ASSUME_RECVMMSG issues (bug 16610). Similar to the issues for accept4, __ASSUME_RECVMMSG is also confused about whether it relates to function availability or socketcall operation availability; this is now bug 16610. Nothing actually tests __ASSUME_RECVMMSG for function availability, but implicit in the definition in kernel-features.h is the idea that it makes sense when the syscall is available and socketcall is not being used. As with accept4, there are architectures where the syscall was added later than the socketcall operation, meaning that assuming glibc is built with recent enough kernel headers, it does not attempt to use socketcall for these operations and __ASSUME_RECVMMSG gets defined for kernels >= 2.6.33 even when the syscall was only added later. This patch splits the macro into separate macros like those used for accept4; having similar macro structure in both cases (and for sendmmsg once I've dealt with that) seems likely to be less confusing than having a different structure on the basis of nothing actually needing to assume the recvmmsg function works. Appropriate definitions are added for all architectures. Architecture-specific note: Tile's kernel-features.h says "TILE glibc support starts with 2.6.36", which is accurate in that 2.6.36 was the first kernel version with Tile support, and on that basis I've made that header define __ASSUME_RECVMMSG_SYSCALL unconditionally. However, Tile's configure.ac has arch_minimum_kernel=2.6.32. Since arch_minimum_kernel is meant to reflect only kernel.org kernel versions, I think that should change to 2.6.36. (If using glibc with kernel versions from before a port went in kernel.org, it's your responsibility to change arch_minimum_kernel in a local patch, and at the same time to adjust any __ASSUME_* definitions that may not be correct for your older kernel; for developing the official glibc it should only ever be necessary to consider what official kernel.org releases support.) Tested x86_64, including that disassembly of the installed shared libraries is unchanged by this patch. [BZ #16610] * sysdeps/unix/sysv/linux/kernel-features.h [__LINUX_KERNEL_VERSION >= 0x020621 && __ASSUME_SOCKETCALL] (__ASSUME_RECVMMSG_SOCKETCALL): Define. [(__LINUX_KERNEL_VERSION >= 0x020621 && (__i386__ || __x86_64__ || __sparc__)) || (__LINUX_KERNEL_VERSION >= 0x020625 && (__powerpc__ || __sh__))] (__ASSUME_RECVMMSG_SYSCALL): Likewise. [__i386__ || __sparc__] (__ASSUME_RECVMMSG_SYSCALL_WITH_SOCKETCALL): Likewise. [__ASSUME_RECVMMSG_SOCKETCALL || __ASSUME_RECVMMSG_SYSCALL] (__ASSUME_RECVMMSG): Define instead of using previous [__LINUX_KERNEL_VERSION >= 0x020621] condition. * sysdeps/unix/sysv/linux/aarch64/kernel-features.h (__ASSUME_RECVMMSG_SYSCALL): Define. * sysdeps/unix/sysv/linux/alpha/kernel-features.h [__LINUX_KERNEL_VERSION >= 0x020621] (__ASSUME_RECVMMSG_SYSCALL): Likewise. * sysdeps/unix/sysv/linux/arm/kernel-features.h [__LINUX_KERNEL_VERSION >= 0x020621] (__ASSUME_RECVMMSG_SYSCALL): Likewise. * sysdeps/unix/sysv/linux/ia64/kernel-features.h [__LINUX_KERNEL_VERSION >= 0x020621] (__ASSUME_RECVMMSG_SYSCALL): Likewise. * sysdeps/unix/sysv/linux/internal_recvmmsg.S [__ASSUME_SOCKETCALL && !__ASSUME_RECVMMSG_SYSCALL_WITH_SOCKETCALL && !__ASSUME_RECVMMSG_SYSCALL] (__NR_recvmmsg): Undefine. [__ASSUME_RECVMMSG]: Change condition to [__ASSUME_RECVMMSG_SOCKETCALL]. * sysdeps/unix/sysv/linux/microblaze/kernel-features.h [__LINUX_KERNEL_VERSION >= 0x020621] (__ASSUME_RECVMMSG_SYSCALL): Define. (__ASSUME_RECVMMSG_SYSCALL_WITH_SOCKETCALL): Likewise. * sysdeps/unix/sysv/linux/mips/kernel-features.h [__LINUX_KERNEL_VERSION >= 0x020621] (__ASSUME_RECVMMSG_SYSCALL): Likewise. * sysdeps/unix/sysv/linux/recvmmsg.c [__ASSUME_SOCKETCALL && !__ASSUME_RECVMMSG_SYSCALL_WITH_SOCKETCALL && !__ASSUME_RECVMMSG_SYSCALL] (__NR_recvmmsg): Undefine. [!__ASSUME_RECVMMSG]: Change condition to [!__ASSUME_RECVMMSG_SOCKETCALL]. * sysdeps/unix/sysv/linux/tile/kernel-features.h (__ASSUME_RECVMMSG_SYSCALL): Define. * sysdeps/unix/sysv/linux/hppa/kernel-features.h [__LINUX_KERNEL_VERSION >= 0x020622] (__ASSUME_RECVMMSG_SYSCALL): Define.
2014-02-20 17:53:08 +00:00
/* Do not use the recvmmsg syscall on socketcall architectures unless
it was added at the same time as the socketcall support or can be
assumed to be present. */
#if defined __ASSUME_SOCKETCALL \
&& !defined __ASSUME_RECVMMSG_SYSCALL_WITH_SOCKETCALL \
&& !defined __ASSUME_RECVMMSG_SYSCALL
# undef __NR_recvmmsg
#endif
2010-05-21 12:11:28 -07:00
network: recvmmsg and sendmmsg standard compliance (BZ#16919) POSIX specifies that both msghdr::msg_iovlen and msghdr::msg_controllen to be of size int and socklen_t respectively, however Linux implements it as a size_t. So for 64-bits architecture where sizeof of size_t is larger than socklen_t, both sendmmsg and recvmmsg need to adjust the mmsghdr::msg_hdr internal fields before issuing the syscall itself. This patch fixes it by operating on the padding if it the case. For recvmmsg, the most straightfoward case, only zero padding the fields is suffice. However, for sendmmsg, where adjusting the buffer is out of the contract (since it may point to a read-only data), the function is rewritten to use sendmsg instead (which from previous patch allocates a temporary msghdr to operate on). Also for 64-bit ports that requires it, a new recvmmsg and sendmmsg compat version is created (which uses size_t for both cmsghdr::cmsg_len and internal Tested on x86_64, i686, aarch64, armhf, and powerpc64le. * sysdeps/unix/sysv/linux/Makefile [$(subdir) = socket] (sysdep_routines): Add oldrecvmmsg and oldsendmmsg. * sysdeps/unix/sysv/linux/aarch64/libc.abilist: Add recvmmsg and sendmmsg. * sysdeps/unix/sysv/linux/alpha/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/ia64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist: Likewise. * sysdeps/sysv/linux/powerpc/powerpc64/libc-le.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/x86_64/64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/oldrecvmmsg.c: New file. * sysdeps/unix/sysv/linux/oldsendmmsg.c: Likewise. * sysdeps/unix/sysv/linux/recvmmsg.c (__recvmmsg): Adjust msghdr iovlen and controllen fields to adjust to POSIX specification. * sysdeps/unix/sysv/linux/sendmmsg.c (__sendmmsg): Likewise.
2016-03-17 09:52:17 -03:00
static inline void
adjust_mmsghdr (struct mmsghdr *vmessages, unsigned int vlen)
{
#if __WORDSIZE == 64
/* POSIX specifies that both msghdr::msg_iovlen and msghdr::msg_controllen
to be int and socklen_t respectively. However Linux defines it as
both size_t. So for 64-bit it requires some adjustments by zeroing
the pad fields. */
struct mmsghdr *vmhdr = vmessages;
for (unsigned int i = 0; i != 0; i--, vmhdr++)
{
vmhdr->msg_hdr.__glibc_reserved1 = 0;
vmhdr->msg_hdr.__glibc_reserved2 = 0;
}
#endif
}
2010-05-21 12:11:28 -07:00
int
network: recvmmsg and sendmmsg standard compliance (BZ#16919) POSIX specifies that both msghdr::msg_iovlen and msghdr::msg_controllen to be of size int and socklen_t respectively, however Linux implements it as a size_t. So for 64-bits architecture where sizeof of size_t is larger than socklen_t, both sendmmsg and recvmmsg need to adjust the mmsghdr::msg_hdr internal fields before issuing the syscall itself. This patch fixes it by operating on the padding if it the case. For recvmmsg, the most straightfoward case, only zero padding the fields is suffice. However, for sendmmsg, where adjusting the buffer is out of the contract (since it may point to a read-only data), the function is rewritten to use sendmsg instead (which from previous patch allocates a temporary msghdr to operate on). Also for 64-bit ports that requires it, a new recvmmsg and sendmmsg compat version is created (which uses size_t for both cmsghdr::cmsg_len and internal Tested on x86_64, i686, aarch64, armhf, and powerpc64le. * sysdeps/unix/sysv/linux/Makefile [$(subdir) = socket] (sysdep_routines): Add oldrecvmmsg and oldsendmmsg. * sysdeps/unix/sysv/linux/aarch64/libc.abilist: Add recvmmsg and sendmmsg. * sysdeps/unix/sysv/linux/alpha/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/ia64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist: Likewise. * sysdeps/sysv/linux/powerpc/powerpc64/libc-le.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/x86_64/64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/oldrecvmmsg.c: New file. * sysdeps/unix/sysv/linux/oldsendmmsg.c: Likewise. * sysdeps/unix/sysv/linux/recvmmsg.c (__recvmmsg): Adjust msghdr iovlen and controllen fields to adjust to POSIX specification. * sysdeps/unix/sysv/linux/sendmmsg.c (__sendmmsg): Likewise.
2016-03-17 09:52:17 -03:00
__recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen,
int flags, struct timespec *tmo)
2010-05-21 12:11:28 -07:00
{
network: recvmmsg and sendmmsg standard compliance (BZ#16919) POSIX specifies that both msghdr::msg_iovlen and msghdr::msg_controllen to be of size int and socklen_t respectively, however Linux implements it as a size_t. So for 64-bits architecture where sizeof of size_t is larger than socklen_t, both sendmmsg and recvmmsg need to adjust the mmsghdr::msg_hdr internal fields before issuing the syscall itself. This patch fixes it by operating on the padding if it the case. For recvmmsg, the most straightfoward case, only zero padding the fields is suffice. However, for sendmmsg, where adjusting the buffer is out of the contract (since it may point to a read-only data), the function is rewritten to use sendmsg instead (which from previous patch allocates a temporary msghdr to operate on). Also for 64-bit ports that requires it, a new recvmmsg and sendmmsg compat version is created (which uses size_t for both cmsghdr::cmsg_len and internal Tested on x86_64, i686, aarch64, armhf, and powerpc64le. * sysdeps/unix/sysv/linux/Makefile [$(subdir) = socket] (sysdep_routines): Add oldrecvmmsg and oldsendmmsg. * sysdeps/unix/sysv/linux/aarch64/libc.abilist: Add recvmmsg and sendmmsg. * sysdeps/unix/sysv/linux/alpha/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/ia64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist: Likewise. * sysdeps/sysv/linux/powerpc/powerpc64/libc-le.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/x86_64/64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/oldrecvmmsg.c: New file. * sysdeps/unix/sysv/linux/oldsendmmsg.c: Likewise. * sysdeps/unix/sysv/linux/recvmmsg.c (__recvmmsg): Adjust msghdr iovlen and controllen fields to adjust to POSIX specification. * sysdeps/unix/sysv/linux/sendmmsg.c (__sendmmsg): Likewise.
2016-03-17 09:52:17 -03:00
#ifdef __NR_recvmmsg
adjust_mmsghdr (vmessages, vlen);
nptl: Rewrite cancellation macros This patch changes the way cancellation entrypoints are defined to instead call the macro SYSCALL_CANCEL. An usual cnacellation definition is defined as: if (SINGLE_THREAD_P) return INLINE_SYSCALL (syscall, NARGS, args...) int oldtype = LIBC_CANCEL_ASYNC (); return INLINE_SYSCALL (syscall, NARGS, args...) LIBC_CANCEL_RESET (oldtype); And it is rewrited as just: SYSCALL_CANCEL (syscall, args...) The idea is to remove LIBC_CANCEL_ASYNC/LIBC_CANCEL_RESET explicit usage. Tested on i386, x86_64, powerpc32, powerpc64le, arm, and aarch64. * sysdeps/unix/sysdep.h [SYSCALL_CANCEL]: New macro: define cancellable syscalls. (SYS_ify): Add guard to no redefine it. (INLINE_SYSCALL): Likewise. * sysdeps/unix/sysv/linux/accept4.c (accept4): Remove LIBC_CANCEL_ASYNC/INLINE_SYSCALL/LIBC_CANCEL_RESET and use SYSCALL_CANCEL instead. * sysdeps/unix/sysv/linux/alpha/fdatasync.c (__fdatasync): Likewise. * sysdeps/unix/sysv/linux/arm/pread.c (__libc_pread): Likewise. * sysdeps/unix/sysv/linux/arm/pread64.c (__libc_pread64): Likewise. * sysdeps/unix/sysv/linux/arm/pwrite.c (__libc_pwrite): Likewise. * sysdeps/unix/sysv/linux/arm/pwrite64.c (__libc_pwrite64): Likewise. * sysdeps/unix/sysv/linux/epoll_pwait.c (epoll_pwait): Likewise. * sysdeps/unix/sysv/linux/fallocate.c (fallocate): Likewise. * sysdeps/unix/sysv/linux/fallocate64.c (fallocate64): Likewise. * sysdeps/unix/sysv/linux/generic/open.c (__libc_open): Likewise. * sysdeps/unix/sysv/linux/generic/open64.c (__libc_open64): Likewise. * sysdeps/unix/sysv/linux/generic/pause.c (__libc_pause): Likewise. * sysdeps/unix/sysv/linux/generic/poll.c (__poll): Likewise. * sysdeps/unix/sysv/linux/generic/recv.c (__libc_recv): Likewise. * sysdeps/unix/sysv/linux/generic/select.c (__select): Likewise. * sysdeps/unix/sysv/linux/generic/send.c (__libc_send): Likewise. * sysdeps/unix/sysv/linux/generic/wordsize-32/pread.c (__libc_pread): Likewise. * sysdeps/unix/sysv/linux/generic/wordsize-32/pread64.c (__libc_pread64): Likewise. * sysdeps/unix/sysv/linux/generic/wordsize-32/preadv.c (__libc_preadv): Likewise. * sysdeps/unix/sysv/linux/generic/wordsize-32/preadv64.c (__libc_readv64): Likewise. * sysdeps/unix/sysv/linux/generic/wordsize-32/pwrite.c (__libc_pwrite): Likewise. * sysdeps/unix/sysv/linux/generic/wordsize-32/pwrite64.c (__libc_pwrite64): Likewise. * sysdeps/unix/sysv/linux/generic/wordsize-32/pwritev.c (__libc_pwritev): Likewise. * sysdeps/sysv/linux/generic/wordsize-32/pwritev64.c (__libc_pwritev64): Likewise. * sysdeps/unix/sysv/linux/i386/fcntl.c (__libc_fcntl): Likewise. * sysdeps/unix/sysv/linux/mips/mips32/sync_file_range.c (sync_file_range): Likewise. * sysdeps/unix/sysv/linux/mips/mips64/n32/fallocate.c (fallocate): Likewise. * sysdeps/unix/sysv/linux/mips/mips64/n32/fallocate64.c (fallocate64): Likewise. * sysdeps/unix/sysv/linux/mips/pread.c (__libc_pread): Likewise. * sysdeps/unix/sysv/linux/mips/pread64.c (__libc_pread64): Likewise. * sysdeps/unix/sysv/linux/mips/pwrite.c (__libc_pwrite): Likewise. * sysdeps/unix/sysv/linux/mips/pwrite64.c (__libc_pwrite64): Likewise. * sysdeps/unix/sysv/linux/msgrcv.c (__libc_msgrcv): Likewise. * sysdeps/unix/sysv/linux/msgsnd.c (__libc_msgsnd): Likewise. * sysdeps/unix/sysv/linux/open64.c (__libc_open64): Likewise. * sysdeps/unix/sysv/linux/openat.c (__libc_openat): Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc32/pread.c (__libc_pread): Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc32/pread64.c (__libc_read64): Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite.c (__libc_write): Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc32/pwrite64.c (__libc_write64): Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/fcntl.c (__libc_fcntl): Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/pread.c (__libc_pread): Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/pread64.c (__libc_pread64): Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/pwrite.c (__libc_pwrite): Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/pwrite64.c (__libc_pwrite64): Likewise. * sysdeps/sysv/linux/powerpc/powerpc64/sync_file_range.c (sync_file_range): Likewise. * sysdeps/unix/sysv/linux/ppoll.c (ppoll): Likewise. * sysdeps/unix/sysv/linux/pread.c (__libc_pread): Likewise. * sysdeps/unix/sysv/linux/pread64.c (__libc_pread64): Likewise. * sysdeps/unix/sysv/linux/preadv.c (__libc_preadv): Likewise. * sysdeps/unix/sysv/linux/pselect.c (__pselect): Likewise. * sysdeps/unix/sysv/linux/pwrite.c (__libc_pwrite): Likewise. * sysdeps/unix/sysv/linux/pwrite64.c (__libc_pwrite64): Likewise. * sysdeps/unix/sysv/linux/pwritev.c (PWRITEV): Likewise. * sysdeps/unix/sysv/linux/readv.c (__libc_readv): Likewise. * sysdeps/unix/sysv/linux/recvmmsg.c (recvmmsg): Likewise. * sysdeps/unix/sysv/linux/sendmmsg.c (sendmmsg): Likewise. * sysdeps/unix/sysv/linux/sh/pread.c (__libc_pread): Likewise. * sysdeps/unix/sysv/linux/sh/pread64.c (__libc_pread64): Likewise. * sysdeps/unix/sysv/linux/sh/pwrite.c (__libc_pwrite): Likewise. * sysdeps/unix/sysv/linux/sh/pwrite64.c (__libc_pwrite64): Likewise. * sysdeps/unix/sysv/linux/sigsuspend.c (__sigsuspend): Likewise. * sysdeps/unix/sysv/linux/sigtimedwait.c (__sigtimedwait): Likewise. * sysdeps/unix/sysv/linux/sigwaitinfo.c (__sigwaitinfo): Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/msgrcv.c (__libc_msgrcv): Likewise. * sysdeps/unix/sysv/linux/sync_file_range.c (sync_file_range): Likewise. * sysdeps/unix/sysv/linux/tcdrain.c (__libc_tcdrain): Likewise. * sysdeps/unix/sysv/linux/timer_routines.c (timer_helper_thread): Likewise. * sysdeps/unix/sysv/linux/wait.c (__libc_wait): Likewise. * sysdeps/unix/sysv/linux/waitid.c (__waitid): Likewise. * sysdeps/unix/sysv/linux/waitpid.c (__libc_waitpid): Likewise. * sysdeps/unix/sysv/linux/wordsize-64/fallocate.c (fallocate): Likewise. * sysdeps/unix/sysv/linux/wordsize-64/preadv.c (preadv): Likewise. * sysdeps/unix/sysv/linux/wordsize-64/pwritev.c (pwritev): Likewise. * sysdeps/unix/sysv/linux/writev.c (__libc_writev): Likewise. * sysdeps/unix/sysv/linux/x86_64/recv.c (__libc_recv): Likewise. * sysdeps/unix/sysv/linux/x86_64/send.c (__libc_send): Likewise.
2014-09-28 08:46:23 -03:00
return SYSCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags, tmo);
2010-05-21 12:11:28 -07:00
#elif defined __NR_socketcall
# ifdef __ASSUME_RECVMMSG_SOCKETCALL
network: recvmmsg and sendmmsg standard compliance (BZ#16919) POSIX specifies that both msghdr::msg_iovlen and msghdr::msg_controllen to be of size int and socklen_t respectively, however Linux implements it as a size_t. So for 64-bits architecture where sizeof of size_t is larger than socklen_t, both sendmmsg and recvmmsg need to adjust the mmsghdr::msg_hdr internal fields before issuing the syscall itself. This patch fixes it by operating on the padding if it the case. For recvmmsg, the most straightfoward case, only zero padding the fields is suffice. However, for sendmmsg, where adjusting the buffer is out of the contract (since it may point to a read-only data), the function is rewritten to use sendmsg instead (which from previous patch allocates a temporary msghdr to operate on). Also for 64-bit ports that requires it, a new recvmmsg and sendmmsg compat version is created (which uses size_t for both cmsghdr::cmsg_len and internal Tested on x86_64, i686, aarch64, armhf, and powerpc64le. * sysdeps/unix/sysv/linux/Makefile [$(subdir) = socket] (sysdep_routines): Add oldrecvmmsg and oldsendmmsg. * sysdeps/unix/sysv/linux/aarch64/libc.abilist: Add recvmmsg and sendmmsg. * sysdeps/unix/sysv/linux/alpha/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/ia64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist: Likewise. * sysdeps/sysv/linux/powerpc/powerpc64/libc-le.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/x86_64/64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/oldrecvmmsg.c: New file. * sysdeps/unix/sysv/linux/oldsendmmsg.c: Likewise. * sysdeps/unix/sysv/linux/recvmmsg.c (__recvmmsg): Adjust msghdr iovlen and controllen fields to adjust to POSIX specification. * sysdeps/unix/sysv/linux/sendmmsg.c (__sendmmsg): Likewise.
2016-03-17 09:52:17 -03:00
adjust_mmsghdr (vmessages, vlen);
return SOCKETCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags, tmo);
# else
network: recvmmsg and sendmmsg standard compliance (BZ#16919) POSIX specifies that both msghdr::msg_iovlen and msghdr::msg_controllen to be of size int and socklen_t respectively, however Linux implements it as a size_t. So for 64-bits architecture where sizeof of size_t is larger than socklen_t, both sendmmsg and recvmmsg need to adjust the mmsghdr::msg_hdr internal fields before issuing the syscall itself. This patch fixes it by operating on the padding if it the case. For recvmmsg, the most straightfoward case, only zero padding the fields is suffice. However, for sendmmsg, where adjusting the buffer is out of the contract (since it may point to a read-only data), the function is rewritten to use sendmsg instead (which from previous patch allocates a temporary msghdr to operate on). Also for 64-bit ports that requires it, a new recvmmsg and sendmmsg compat version is created (which uses size_t for both cmsghdr::cmsg_len and internal Tested on x86_64, i686, aarch64, armhf, and powerpc64le. * sysdeps/unix/sysv/linux/Makefile [$(subdir) = socket] (sysdep_routines): Add oldrecvmmsg and oldsendmmsg. * sysdeps/unix/sysv/linux/aarch64/libc.abilist: Add recvmmsg and sendmmsg. * sysdeps/unix/sysv/linux/alpha/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/ia64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist: Likewise. * sysdeps/sysv/linux/powerpc/powerpc64/libc-le.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/x86_64/64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/oldrecvmmsg.c: New file. * sysdeps/unix/sysv/linux/oldsendmmsg.c: Likewise. * sysdeps/unix/sysv/linux/recvmmsg.c (__recvmmsg): Adjust msghdr iovlen and controllen fields to adjust to POSIX specification. * sysdeps/unix/sysv/linux/sendmmsg.c (__sendmmsg): Likewise.
2016-03-17 09:52:17 -03:00
static int have_recvmmsg;
if (__glibc_likely (have_recvmmsg >= 0))
2010-05-21 12:11:28 -07:00
{
network: recvmmsg and sendmmsg standard compliance (BZ#16919) POSIX specifies that both msghdr::msg_iovlen and msghdr::msg_controllen to be of size int and socklen_t respectively, however Linux implements it as a size_t. So for 64-bits architecture where sizeof of size_t is larger than socklen_t, both sendmmsg and recvmmsg need to adjust the mmsghdr::msg_hdr internal fields before issuing the syscall itself. This patch fixes it by operating on the padding if it the case. For recvmmsg, the most straightfoward case, only zero padding the fields is suffice. However, for sendmmsg, where adjusting the buffer is out of the contract (since it may point to a read-only data), the function is rewritten to use sendmsg instead (which from previous patch allocates a temporary msghdr to operate on). Also for 64-bit ports that requires it, a new recvmmsg and sendmmsg compat version is created (which uses size_t for both cmsghdr::cmsg_len and internal Tested on x86_64, i686, aarch64, armhf, and powerpc64le. * sysdeps/unix/sysv/linux/Makefile [$(subdir) = socket] (sysdep_routines): Add oldrecvmmsg and oldsendmmsg. * sysdeps/unix/sysv/linux/aarch64/libc.abilist: Add recvmmsg and sendmmsg. * sysdeps/unix/sysv/linux/alpha/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/ia64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist: Likewise. * sysdeps/sysv/linux/powerpc/powerpc64/libc-le.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/x86_64/64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/oldrecvmmsg.c: New file. * sysdeps/unix/sysv/linux/oldsendmmsg.c: Likewise. * sysdeps/unix/sysv/linux/recvmmsg.c (__recvmmsg): Adjust msghdr iovlen and controllen fields to adjust to POSIX specification. * sysdeps/unix/sysv/linux/sendmmsg.c (__sendmmsg): Likewise.
2016-03-17 09:52:17 -03:00
adjust_mmsghdr (vmessages, vlen);
int ret = SOCKETCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags,
tmo);
2010-05-21 12:11:28 -07:00
/* 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_recvmmsg == 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 = SOCKETCALL_CANCEL (invalid, -1);
2010-05-21 12:11:28 -07:00
if (errno == EINVAL)
{
have_recvmmsg = -1;
__set_errno (ENOSYS);
}
else
{
have_recvmmsg = 1;
__set_errno (EINVAL);
}
return -1;
}
return ret;
}
__set_errno (ENOSYS);
return -1;
# endif /* __ASSUME_RECVMMSG_SOCKETCALL */
2010-05-21 12:11:28 -07:00
#else
network: recvmmsg and sendmmsg standard compliance (BZ#16919) POSIX specifies that both msghdr::msg_iovlen and msghdr::msg_controllen to be of size int and socklen_t respectively, however Linux implements it as a size_t. So for 64-bits architecture where sizeof of size_t is larger than socklen_t, both sendmmsg and recvmmsg need to adjust the mmsghdr::msg_hdr internal fields before issuing the syscall itself. This patch fixes it by operating on the padding if it the case. For recvmmsg, the most straightfoward case, only zero padding the fields is suffice. However, for sendmmsg, where adjusting the buffer is out of the contract (since it may point to a read-only data), the function is rewritten to use sendmsg instead (which from previous patch allocates a temporary msghdr to operate on). Also for 64-bit ports that requires it, a new recvmmsg and sendmmsg compat version is created (which uses size_t for both cmsghdr::cmsg_len and internal Tested on x86_64, i686, aarch64, armhf, and powerpc64le. * sysdeps/unix/sysv/linux/Makefile [$(subdir) = socket] (sysdep_routines): Add oldrecvmmsg and oldsendmmsg. * sysdeps/unix/sysv/linux/aarch64/libc.abilist: Add recvmmsg and sendmmsg. * sysdeps/unix/sysv/linux/alpha/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/ia64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist: Likewise. * sysdeps/sysv/linux/powerpc/powerpc64/libc-le.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/x86_64/64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/oldrecvmmsg.c: New file. * sysdeps/unix/sysv/linux/oldsendmmsg.c: Likewise. * sysdeps/unix/sysv/linux/recvmmsg.c (__recvmmsg): Adjust msghdr iovlen and controllen fields to adjust to POSIX specification. * sysdeps/unix/sysv/linux/sendmmsg.c (__sendmmsg): Likewise.
2016-03-17 09:52:17 -03:00
# define STUB 1
__set_errno (ENOSYS);
return -1;
#endif
}
#ifdef STUB
stub_warning (recvmmsg)
#endif
#if __WORDSIZE == 64
versioned_symbol (libc, __recvmmsg, recvmmsg, GLIBC_2_24);
#else
weak_alias (__recvmmsg, recvmmsg)
2010-05-21 12:11:28 -07:00
#endif