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>
This commit is contained in:
Alex Richardson 2021-03-19 10:02:41 +00:00 committed by Alexander Richardson
parent 42bf011f65
commit 382f368a27
3 changed files with 33 additions and 1 deletions

View file

@ -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'

View file

@ -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);
}

View file

@ -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();