diff --git a/src/wayland-os.c b/src/wayland-os.c index 86e9816d..ba2c814b 100644 --- a/src/wayland-os.c +++ b/src/wayland-os.c @@ -81,6 +81,26 @@ wl_os_socket_cloexec(int domain, int type, int 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) diff --git a/src/wayland-os.h b/src/wayland-os.h index 068fd2fe..42e28007 100644 --- a/src/wayland-os.h +++ b/src/wayland-os.h @@ -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); diff --git a/tests/client-test.c b/tests/client-test.c index 47be83fc..d3b09443 100644 --- a/tests/client-test.c +++ b/tests/client-test.c @@ -34,6 +34,7 @@ #include #include +#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]); diff --git a/tests/connection-test.c b/tests/connection-test.c index 9762e0da..80f4f443 100644 --- a/tests/connection-test.c +++ b/tests/connection-test.c @@ -37,6 +37,7 @@ #include #include +#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]); diff --git a/tests/os-wrappers-test.c b/tests/os-wrappers-test.c index 552eddbd..717fc19f 100644 --- a/tests/os-wrappers-test.c +++ b/tests/os-wrappers-test.c @@ -92,10 +92,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); } @@ -181,7 +183,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); } @@ -255,8 +261,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); diff --git a/tests/resources-test.c b/tests/resources-test.c index fa6ba2b2..ca4595cb 100644 --- a/tests/resources-test.c +++ b/tests/resources-test.c @@ -28,6 +28,7 @@ #include #include +#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]);