mirror of
https://github.com/openvswitch/ovs
synced 2025-09-02 15:25:22 +00:00
socket-util: Emulate recvmmsg() and sendmmsg() on Linux only.
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> Acked-by: Ilya Maximets <i.maximets@ovn.org> Signed-off-by: Ben Pfaff <blp@ovn.org>
This commit is contained in:
@@ -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;
|
||||
|
Reference in New Issue
Block a user