Example #1
0
static int
decode_cmsg(struct wl_buffer *buffer, struct msghdr *msg)
{
	struct cmsghdr *cmsg;
	size_t size, max, i;
	int overflow = 0;

	for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL;
	     cmsg = CMSG_NXTHDR(msg, cmsg)) {
		if (cmsg->cmsg_level != SOL_SOCKET ||
		    cmsg->cmsg_type != SCM_RIGHTS)
			continue;

		size = cmsg->cmsg_len - CMSG_LEN(0);
		max = sizeof(buffer->data) - wl_buffer_size(buffer);
		if (size > max || overflow) {
			overflow = 1;
			size /= sizeof(int32_t);
			for (i = 0; i < size; i++)
				close(((int*)CMSG_DATA(cmsg))[i]);
		} else if (wl_buffer_put(buffer, CMSG_DATA(cmsg), size) < 0) {
				return -1;
		}
	}

	if (overflow) {
		errno = EOVERFLOW;
		return -1;
	}

	return 0;
}
Example #2
0
static int
wl_connection_put_fd(struct wl_connection *connection, int32_t fd)
{
	if (wl_buffer_size(&connection->fds_out) == MAX_FDS_OUT * sizeof fd) {
		connection->want_flush = 1;
		if (wl_connection_flush(connection) < 0)
			return -1;
	}

	return wl_buffer_put(&connection->fds_out, &fd, sizeof fd);
}
Example #3
0
static int
wl_connection_put_fd(struct wl_connection *connection, int32_t fd)
{
	if (wl_buffer_size(&connection->fds_out) == MAX_FDS_OUT * sizeof fd)
		if (wl_connection_data(connection, WL_CONNECTION_WRITABLE))
			return -1;

	wl_buffer_put(&connection->fds_out, &fd, sizeof fd);

	return 0;
}
Example #4
0
int
wl_connection_read(struct wl_connection *connection)
{
	struct iovec iov[2];
	struct msghdr msg;
	char cmsg[CLEN];
	int len, count, ret;

	if (wl_buffer_size(&connection->in) >= sizeof(connection->in.data)) {
		errno = EOVERFLOW;
		return -1;
	}

	wl_buffer_put_iov(&connection->in, iov, &count);

	msg.msg_name = NULL;
	msg.msg_namelen = 0;
	msg.msg_iov = iov;
	msg.msg_iovlen = count;
	msg.msg_control = cmsg;
	msg.msg_controllen = sizeof cmsg;
	msg.msg_flags = 0;

	do {
		len = wl_os_recvmsg_cloexec(connection->fd, &msg, MSG_DONTWAIT);
	} while (len < 0 && errno == EINTR);

	if (len <= 0)
		return len;

	ret = decode_cmsg(&connection->fds_in, &msg);
	if (ret)
		return -1;

	connection->in.head += len;

	return wl_connection_pending_input(connection);
}
Example #5
0
uint32_t
wl_connection_pending_input(struct wl_connection *connection)
{
	return wl_buffer_size(&connection->in);
}