[ovs-dev] [PATCH] socket-util: Emulate recvmmsg() and sendmmsg() on Linux only.
Ben Pfaff
blp at ovn.org
Mon Jan 13 18:03:04 UTC 2020
These functions failed to build on OS X because MSG_WAITFORONE is not
defined there. There are pitfalls for trying to define our own MSG_*
constants, since it's hard to pick a constant that is not used by the
system already. Because OVS only uses recvmmsg() and sendmmsg() on
Linux, it seems easiest to just emulate them there.
Reported-by: Ilya Maximets <i.maximets at ovn.org>
Signed-off-by: Ben Pfaff <blp at ovn.org>
---
lib/socket-util.c | 8 +++-----
lib/socket-util.h | 20 ++++++++++----------
2 files changed, 13 insertions(+), 15 deletions(-)
diff --git a/lib/socket-util.c b/lib/socket-util.c
index f6f6f3b0a33f..4f1ffecf5d6f 100644
--- a/lib/socket-util.c
+++ b/lib/socket-util.c
@@ -1241,7 +1241,7 @@ sock_strerror(int error)
#endif
}
-#ifndef _WIN32 /* Avoid using sendmsg on Windows entirely. */
+#ifdef __linux__
static int
emulate_sendmmsg(int fd, struct mmsghdr *msgs, unsigned int n,
unsigned int flags)
@@ -1282,9 +1282,7 @@ wrap_sendmmsg(int fd, struct mmsghdr *msgs, unsigned int n, unsigned int flags)
return emulate_sendmmsg(fd, msgs, n, flags);
}
#endif
-#endif
-
-#ifndef _WIN32 /* Avoid using recvmsg on Windows entirely. */
+
static int
emulate_recvmmsg(int fd, struct mmsghdr *msgs, unsigned int n,
int flags, struct timespec *timeout OVS_UNUSED)
@@ -1338,4 +1336,4 @@ wrap_recvmmsg(int fd, struct mmsghdr *msgs, unsigned int n,
return emulate_recvmmsg(fd, msgs, n, flags, timeout);
}
#endif
-#endif
+#endif /* __linux__ */
diff --git a/lib/socket-util.h b/lib/socket-util.h
index 71bd68926aaa..9ccb7d4cc41d 100644
--- a/lib/socket-util.h
+++ b/lib/socket-util.h
@@ -104,27 +104,26 @@ int make_unix_socket(int style, bool nonblock,
const char *bind_path, const char *connect_path);
int get_unix_name_len(const struct sockaddr_un *sun, socklen_t sun_len);
-/* Universal sendmmsg and recvmmsg support.
+/* Universal sendmmsg and recvmmsg support on Linux.
*
- * Some platforms, such as new enough Linux and FreeBSD, support sendmmsg and
- * recvmmsg, but other platforms (or older ones) do not. We add the following
- * infrastructure to allow all code to use sendmmsg and recvmmsg, regardless of
- * platform support:
+ * New enough Linux supports sendmmsg and recvmmsg, but older versions do not.
+ * We add the following infrastructure to allow all code on Linux to use
+ * sendmmsg and recvmmsg, regardless of platform support:
*
* - For platforms that lack these functions entirely, we emulate them.
*
- * - Some platforms have sendmmsg() and recvmmsg() in the C library but not in
- * the kernel. For example, this is true if a Linux system has a newer glibc
- * with an old kernel. To compensate, even if these functions appear to be
- * available, we still wrap them with handlers that uses our emulation if the
- * underlying function returns ENOSYS.
+ * - With newer glibc but an old kernel, sendmmsg() and recvmmsg() fail with
+ * ENOSYS. To compensate, even if these functions appear to be available, we
+ * wrap them with handlers that use our emulation in this case.
*/
+#ifdef __linux__
#ifndef HAVE_STRUCT_MMSGHDR_MSG_LEN
struct mmsghdr {
struct msghdr msg_hdr;
unsigned int msg_len;
};
#endif
+
#ifndef HAVE_SENDMMSG
int sendmmsg(int, struct mmsghdr *, unsigned int, unsigned int);
int recvmmsg(int, struct mmsghdr *, unsigned int, int, struct timespec *);
@@ -134,6 +133,7 @@ int wrap_sendmmsg(int, struct mmsghdr *, unsigned int, unsigned int);
#define recvmmsg wrap_recvmmsg
int wrap_recvmmsg(int, struct mmsghdr *, unsigned int, int, struct timespec *);
#endif
+#endif /* __linux__ */
/* Helpers for calling ioctl() on an AF_INET socket. */
struct ifreq;
--
2.23.0
More information about the dev
mailing list