From 9aa0600b81e0229b3dbf920103b6c60a1dcc6f11 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Thu, 1 Jan 2015 14:38:53 +0100 Subject: [PATCH] udp: implement recvmmsg emulation for older linux kernels --- src/udp.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/src/udp.c b/src/udp.c index 5e97be4b..8fcf0371 100644 --- a/src/udp.c +++ b/src/udp.c @@ -497,7 +497,6 @@ int recvmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, #endif #endif - #ifndef CONFIG_RECVMMSG struct mmsghdr { @@ -505,9 +504,11 @@ struct mmsghdr { unsigned int msg_len; }; -static int -recvmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, - unsigned int flags, struct timespec *timeout) +#endif + +static inline int +recvmmsg_i(int sockfd, struct mmsghdr *msgvec, + unsigned int vlen, unsigned int flags) { ssize_t r; unsigned int i; @@ -522,8 +523,16 @@ recvmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, return i; } -#endif +#ifndef CONFIG_RECVMMSG +int +recvmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, + unsigned int flags, struct timespec *timeout) +{ + return recvmmsg_i(sockfd, msgvec, vlen, flags); +} + +#endif void udp_multirecv_init( udp_multirecv_t *um, int packets, int psize ) @@ -563,6 +572,7 @@ int udp_multirecv_read( udp_multirecv_t *um, int fd, int packets, struct iovec **iovec ) { + static char use_emul = 0; int n, i; if (um == NULL || iovec == NULL) { errno = EINVAL; @@ -570,7 +580,16 @@ udp_multirecv_read( udp_multirecv_t *um, int fd, int packets, } if (packets > um->um_packets) packets = um->um_packets; - n = recvmmsg(fd, (struct mmsghdr *)um->um_msg, packets, MSG_DONTWAIT, NULL); + if (!use_emul) { + n = recvmmsg(fd, (struct mmsghdr *)um->um_msg, packets, MSG_DONTWAIT, NULL); + } else { + n = -1; + errno = ENOSYS; + } + if (n < 0 && errno == ENOSYS) { + use_emul = 1; + n = recvmmsg_i(fd, (struct mmsghdr *)um->um_msg, packets, MSG_DONTWAIT); + } if (n > 0) { for (i = 0; i < n; i++) um->um_riovec[i].iov_len = ((struct mmsghdr *)um->um_msg)[i].msg_len;