aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Richardson <Alexander.Richardson@cl.cam.ac.uk>2021-03-19 10:02:41 +0000
committerAlexander Richardson <alexander.richardson@cl.cam.ac.uk>2021-09-10 11:35:54 +0000
commit382f368a2795cacbe0f3690f9bf5be749f9f0f5e (patch)
tree919cca635c9d1372f99c312d3c5f4cabe2e80f05
parenttest-helpers: use sysctl() to count open fds on FreeBSD (diff)
downloadwayland-382f368a2795cacbe0f3690f9bf5be749f9f0f5e.tar
wayland-382f368a2795cacbe0f3690f9bf5be749f9f0f5e.tar.gz
wayland-382f368a2795cacbe0f3690f9bf5be749f9f0f5e.tar.bz2
wayland-382f368a2795cacbe0f3690f9bf5be749f9f0f5e.tar.lz
wayland-382f368a2795cacbe0f3690f9bf5be749f9f0f5e.tar.xz
wayland-382f368a2795cacbe0f3690f9bf5be749f9f0f5e.tar.zst
wayland-382f368a2795cacbe0f3690f9bf5be749f9f0f5e.zip
Detect FreeBSD versions with broken MSG_CMSG_CLOEXEC
If we are compiling against a version of FreeBSD where MSG_CMSG_CLOEXEC does not work, use the fallback directly. This was only fixed recently (in https://cgit.freebsd.org/src/commit/?id=6ceacebdf52211). Signed-off-by: Alex Richardson <Alexander.Richardson@cl.cam.ac.uk>
-rw-r--r--meson.build16
-rw-r--r--src/wayland-os.c11
-rw-r--r--tests/os-wrappers-test.c7
3 files changed, 33 insertions, 1 deletions
diff --git a/meson.build b/meson.build
index a116d9d..5cd978f 100644
--- a/meson.build
+++ b/meson.build
@@ -43,6 +43,22 @@ foreach f: have_funcs
config_h.set('HAVE_' + f.underscorify().to_upper(), cc.has_function(f))
endforeach
config_h.set10('HAVE_XUCRED_CR_PID', cc.has_member('struct xucred', 'cr_pid', prefix : '#include <sys/ucred.h>'))
+have_broken_msg_cmsg_cloexec = false
+if host_machine.system() == 'freebsd'
+ have_broken_msg_cmsg_cloexec = not cc.compiles('''
+#include <sys/param.h> /* To get __FreeBSD_version. */
+#if __FreeBSD_version < 1300502 || \
+ (__FreeBSD_version >= 1400000 && __FreeBSD_version < 1400006)
+/*
+ * FreeBSD had a broken implementation of MSG_CMSG_CLOEXEC between 2015 and
+ * 2021. Check if we are compiling against a version that includes the fix
+ * (https://cgit.freebsd.org/src/commit/?id=6ceacebdf52211).
+ */
+#error "Broken MSG_CMSG_CLOEXEC"
+#endif
+''', name : 'MSG_CMSG_CLOEXEC works correctly')
+endif
+config_h.set10('HAVE_BROKEN_MSG_CMSG_CLOEXEC', have_broken_msg_cmsg_cloexec)
if get_option('libraries')
if host_machine.system() == 'freebsd'
diff --git a/src/wayland-os.c b/src/wayland-os.c
index 44d4e72..27c6035 100644
--- a/src/wayland-os.c
+++ b/src/wayland-os.c
@@ -168,6 +168,15 @@ recvmsg_cloexec_fallback(int sockfd, struct msghdr *msg, int flags)
ssize_t
wl_os_recvmsg_cloexec(int sockfd, struct msghdr *msg, int flags)
{
+#if HAVE_BROKEN_MSG_CMSG_CLOEXEC
+ /*
+ * FreeBSD had a broken implementation of MSG_CMSG_CLOEXEC between 2015
+ * and 2021, so we have to use the non-MSG_CMSG_CLOEXEC fallback
+ * directly when compiling against a version that does not include the
+ * fix (https://cgit.freebsd.org/src/commit/?id=6ceacebdf52211).
+ */
+#pragma message("Using fallback directly since MSG_CMSG_CLOEXEC is broken.")
+#else
ssize_t len;
len = recvmsg(sockfd, msg, flags | MSG_CMSG_CLOEXEC);
@@ -175,7 +184,7 @@ wl_os_recvmsg_cloexec(int sockfd, struct msghdr *msg, int flags)
return len;
if (errno != EINVAL)
return -1;
-
+#endif
return recvmsg_cloexec_fallback(sockfd, msg, flags);
}
diff --git a/tests/os-wrappers-test.c b/tests/os-wrappers-test.c
index 51eaa29..aadb93b 100644
--- a/tests/os-wrappers-test.c
+++ b/tests/os-wrappers-test.c
@@ -23,6 +23,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
+#include "../config.h"
#define _GNU_SOURCE
@@ -341,7 +342,13 @@ do_os_wrappers_recvmsg_cloexec(int n)
struct marshal_data data;
data.nr_fds_begin = count_open_fds();
+#if HAVE_BROKEN_MSG_CMSG_CLOEXEC
+ /* We call the fallback directly on FreeBSD versions with a broken
+ * MSG_CMSG_CLOEXEC, so we don't call the local recvmsg() wrapper. */
+ data.wrapped_calls = 0;
+#else
data.wrapped_calls = n;
+#endif
setup_marshal_data(&data);
data.nr_fds_conn = count_open_fds();