os: Use fallback implementations when *_CLOEXEC are unavailable at build time

On platforms without F_DUPFD_CLOEXEC, MSG_CMSG_CLOEXEC, or SOCK_CLOEXEC, we
should skip past their usage and just use the fcntl() fallback.

Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
This commit is contained in:
Jeremy Huddleston Sequoia 2023-01-27 14:52:05 -08:00
parent aa7c02ff80
commit b5cb23d698
2 changed files with 10 additions and 3 deletions

View file

@ -69,11 +69,13 @@ wl_os_socket_cloexec(int domain, int type, int protocol)
{ {
int fd; int fd;
#ifdef SOCK_CLOEXEC
fd = socket(domain, type | SOCK_CLOEXEC, protocol); fd = socket(domain, type | SOCK_CLOEXEC, protocol);
if (fd >= 0) if (fd >= 0)
return fd; return fd;
if (errno != EINVAL) if (errno != EINVAL)
return -1; return -1;
#endif
fd = socket(domain, type, protocol); fd = socket(domain, type, protocol);
return set_cloexec_or_close(fd); return set_cloexec_or_close(fd);
@ -140,11 +142,13 @@ wl_os_dupfd_cloexec(int fd, int minfd)
{ {
int newfd; int newfd;
#ifdef F_DUPFD_CLOEXEC
newfd = fcntl(fd, F_DUPFD_CLOEXEC, minfd); newfd = fcntl(fd, F_DUPFD_CLOEXEC, minfd);
if (newfd >= 0) if (newfd >= 0)
return newfd; return newfd;
if (errno != EINVAL) if (errno != EINVAL)
return -1; return -1;
#endif
newfd = fcntl(fd, F_DUPFD, minfd); newfd = fcntl(fd, F_DUPFD, minfd);
return set_cloexec_or_close(newfd); return set_cloexec_or_close(newfd);
@ -192,7 +196,7 @@ wl_os_recvmsg_cloexec(int sockfd, struct msghdr *msg, int flags)
* fix (https://cgit.freebsd.org/src/commit/?id=6ceacebdf52211). * fix (https://cgit.freebsd.org/src/commit/?id=6ceacebdf52211).
*/ */
#pragma message("Using fallback directly since MSG_CMSG_CLOEXEC is broken.") #pragma message("Using fallback directly since MSG_CMSG_CLOEXEC is broken.")
#else #elif defined(MSG_CMSG_CLOEXEC)
ssize_t len; ssize_t len;
len = recvmsg(sockfd, msg, flags | MSG_CMSG_CLOEXEC); len = recvmsg(sockfd, msg, flags | MSG_CMSG_CLOEXEC);

View file

@ -141,10 +141,12 @@ recvmsg(int sockfd, struct msghdr *msg, int flags)
{ {
wrapped_calls_recvmsg++; wrapped_calls_recvmsg++;
#ifdef MSG_CMSG_CLOEXEC
if (fall_back && (flags & MSG_CMSG_CLOEXEC)) { if (fall_back && (flags & MSG_CMSG_CLOEXEC)) {
errno = EINVAL; errno = EINVAL;
return -1; return -1;
} }
#endif
return real_recvmsg(sockfd, msg, flags); return real_recvmsg(sockfd, msg, flags);
} }
@ -342,9 +344,10 @@ do_os_wrappers_recvmsg_cloexec(int n)
struct marshal_data data; struct marshal_data data;
data.nr_fds_begin = count_open_fds(); data.nr_fds_begin = count_open_fds();
#if HAVE_BROKEN_MSG_CMSG_CLOEXEC #if HAVE_BROKEN_MSG_CMSG_CLOEXEC || !defined(MSG_CMSG_CLOEXEC)
/* We call the fallback directly on FreeBSD versions with a broken /* We call the fallback directly on FreeBSD versions with a broken
* MSG_CMSG_CLOEXEC, so we don't call the local recvmsg() wrapper. */ * MSG_CMSG_CLOEXEC or platforms without MSG_CMSG_CLOEXEC, so we
* don't call the local recvmsg() wrapper. */
data.wrapped_calls = 0; data.wrapped_calls = 0;
#else #else
data.wrapped_calls = n; data.wrapped_calls = n;