Skip to content

Instantly share code, notes, and snippets.

@mgood7123
Created November 30, 2022 09:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mgood7123/39fb2f8eb43d99df5994b237eb5130a7 to your computer and use it in GitHub Desktop.
Save mgood7123/39fb2f8eb43d99df5994b237eb5130a7 to your computer and use it in GitHub Desktop.
int
wl_connection_flush(struct wl_connection *connection)
{
struct iovec iov[2];
int len = 0, count;
size_t clen;
uint32_t tail;
if (!connection->want_flush)
return 0;
tail = connection->out.tail;
uid_t uid = 0; gid_t gid = 0; pid_t pid = 0;
struct wl_ring_buffer * buffer = &connection->fds_out;
struct RING_BUFFER_FD_STORAGE s = {0};
RING_BUFFER_INIT_STORAGE(buffer, s);
if (s.len > 0) {
wl_os_socket_peercred(connection->fd, &uid, &gid, &pid);
}
if (s.len > 0) {
// send fd's first
size_t pi_bytes = sizeof(WSAPROTOCOL_INFO) * s.len;
WSAPROTOCOL_INFO * pi = zalloc(pi_bytes);
WSAPROTOCOL_INFO * start = pi;
// send the fd's
for (FD_HANDLE_T * fd = RING_BUFFER_GET_NEXT_FD(s); fd != NULL; fd = RING_BUFFER_GET_NEXT_FD(s)) {
if (FD_HANDLE_IS_SOCKET(*fd)) {
if (WSADuplicateSocket(*fd, pid, start) == SOCKET_ERROR) {
wl_log("WSADuplicateSocket(): failed. Error = %d\n", WSAGetLastError());
}
start += sizeof(WSAPROTOCOL_INFO);
}
}
do {
len = send(connection->fd, pi_bytes, sizeof(size_t), 0);
} while (len == SOCKET_ERROR && WSAGetLastError() == WSAEINTR);
do {
len = send(connection->fd, pi, pi_bytes, 0);
} while (len == SOCKET_ERROR && WSAGetLastError() == WSAEINTR);
free(pi);
close_fds(&connection->fds_out, MAX_FDS_OUT);
}
if (len == SOCKET_ERROR)
return -1;
// now send data
while (connection->out.head - connection->out.tail > 0) {
ring_buffer_get_iov(&connection->out, iov, &count);
if (len == SOCKET_ERROR)
return -1;
struct wl_ring_buffer * buffer = &connection->out;
do {
len = send(connection->fd, ring_buffer_size(buffer), sizeof(size_t), 0);
} while (len == SOCKET_ERROR && WSAGetLastError() == WSAEINTR);
do {
len = send(connection->fd, connection->out.data, ring_buffer_size(buffer), 0);
} while (len == SOCKET_ERROR && WSAGetLastError() == WSAEINTR);
connection->out.tail += len;
}
connection->want_flush = 0;
return connection->out.head - tail;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment