mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2026-04-06 07:15:47 -04:00
Merge branch 'fix-cmsg' into 'main'
connection: properly use sendmsg(2) and recvmsg(2) See merge request wayland/wayland!445
This commit is contained in:
commit
83b741e68e
2 changed files with 34 additions and 16 deletions
|
|
@ -424,14 +424,23 @@ decode_cmsg(struct wl_ring_buffer *buffer, struct msghdr *msg)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
size = cmsg->cmsg_len - CMSG_LEN(0);
|
size = cmsg->cmsg_len - CMSG_LEN(0);
|
||||||
|
if (size % sizeof(int) != 0) {
|
||||||
|
/* This indicates a kernel bug. */
|
||||||
|
wl_abort("SOL_SOCKET SCM_RIGHTS cmsg has invalid size %zu\n", size);
|
||||||
|
}
|
||||||
|
|
||||||
if (ring_buffer_ensure_space(buffer, size) < 0 || overflow) {
|
if (ring_buffer_ensure_space(buffer, size) < 0 || overflow) {
|
||||||
|
const unsigned char *data = CMSG_DATA(cmsg);
|
||||||
overflow = 1;
|
overflow = 1;
|
||||||
size /= sizeof(int32_t);
|
for (i = 0; i < size; i += sizeof(int)) {
|
||||||
for (i = 0; i < size; i++)
|
/* man:cmsg(3) requires that memcpy()
|
||||||
close(((int*)CMSG_DATA(cmsg))[i]);
|
* be used instead of a pointer cast. */
|
||||||
|
int fd;
|
||||||
|
memcpy(&fd, data + i, sizeof(fd));
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
} else if (ring_buffer_put(buffer, CMSG_DATA(cmsg), size) < 0) {
|
} else if (ring_buffer_put(buffer, CMSG_DATA(cmsg), size) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -443,22 +452,26 @@ decode_cmsg(struct wl_ring_buffer *buffer, struct msghdr *msg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
ssize_t
|
||||||
wl_connection_flush(struct wl_connection *connection)
|
wl_connection_flush(struct wl_connection *connection)
|
||||||
{
|
{
|
||||||
struct iovec iov[2];
|
struct iovec iov[2];
|
||||||
struct msghdr msg = {0};
|
struct msghdr msg = {0};
|
||||||
char cmsg[CLEN];
|
ssize_t len = 0;
|
||||||
int len = 0, count;
|
union {
|
||||||
|
char cmsg[CLEN];
|
||||||
|
struct cmsghdr align;
|
||||||
|
} u;
|
||||||
size_t clen;
|
size_t clen;
|
||||||
size_t tail;
|
size_t tail;
|
||||||
|
int count;
|
||||||
|
|
||||||
if (!connection->want_flush)
|
if (!connection->want_flush)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
tail = connection->out.tail;
|
tail = connection->out.tail;
|
||||||
while (ring_buffer_size(&connection->out) > 0) {
|
while (ring_buffer_size(&connection->out) > 0) {
|
||||||
build_cmsg(&connection->fds_out, cmsg, &clen);
|
build_cmsg(&connection->fds_out, u.cmsg, &clen);
|
||||||
|
|
||||||
if (clen >= CLEN) {
|
if (clen >= CLEN) {
|
||||||
/* UNIX domain sockets allows to send file descriptors
|
/* UNIX domain sockets allows to send file descriptors
|
||||||
|
|
@ -487,7 +500,7 @@ wl_connection_flush(struct wl_connection *connection)
|
||||||
msg.msg_namelen = 0;
|
msg.msg_namelen = 0;
|
||||||
msg.msg_iov = iov;
|
msg.msg_iov = iov;
|
||||||
msg.msg_iovlen = count;
|
msg.msg_iovlen = count;
|
||||||
msg.msg_control = (clen > 0) ? cmsg : NULL;
|
msg.msg_control = (clen > 0) ? u.cmsg : NULL;
|
||||||
msg.msg_controllen = clen;
|
msg.msg_controllen = clen;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
@ -514,13 +527,17 @@ wl_connection_pending_input(struct wl_connection *connection)
|
||||||
return ring_buffer_size(&connection->in);
|
return ring_buffer_size(&connection->in);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
ssize_t
|
||||||
wl_connection_read(struct wl_connection *connection)
|
wl_connection_read(struct wl_connection *connection)
|
||||||
{
|
{
|
||||||
struct iovec iov[2];
|
struct iovec iov[2];
|
||||||
struct msghdr msg;
|
struct msghdr msg;
|
||||||
char cmsg[CLEN];
|
union {
|
||||||
int len, count, ret;
|
char cmsg[CLEN];
|
||||||
|
struct cmsghdr align;
|
||||||
|
} u;
|
||||||
|
int count, ret;
|
||||||
|
ssize_t len;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
int data_size = ring_buffer_size(&connection->in);
|
int data_size = ring_buffer_size(&connection->in);
|
||||||
|
|
@ -538,8 +555,8 @@ wl_connection_read(struct wl_connection *connection)
|
||||||
msg.msg_namelen = 0;
|
msg.msg_namelen = 0;
|
||||||
msg.msg_iov = iov;
|
msg.msg_iov = iov;
|
||||||
msg.msg_iovlen = count;
|
msg.msg_iovlen = count;
|
||||||
msg.msg_control = cmsg;
|
msg.msg_control = u.cmsg;
|
||||||
msg.msg_controllen = sizeof cmsg;
|
msg.msg_controllen = sizeof u.cmsg;
|
||||||
msg.msg_flags = 0;
|
msg.msg_flags = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#define WL_HIDE_DEPRECATED 1
|
#define WL_HIDE_DEPRECATED 1
|
||||||
|
|
||||||
|
|
@ -144,13 +145,13 @@ wl_connection_copy(struct wl_connection *connection, void *data, size_t size);
|
||||||
void
|
void
|
||||||
wl_connection_consume(struct wl_connection *connection, size_t size);
|
wl_connection_consume(struct wl_connection *connection, size_t size);
|
||||||
|
|
||||||
int
|
ssize_t
|
||||||
wl_connection_flush(struct wl_connection *connection);
|
wl_connection_flush(struct wl_connection *connection);
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
wl_connection_pending_input(struct wl_connection *connection);
|
wl_connection_pending_input(struct wl_connection *connection);
|
||||||
|
|
||||||
int
|
ssize_t
|
||||||
wl_connection_read(struct wl_connection *connection);
|
wl_connection_read(struct wl_connection *connection);
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue