From 0cb5da5c09e2b2eb47348d110282b92ec27eedf5 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Tue, 9 May 2017 20:01:52 +0000 Subject: 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. --- ChangeLog | 8 ++++ sysdeps/unix/sysv/linux/kernel-features.h | 9 +--- sysdeps/unix/sysv/linux/sendmmsg.c | 71 +++++-------------------------- 3 files changed, 20 insertions(+), 68 deletions(-) diff --git a/ChangeLog b/ChangeLog index 554b8082e4..5387b1949b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ 2017-05-09 Joseph Myers + * 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 (__ASSUME_RECVMMSG_SYSCALL): Define unconditionally. (__ASSUME_RECVMMSG_SOCKETCALL): Remove macro. diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h index a5c226311c..77285656cd 100644 --- a/sysdeps/unix/sysv/linux/kernel-features.h +++ b/sysdeps/unix/sysv/linux/kernel-features.h @@ -99,13 +99,8 @@ /* Support for sendmmsg functionality was added in 3.0. The macros defined correspond to those for accept4 and recvmmsg. */ -#if __LINUX_KERNEL_VERSION >= 0x030000 -# ifdef __ASSUME_SOCKETCALL -# define __ASSUME_SENDMMSG_SOCKETCALL 1 -# endif -# define __ASSUME_SENDMMSG_SYSCALL 1 -# define __ASSUME_SENDMMSG 1 -#endif +#define __ASSUME_SENDMMSG_SYSCALL 1 +#define __ASSUME_SENDMMSG 1 /* On most architectures, most socket syscalls are supported for all supported kernel versions, but on some socketcall architectures diff --git a/sysdeps/unix/sysv/linux/sendmmsg.c b/sysdeps/unix/sysv/linux/sendmmsg.c index 2dd0eba746..c559623c12 100644 --- a/sysdeps/unix/sysv/linux/sendmmsg.c +++ b/sysdeps/unix/sysv/linux/sendmmsg.c @@ -21,73 +21,22 @@ #include #include +#include #include -/* Do not use the sendmmsg 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_SENDMMSG_SYSCALL_WITH_SOCKETCALL \ - && !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 -# ifdef __ASSUME_SENDMMSG_SOCKETCALL 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 + assumed to be present. */ +#if defined __ASSUME_SOCKETCALL \ + && !defined __ASSUME_SENDMMSG_SYSCALL_WITH_SOCKETCALL \ + && !defined __ASSUME_SENDMMSG_SYSCALL 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) weak_alias (__sendmmsg, sendmmsg) -#else -# include -#endif -- cgit 1.4.1