mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2026-02-05 04:06:20 -05:00
Merge branch 'darwin-portability' into 'main'
Misc portability improvements to help bring wayland to darwin See merge request wayland/wayland!290
This commit is contained in:
commit
29f820549f
14 changed files with 138 additions and 28 deletions
|
|
@ -14,7 +14,12 @@ if ! test -n "$NM"; then
|
|||
exit 99
|
||||
fi
|
||||
|
||||
AVAIL_FUNCS="$($NM -D --format=bsd --defined-only $LIB | awk '{print $3}')"
|
||||
# Assuming any system with SystemVersion.plist is a darwin-derivative and prefixes C symbols with _
|
||||
if [ -f "/System/Library/CoreServices/SystemVersion.plist" ] ; then
|
||||
AVAIL_FUNCS="$($NM $LIB | awk '{print $3}' | sed 's:^_::')"
|
||||
else
|
||||
AVAIL_FUNCS="$($NM -D --format=bsd --defined-only $LIB | awk '{print $3}')"
|
||||
fi
|
||||
|
||||
# Official ABI, taken from the header.
|
||||
REQ_FUNCS="wl_egl_window_resize
|
||||
|
|
|
|||
32
meson.build
32
meson.build
|
|
@ -19,6 +19,10 @@ cc_args = []
|
|||
if host_machine.system() != 'freebsd'
|
||||
cc_args += ['-D_POSIX_C_SOURCE=200809L']
|
||||
endif
|
||||
if host_machine.system() == 'darwin'
|
||||
# For CMSG_LEN(), which is an RFC 2292 addition and not part of POSIX.1-2008
|
||||
cc_args += ['-D_DARWIN_C_SOURCE']
|
||||
endif
|
||||
add_project_arguments(cc_args, language: 'c')
|
||||
|
||||
compiler_flags = [
|
||||
|
|
@ -40,6 +44,7 @@ endforeach
|
|||
|
||||
have_funcs = [
|
||||
'accept4',
|
||||
'getpeereid',
|
||||
'mkostemp',
|
||||
'posix_fallocate',
|
||||
'prctl',
|
||||
|
|
@ -69,15 +74,20 @@ endif
|
|||
config_h.set10('HAVE_BROKEN_MSG_CMSG_CLOEXEC', have_broken_msg_cmsg_cloexec)
|
||||
|
||||
if get_option('libraries')
|
||||
if host_machine.system() == 'freebsd'
|
||||
# When building for FreeBSD, epoll(7) is provided by a userspace
|
||||
# wrapper around kqueue(2).
|
||||
if host_machine.system() in ['darwin', 'freebsd']
|
||||
# When building for darwin or FreeBSD, epoll(7) is provided by a
|
||||
# userspace wrapper around kqueue(2).
|
||||
epoll_dep = dependency('epoll-shim')
|
||||
else
|
||||
# Otherwise, assume that epoll(7) is supported natively.
|
||||
epoll_dep = []
|
||||
endif
|
||||
ffi_dep = dependency('libffi')
|
||||
|
||||
if host_machine.system() == 'darwin'
|
||||
ffi_dep = cc.find_library('ffi')
|
||||
else
|
||||
ffi_dep = dependency('libffi')
|
||||
endif
|
||||
|
||||
decls = [
|
||||
{ 'header': 'sys/signalfd.h', 'symbol': 'SFD_CLOEXEC' },
|
||||
|
|
@ -91,11 +101,15 @@ if get_option('libraries')
|
|||
endif
|
||||
endforeach
|
||||
|
||||
rt_dep = []
|
||||
if not cc.has_function('clock_gettime', prefix: '#include <time.h>')
|
||||
rt_dep = cc.find_library('rt')
|
||||
if not cc.has_function('clock_gettime', prefix: '#include <time.h>', dependencies: rt_dep, args: cc_args)
|
||||
error('clock_gettime not found')
|
||||
if host_machine.system() == 'darwin'
|
||||
rt_dep = []
|
||||
else
|
||||
rt_dep = []
|
||||
if cc.has_function('clock_gettime', prefix: '#include <time.h>')
|
||||
rt_dep = cc.find_library('rt')
|
||||
if not cc.has_function('clock_gettime', prefix: '#include <time.h>', dependencies: rt_dep, args: cc_args)
|
||||
error('clock_gettime not found')
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -38,7 +38,11 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <time.h>
|
||||
#ifdef __APPLE__
|
||||
#include <ffi/ffi.h>
|
||||
#else
|
||||
#include <ffi.h>
|
||||
#endif
|
||||
|
||||
#include "wayland-util.h"
|
||||
#include "wayland-private.h"
|
||||
|
|
|
|||
|
|
@ -29,7 +29,12 @@ wayland_util_dep = declare_dependency(
|
|||
if get_option('scanner')
|
||||
# wayland-scanner
|
||||
|
||||
scanner_deps = [ dependency('expat') ]
|
||||
if host_machine.system() == 'darwin'
|
||||
scanner_deps = [ cc.find_library('expat') ]
|
||||
else
|
||||
scanner_deps = [ dependency('expat') ]
|
||||
endif
|
||||
|
||||
scanner_args = [ '-include', 'config.h' ]
|
||||
|
||||
if get_option('dtd_validation')
|
||||
|
|
|
|||
|
|
@ -69,16 +69,38 @@ wl_os_socket_cloexec(int domain, int type, int protocol)
|
|||
{
|
||||
int fd;
|
||||
|
||||
#ifdef SOCK_CLOEXEC
|
||||
fd = socket(domain, type | SOCK_CLOEXEC, protocol);
|
||||
if (fd >= 0)
|
||||
return fd;
|
||||
if (errno != EINVAL)
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
fd = socket(domain, type, protocol);
|
||||
return set_cloexec_or_close(fd);
|
||||
}
|
||||
|
||||
int
|
||||
wl_os_socketpair_cloexec(int domain, int type, int protocol, int sv[2])
|
||||
{
|
||||
int retval;
|
||||
|
||||
#ifdef SOCK_CLOEXEC
|
||||
retval = socketpair(domain, type | SOCK_CLOEXEC, protocol, sv);
|
||||
if (retval >= 0)
|
||||
return retval;
|
||||
if (errno != EINVAL)
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
retval = socketpair(domain, type, protocol, sv);
|
||||
if (set_cloexec_or_close(sv[0]) == -1 || set_cloexec_or_close(sv[1]) == -1)
|
||||
retval = -1;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
int
|
||||
wl_os_socket_peercred(int sockfd, uid_t *uid, gid_t *gid, pid_t *pid)
|
||||
|
|
@ -115,6 +137,22 @@ wl_os_socket_peercred(int sockfd, uid_t *uid, gid_t *gid, pid_t *pid)
|
|||
*pid = ucred.pid;
|
||||
return 0;
|
||||
}
|
||||
#elif defined(HAVE_GETPEEREID) && defined(LOCAL_PEERPID)
|
||||
int
|
||||
wl_os_socket_peercred(int sockfd, uid_t *uid, gid_t *gid, pid_t *pid)
|
||||
{
|
||||
socklen_t len;
|
||||
|
||||
if (getpeereid(sockfd, uid, gid) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = sizeof(pid_t);
|
||||
if (getsockopt(sockfd, SOL_LOCAL, LOCAL_PEERPID, pid, &len) != 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#error "Don't know how to read ucred on this platform"
|
||||
#endif
|
||||
|
|
@ -124,11 +162,13 @@ wl_os_dupfd_cloexec(int fd, int minfd)
|
|||
{
|
||||
int newfd;
|
||||
|
||||
#ifdef F_DUPFD_CLOEXEC
|
||||
newfd = fcntl(fd, F_DUPFD_CLOEXEC, minfd);
|
||||
if (newfd >= 0)
|
||||
return newfd;
|
||||
if (errno != EINVAL)
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
newfd = fcntl(fd, F_DUPFD, minfd);
|
||||
return set_cloexec_or_close(newfd);
|
||||
|
|
@ -176,7 +216,7 @@ wl_os_recvmsg_cloexec(int sockfd, struct msghdr *msg, int flags)
|
|||
* fix (https://cgit.freebsd.org/src/commit/?id=6ceacebdf52211).
|
||||
*/
|
||||
#pragma message("Using fallback directly since MSG_CMSG_CLOEXEC is broken.")
|
||||
#else
|
||||
#elif defined(MSG_CMSG_CLOEXEC)
|
||||
ssize_t len;
|
||||
|
||||
len = recvmsg(sockfd, msg, flags | MSG_CMSG_CLOEXEC);
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@
|
|||
int
|
||||
wl_os_socket_cloexec(int domain, int type, int protocol);
|
||||
|
||||
int
|
||||
wl_os_socketpair_cloexec(int domain, int type, int protocol, int sv[2]);
|
||||
|
||||
int
|
||||
wl_os_socket_peercred(int sockfd, uid_t *uid, gid_t *gid, pid_t *pid);
|
||||
|
||||
|
|
|
|||
|
|
@ -306,8 +306,10 @@ shm_create_pool(struct wl_client *client, struct wl_resource *resource,
|
|||
uint32_t id, int fd, int32_t size)
|
||||
{
|
||||
struct wl_shm_pool *pool;
|
||||
#ifdef HAVE_MEMFD_CREATE
|
||||
struct stat statbuf;
|
||||
int seals;
|
||||
#endif
|
||||
int prot;
|
||||
int flags;
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "wayland-os.h"
|
||||
#include "wayland-private.h"
|
||||
#include "wayland-server.h"
|
||||
#include "test-runner.h"
|
||||
|
|
@ -88,7 +89,7 @@ TEST(client_destroy_listener)
|
|||
struct client_destroy_listener a, b;
|
||||
int s[2];
|
||||
|
||||
assert(socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, s) == 0);
|
||||
assert(wl_os_socketpair_cloexec(AF_UNIX, SOCK_STREAM, 0, s) == 0);
|
||||
display = wl_display_create();
|
||||
assert(display);
|
||||
client = wl_client_create(display, s[0]);
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
#include <sys/stat.h>
|
||||
#include <poll.h>
|
||||
|
||||
#include "wayland-os.h"
|
||||
#include "wayland-private.h"
|
||||
#include "test-runner.h"
|
||||
#include "test-compositor.h"
|
||||
|
|
@ -48,7 +49,7 @@ setup(int *s)
|
|||
{
|
||||
struct wl_connection *connection;
|
||||
|
||||
assert(socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, s) == 0);
|
||||
assert(wl_os_socketpair_cloexec(AF_UNIX, SOCK_STREAM, 0, s) == 0);
|
||||
|
||||
connection = wl_connection_create(s[0]);
|
||||
assert(connection);
|
||||
|
|
@ -181,8 +182,8 @@ struct marshal_data {
|
|||
static void
|
||||
setup_marshal_data(struct marshal_data *data)
|
||||
{
|
||||
assert(socketpair(AF_UNIX,
|
||||
SOCK_STREAM | SOCK_CLOEXEC, 0, data->s) == 0);
|
||||
assert(wl_os_socketpair_cloexec(AF_UNIX,
|
||||
SOCK_STREAM, 0, data->s) == 0);
|
||||
data->read_connection = wl_connection_create(data->s[0]);
|
||||
assert(data->read_connection);
|
||||
data->write_connection = wl_connection_create(data->s[1]);
|
||||
|
|
@ -824,7 +825,7 @@ TEST(request_bogus_size)
|
|||
for (bogus_size = 11; bogus_size >= 0; bogus_size--) {
|
||||
fprintf(stderr, "* bogus size %d\n", bogus_size);
|
||||
|
||||
assert(socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, s) == 0);
|
||||
assert(wl_os_socketpair_cloexec(AF_UNIX, SOCK_STREAM, 0, s) == 0);
|
||||
display = wl_display_create();
|
||||
assert(display);
|
||||
client = wl_client_create(display, s[0]);
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
|
||||
static int fall_back;
|
||||
|
||||
#ifdef __ELF__
|
||||
/* Play nice with sanitizers
|
||||
*
|
||||
* Sanitizers need to intercept syscalls in the compiler run-time library. As
|
||||
|
|
@ -71,6 +72,13 @@ static int fall_back;
|
|||
#define REAL(func) (__interceptor_ ## func) ? \
|
||||
__interceptor_ ## func : \
|
||||
(__typeof__(&__interceptor_ ## func))dlsym(RTLD_NEXT, #func)
|
||||
#else
|
||||
#define DECL(ret_type, func, ...) \
|
||||
static ret_type (*real_ ## func)(__VA_ARGS__); \
|
||||
static int wrapped_calls_ ## func;
|
||||
|
||||
#define REAL(func) (__typeof__(real_ ## func)) dlsym(RTLD_NEXT, #func)
|
||||
#endif
|
||||
|
||||
DECL(int, socket, int, int, int);
|
||||
DECL(int, fcntl, int, int, ...);
|
||||
|
|
@ -92,10 +100,12 @@ socket(int domain, int type, int protocol)
|
|||
{
|
||||
wrapped_calls_socket++;
|
||||
|
||||
#ifdef SOCK_CLOEXEC
|
||||
if (fall_back && (type & SOCK_CLOEXEC)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return real_socket(domain, type, protocol);
|
||||
}
|
||||
|
|
@ -141,10 +151,12 @@ recvmsg(int sockfd, struct msghdr *msg, int flags)
|
|||
{
|
||||
wrapped_calls_recvmsg++;
|
||||
|
||||
#ifdef MSG_CMSG_CLOEXEC
|
||||
if (fall_back && (flags & MSG_CMSG_CLOEXEC)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return real_recvmsg(sockfd, msg, flags);
|
||||
}
|
||||
|
|
@ -179,7 +191,11 @@ do_os_wrappers_socket_cloexec(int n)
|
|||
* Must have 2 calls if falling back, but must also allow
|
||||
* falling back without a forced fallback.
|
||||
*/
|
||||
#ifdef SOCK_CLOEXEC
|
||||
assert(wrapped_calls_socket > n);
|
||||
#else
|
||||
assert(wrapped_calls_socket == 1);
|
||||
#endif
|
||||
|
||||
exec_fd_leak_check(nr_fds);
|
||||
}
|
||||
|
|
@ -253,8 +269,8 @@ struct marshal_data {
|
|||
static void
|
||||
setup_marshal_data(struct marshal_data *data)
|
||||
{
|
||||
assert(socketpair(AF_UNIX,
|
||||
SOCK_STREAM | SOCK_CLOEXEC, 0, data->s) == 0);
|
||||
assert(wl_os_socketpair_cloexec(AF_UNIX,
|
||||
SOCK_STREAM, 0, data->s) == 0);
|
||||
|
||||
data->read_connection = wl_connection_create(data->s[0]);
|
||||
assert(data->read_connection);
|
||||
|
|
@ -342,9 +358,10 @@ do_os_wrappers_recvmsg_cloexec(int n)
|
|||
struct marshal_data data;
|
||||
|
||||
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
|
||||
* 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;
|
||||
#else
|
||||
data.wrapped_calls = n;
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "wayland-os.h"
|
||||
#include "wayland-server.h"
|
||||
#include "test-runner.h"
|
||||
|
||||
|
|
@ -40,7 +41,7 @@ TEST(create_resource_tst)
|
|||
int s[2];
|
||||
uint32_t id;
|
||||
|
||||
assert(socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, s) == 0);
|
||||
assert(wl_os_socketpair_cloexec(AF_UNIX, SOCK_STREAM, 0, s) == 0);
|
||||
display = wl_display_create();
|
||||
assert(display);
|
||||
client = wl_client_create(display, s[0]);
|
||||
|
|
@ -111,7 +112,7 @@ TEST(destroy_res_tst)
|
|||
.notify = &destroy_notify
|
||||
};
|
||||
|
||||
assert(socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, s) == 0);
|
||||
assert(wl_os_socketpair_cloexec(AF_UNIX, SOCK_STREAM, 0, s) == 0);
|
||||
display = wl_display_create();
|
||||
assert(display);
|
||||
client = wl_client_create(display, s[0]);
|
||||
|
|
@ -159,7 +160,7 @@ TEST(create_resource_with_same_id)
|
|||
int s[2];
|
||||
uint32_t id;
|
||||
|
||||
assert(socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, s) == 0);
|
||||
assert(wl_os_socketpair_cloexec(AF_UNIX, SOCK_STREAM, 0, s) == 0);
|
||||
display = wl_display_create();
|
||||
assert(display);
|
||||
client = wl_client_create(display, s[0]);
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ get_socket_name(void)
|
|||
|
||||
gettimeofday(&tv, NULL);
|
||||
snprintf(retval, sizeof retval, "wayland-test-%d-%ld%ld",
|
||||
getpid(), tv.tv_sec, tv.tv_usec);
|
||||
(int)getpid(), (long)tv.tv_sec, (long)tv.tv_usec);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
|
@ -510,7 +510,7 @@ static const struct wl_registry_listener registry_listener =
|
|||
NULL
|
||||
};
|
||||
|
||||
struct client *client_connect()
|
||||
struct client *client_connect(void)
|
||||
{
|
||||
struct wl_registry *reg;
|
||||
struct client *c = calloc(1, sizeof *c);
|
||||
|
|
|
|||
|
|
@ -63,7 +63,12 @@ static int timeouts_enabled = 1;
|
|||
/* set to one if the output goes to the terminal */
|
||||
static int is_atty = 0;
|
||||
|
||||
#ifdef __APPLE__
|
||||
extern const struct test __start_test_section __asm("section$start$__RODATA$test_section");
|
||||
extern const struct test __stop_test_section __asm("section$end$__RODATA$test_section");
|
||||
#else
|
||||
extern const struct test __start_test_section, __stop_test_section;
|
||||
#endif
|
||||
|
||||
static const struct test *
|
||||
find_test(const char *name)
|
||||
|
|
@ -308,6 +313,12 @@ is_debugger_attached(void)
|
|||
|
||||
return rc;
|
||||
}
|
||||
#else
|
||||
static int
|
||||
is_debugger_attached(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
|
|
|
|||
|
|
@ -31,6 +31,12 @@
|
|||
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define TEST_SECTION "__RODATA,test_section"
|
||||
#else
|
||||
#define TEST_SECTION "test_section"
|
||||
#endif
|
||||
|
||||
struct test {
|
||||
const char *name;
|
||||
void (*run)(void);
|
||||
|
|
@ -41,7 +47,7 @@ struct test {
|
|||
static void name(void); \
|
||||
\
|
||||
const struct test test##name \
|
||||
__attribute__ ((used, section ("test_section"))) = { \
|
||||
__attribute__ ((used, section (TEST_SECTION))) = { \
|
||||
#name, name, 0 \
|
||||
}; \
|
||||
\
|
||||
|
|
@ -51,7 +57,7 @@ struct test {
|
|||
static void name(void); \
|
||||
\
|
||||
const struct test test##name \
|
||||
__attribute__ ((used, section ("test_section"))) = { \
|
||||
__attribute__ ((used, section (TEST_SECTION))) = { \
|
||||
#name, name, 1 \
|
||||
}; \
|
||||
\
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue