ssize_t ubus_msg_writev(int fd, struct ubus_msg_buf *ub, size_t offset)
{
+ uint8_t fd_buf[CMSG_SPACE(sizeof(int))] = { 0 };
static struct iovec iov[2];
- static struct {
- int fd;
- struct cmsghdr h;
- } fd_buf = {
- .h = {
- .cmsg_len = sizeof(fd_buf),
- .cmsg_level = SOL_SOCKET,
- .cmsg_type = SCM_RIGHTS,
- },
- };
- struct msghdr msghdr = {
- .msg_iov = iov,
- .msg_iovlen = ARRAY_SIZE(iov),
- .msg_control = &fd_buf,
- .msg_controllen = sizeof(fd_buf),
- };
+ struct msghdr msghdr = { 0 };
struct ubus_msghdr hdr;
+ struct cmsghdr *cmsg;
ssize_t ret;
+ int *pfd;
- fd_buf.fd = ub->fd;
+ msghdr.msg_iov = iov;
+ msghdr.msg_iovlen = ARRAY_SIZE(iov);
+ msghdr.msg_control = fd_buf;
+ msghdr.msg_controllen = sizeof(fd_buf);
+
+ cmsg = CMSG_FIRSTHDR(&msghdr);
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(int));
+
+ pfd = (int *) CMSG_DATA(cmsg);
+ msghdr.msg_controllen = cmsg->cmsg_len;
+
+ *pfd = ub->fd;
if (ub->fd < 0 || offset) {
msghdr.msg_control = NULL;
msghdr.msg_controllen = 0;
return ret;
}
+void ubus_msg_list_free(struct ubus_msg_buf_list *ubl)
+{
+ list_del_init(&ubl->list);
+ ubus_msg_free(ubl->msg);
+ free(ubl);
+}
+
static void ubus_msg_enqueue(struct ubus_client *cl, struct ubus_msg_buf *ub)
{
- if (cl->tx_queue[cl->txq_tail])
+ struct ubus_msg_buf_list *ubl;
+
+ ubl = calloc(1, sizeof(struct ubus_msg_buf_list));
+ if (!ubl)
return;
- cl->tx_queue[cl->txq_tail] = ubus_msg_ref(ub);
- cl->txq_tail = (cl->txq_tail + 1) % ARRAY_SIZE(cl->tx_queue);
+ INIT_LIST_HEAD(&ubl->list);
+ ubl->msg = ubus_msg_ref(ub);
+
+ list_add_tail(&cl->tx_queue, &ubl->list);
}
/* takes the msgbuf reference */
if (ub->hdr.type != UBUS_MSG_MONITOR)
ubusd_monitor_message(cl, ub, true);
- if (!cl->tx_queue[cl->txq_cur]) {
+ if (list_empty(&cl->tx_queue)) {
written = ubus_msg_writev(cl->sock.fd, ub, 0);
if (written < 0)