os: Provide wl_os_socketpair_cloexec wrapper for systems without SOCK_CLOEXEC

Reviewed-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
Signed-off-by: Weijia Wang <contact@weijia.wang>
This commit is contained in:
Weijia Wang 2022-07-28 01:37:50 +02:00 committed by Jeremy Huddleston Sequoia
parent b5cb23d698
commit e519c4318c
6 changed files with 42 additions and 10 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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