1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-29 11:41:21 +03:00

Simplify sendmmsg code.

Now we can assume a kernel with sendmmsg support, this patch
simplifies the implementation to be similar to that for accept4:
either using socketcall or the syscall according to whether the
syscall is known to be available, without further fallback
implementations.  The __ASSUME_SENDMMSG macro is kept (now defined
unconditionally), since it's used in resolv/res_send.c.

Tested for x86_64 and x86.

	* sysdeps/unix/sysv/linux/kernel-features.h
	(__ASSUME_SENDMMSG_SYSCALL): Define unconditionally.
	(__ASSUME_SENDMMSG): Likewise.
	(__ASSUME_SENDMMSG_SOCKETCALL): Remove macro.
	* sysdeps/unix/sysv/linux/sendmmsg.c (__sendmmsg): Define using
	sendmmsg syscall if that can be assumed to be present, socketcall
	otherwise, with no fallback for runtime failure.
This commit is contained in:
Joseph Myers
2017-05-09 20:01:52 +00:00
parent 9a45f54310
commit 0cb5da5c09
3 changed files with 20 additions and 68 deletions

View File

@ -1,5 +1,13 @@
2017-05-09 Joseph Myers <joseph@codesourcery.com> 2017-05-09 Joseph Myers <joseph@codesourcery.com>
* sysdeps/unix/sysv/linux/kernel-features.h
(__ASSUME_SENDMMSG_SYSCALL): Define unconditionally.
(__ASSUME_SENDMMSG): Likewise.
(__ASSUME_SENDMMSG_SOCKETCALL): Remove macro.
* sysdeps/unix/sysv/linux/sendmmsg.c (__sendmmsg): Define using
sendmmsg syscall if that can be assumed to be present, socketcall
otherwise, with no fallback for runtime failure.
* sysdeps/unix/sysv/linux/kernel-features.h * sysdeps/unix/sysv/linux/kernel-features.h
(__ASSUME_RECVMMSG_SYSCALL): Define unconditionally. (__ASSUME_RECVMMSG_SYSCALL): Define unconditionally.
(__ASSUME_RECVMMSG_SOCKETCALL): Remove macro. (__ASSUME_RECVMMSG_SOCKETCALL): Remove macro.

View File

@ -99,13 +99,8 @@
/* Support for sendmmsg functionality was added in 3.0. The macros /* Support for sendmmsg functionality was added in 3.0. The macros
defined correspond to those for accept4 and recvmmsg. */ defined correspond to those for accept4 and recvmmsg. */
#if __LINUX_KERNEL_VERSION >= 0x030000 #define __ASSUME_SENDMMSG_SYSCALL 1
# ifdef __ASSUME_SOCKETCALL #define __ASSUME_SENDMMSG 1
# define __ASSUME_SENDMMSG_SOCKETCALL 1
# endif
# define __ASSUME_SENDMMSG_SYSCALL 1
# define __ASSUME_SENDMMSG 1
#endif
/* On most architectures, most socket syscalls are supported for all /* On most architectures, most socket syscalls are supported for all
supported kernel versions, but on some socketcall architectures supported kernel versions, but on some socketcall architectures

View File

@ -21,73 +21,22 @@
#include <sysdep-cancel.h> #include <sysdep-cancel.h>
#include <sys/syscall.h> #include <sys/syscall.h>
#include <socketcall.h>
#include <kernel-features.h> #include <kernel-features.h>
/* Do not use the sendmmsg syscall on socketcall architectures unless int
__sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
{
/* Do not use the sendmmsg syscall on socketcall architectures unless
it was added at the same time as the socketcall support or can be it was added at the same time as the socketcall support or can be
assumed to be present. */ assumed to be present. */
#if defined __ASSUME_SOCKETCALL \ #if defined __ASSUME_SOCKETCALL \
&& !defined __ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL \ && !defined __ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL \
&& !defined __ASSUME_SENDMMSG_SYSCALL && !defined __ASSUME_SENDMMSG_SYSCALL
# undef __NR_sendmmsg
#endif
#ifdef __NR_sendmmsg
int
__sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
{
return SYSCALL_CANCEL (sendmmsg, fd, vmessages, vlen, flags);
}
libc_hidden_def (__sendmmsg)
weak_alias (__sendmmsg, sendmmsg)
#elif defined __NR_socketcall
# include <socketcall.h>
# ifdef __ASSUME_SENDMMSG_SOCKETCALL
int
__sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
{
return SOCKETCALL_CANCEL (sendmmsg, fd, vmessages, vlen, flags); return SOCKETCALL_CANCEL (sendmmsg, fd, vmessages, vlen, flags);
#else
return SYSCALL_CANCEL (sendmmsg, fd, vmessages, vlen, flags);
#endif
} }
# else
static int have_sendmmsg;
int
__sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
{
if (__glibc_likely (have_sendmmsg >= 0))
{
int ret = SOCKETCALL_CANCEL (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 = SOCKETCALL_CANCEL (invalid, -1);
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;
}
# endif /* __ASSUME_SENDMMSG_SOCKETCALL */
libc_hidden_def (__sendmmsg) libc_hidden_def (__sendmmsg)
weak_alias (__sendmmsg, sendmmsg) weak_alias (__sendmmsg, sendmmsg)
#else
# include <socket/sendmmsg.c>
#endif