Exemplo n.º 1
0
Arquivo: ipcc.c Projeto: krig/libqb
ssize_t
qb_ipcc_event_recv(struct qb_ipcc_connection * c, void *msg_pt,
		   size_t msg_len, int32_t ms_timeout)
{
	char one_byte = 1;
	int32_t res;
	ssize_t size;

	if (c == NULL) {
		return -EINVAL;
	}
	res = _check_connection_state_with(c, -EAGAIN, _event_sock_one_way_get(c),
					   ms_timeout, POLLIN);
	if (res < 0) {
		return res;
	}
	size = c->funcs.recv(&c->event, msg_pt, msg_len, ms_timeout);
	if (size > 0 && c->needs_sock_for_poll) {
		res = qb_ipc_us_recv(&c->setup, &one_byte, 1, -1);
		if (res != 1) {
			size = res;
		}
	}
	return _check_connection_state(c, size);
}
Exemplo n.º 2
0
Arquivo: ipcc.c Projeto: ip1981/libqb
ssize_t
qb_ipcc_event_recv(struct qb_ipcc_connection * c, void *msg_pt,
		   size_t msg_len, int32_t ms_timeout)
{
	char one_byte = 1;
	int32_t res;
	ssize_t size;
	struct qb_ipc_one_way *ow = NULL;

	if (c == NULL) {
		return -EINVAL;
	}
	ow = _event_sock_one_way_get(c);
	if (ow) {
		res = qb_ipc_us_recv_ready(ow, ms_timeout);
		if (res < 0) {
			_check_connection_state(c, res);
			return res;
		}
	}
	size = c->funcs.recv(&c->event, msg_pt, msg_len, ms_timeout);
	if (size < 0) {
		_check_connection_state(c, size);
		return size;
	}
	if (c->needs_sock_for_poll) {
		res = qb_ipc_us_recv(&c->setup, &one_byte, 1, -1);
		if (res < 0) {
			_check_connection_state(c, res);
			return res;
		}
	}
	return size;
}
Exemplo n.º 3
0
int32_t
qb_ipcc_us_setup_connect(struct qb_ipcc_connection *c,
			 struct qb_ipc_connection_response *r)
{
	int32_t res;
	struct qb_ipc_connection_request request;
#ifdef QB_LINUX
	int off = 0;
	int on = 1;
#endif

	res = qb_ipcc_stream_sock_connect(c->name, &c->setup.u.us.sock);
	if (res != 0) {
		return res;
	}
#ifdef QB_LINUX
	setsockopt(c->setup.u.us.sock, SOL_SOCKET, SO_PASSCRED, &on,
		   sizeof(on));
#endif

	memset(&request, 0, sizeof(request));
	request.hdr.id = QB_IPC_MSG_AUTHENTICATE;
	request.hdr.size = sizeof(request);
	request.max_msg_size = c->setup.max_msg_size;
	res = qb_ipc_us_send(&c->setup, &request, request.hdr.size);
	if (res < 0) {
		qb_ipcc_us_sock_close(c->setup.u.us.sock);
		return res;
	}
#ifdef QB_LINUX
	setsockopt(c->setup.u.us.sock, SOL_SOCKET, SO_PASSCRED, &off,
		   sizeof(off));
#endif

	res =
	    qb_ipc_us_recv(&c->setup, r,
			   sizeof(struct qb_ipc_connection_response), -1);
	if (res < 0) {
		return res;
	}

	if (r->hdr.error != 0) {
		return r->hdr.error;
	}
	return 0;
}
Exemplo n.º 4
0
Arquivo: ipcs.c Projeto: ip1981/libqb
int32_t
qb_ipcs_dispatch_connection_request(int32_t fd, int32_t revents, void *data)
{
	struct qb_ipcs_connection *c = (struct qb_ipcs_connection *)data;
	char bytes[MAX_RECV_MSGS];
	int32_t res;
	int32_t res2;
	int32_t recvd = 0;
	ssize_t avail;

	if (revents & POLLNVAL) {
		qb_util_log(LOG_DEBUG, "NVAL conn:%p fd:%d", c, fd);
		return -EINVAL;
	}
	if (revents & POLLHUP) {
		qb_util_log(LOG_DEBUG, "HUP conn:%p fd:%d", c, fd);
		qb_ipcs_disconnect(c);
		return -ESHUTDOWN;
	}

	if (revents & POLLOUT) {
		res = resend_event_notifications(c);
		if (res < 0 && res != -EAGAIN) {
			errno = -res;
			qb_util_perror(LOG_WARNING, "resend_event_notifications");
		}
		if ((revents & POLLIN) == 0) {
			return 0;
		}
	}
	if (c->fc_enabled) {
		return 0;
	}
	avail = _request_q_len_get(c);

	if (c->service->needs_sock_for_poll && avail == 0) {
		res2 = qb_ipc_us_recv(&c->setup, bytes, 1, 0);
		qb_util_log(LOG_WARNING,
			    "conn:%p Nothing in q but got POLLIN on fd:%d (res2:%d)",
			    c, fd, res2);
		return 0;
	}

	do {
		res = _process_request_(c, IPC_REQUEST_TIMEOUT);
		if (res > 0 || res == -ENOBUFS || res == -EINVAL) {
			recvd++;
		}
		if (res > 0) {
			avail--;
		}
	} while (avail > 0 && res > 0 && !c->fc_enabled);

	if (c->service->needs_sock_for_poll && recvd > 0) {
		res2 = qb_ipc_us_recv(&c->setup, bytes, recvd, -1);
		if (res2 < 0) {
			errno = -res2;
			qb_util_perror(LOG_ERR, "error receiving from setup sock");
		}
	}

	res = QB_MIN(0, res);
	if (res == -EAGAIN || res == -ETIMEDOUT || res == -ENOBUFS) {
		res = 0;
	}
	if (res != 0) {
		errno = -res;
		qb_util_perror(LOG_ERR, "request returned error");
		qb_ipcs_connection_unref(c);
	}

	return res;
}