diff options
author | Joseph Myers <joseph@codesourcery.com> | 2017-05-09 20:01:52 +0000 |
---|---|---|
committer | Joseph Myers <joseph@codesourcery.com> | 2017-05-09 20:01:52 +0000 |
commit | 0cb5da5c09e2b2eb47348d110282b92ec27eedf5 (patch) | |
tree | 52372d318cc72f03ad9690fbb78dafa2f3e7572e | |
parent | 9a45f54310573c190fa270e1f80d8307750305e9 (diff) | |
download | glibc-0cb5da5c09e2b2eb47348d110282b92ec27eedf5.zip glibc-0cb5da5c09e2b2eb47348d110282b92ec27eedf5.tar.gz glibc-0cb5da5c09e2b2eb47348d110282b92ec27eedf5.tar.bz2 |
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.
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/kernel-features.h | 9 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sendmmsg.c | 71 |
3 files changed, 20 insertions, 68 deletions
@@ -1,6 +1,14 @@ 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 (__ASSUME_RECVMMSG_SYSCALL): Define unconditionally. (__ASSUME_RECVMMSG_SOCKETCALL): Remove macro. (__ASSUME_RECVMMSG): Likewise. diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h index a5c2263..7728565 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 2dd0eba..c559623 100644 --- a/sysdeps/unix/sysv/linux/sendmmsg.c +++ b/sysdeps/unix/sysv/linux/sendmmsg.c @@ -21,73 +21,22 @@ #include <sysdep-cancel.h> #include <sys/syscall.h> +#include <socketcall.h> #include <kernel-features.h> -/* 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 <socketcall.h> -# 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 <socket/sendmmsg.c> -#endif |