diff mbox series

[ovs-dev] socket-util: Emulate recvmmsg() and sendmmsg() on Linux only.

Message ID 20200113180304.4105719-1-blp@ovn.org
State Accepted
Headers show
Series [ovs-dev] socket-util: Emulate recvmmsg() and sendmmsg() on Linux only. | expand

Commit Message

Ben Pfaff Jan. 13, 2020, 6:03 p.m. UTC
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@ovn.org>
Signed-off-by: Ben Pfaff <blp@ovn.org>
---
 lib/socket-util.c |  8 +++-----
 lib/socket-util.h | 20 ++++++++++----------
 2 files changed, 13 insertions(+), 15 deletions(-)

Comments

Ilya Maximets Jan. 14, 2020, 6:09 p.m. UTC | #1
On 13.01.2020 19:03, Ben Pfaff wrote:
> 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.

Thanks!  This looks good to me and passes Travis build.

Acked-by: Ilya Maximets <i.maximets@ovn.org>
Ben Pfaff Jan. 14, 2020, 6:37 p.m. UTC | #2
On Tue, Jan 14, 2020 at 07:09:36PM +0100, Ilya Maximets wrote:
> On 13.01.2020 19:03, Ben Pfaff wrote:
> > 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.
> 
> Thanks!  This looks good to me and passes Travis build.
> 
> Acked-by: Ilya Maximets <i.maximets@ovn.org>

Thanks!  Applied to master.
diff mbox series

Patch

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;