#define STATIC_IOV(_var) { .iov_base = (char *) &(_var), .iov_len = sizeof(_var) }
+#define UBUS_MSGBUF_REDUCTION_INTERVAL 16
+
static const struct blob_attr_info ubus_policy[UBUS_ATTR_MAX] = {
[UBUS_ATTR_STATUS] = { .type = BLOB_ATTR_INT32 },
[UBUS_ATTR_OBJID] = { .type = BLOB_ATTR_INT32 },
if (!iov_len)
return len;
}
+ iov->iov_base += cur_len;
iov->iov_len -= cur_len;
+ msghdr.msg_iov = iov;
+ msghdr.msg_iovlen = iov_len;
} while (1);
/* Should never reach here */
return false;
len = blob_raw_len(&hdrbuf.data);
- if (len > ctx->msgbuf_data_len) {
+ if (len > ctx->msgbuf_data_len)
+ ctx->msgbuf_reduction_counter = UBUS_MSGBUF_REDUCTION_INTERVAL;
+ else if (ctx->msgbuf_reduction_counter > 0 && len < UBUS_MSG_CHUNK_SIZE)
+ len = !--ctx->msgbuf_reduction_counter ? UBUS_MSG_CHUNK_SIZE : -1;
+ else
+ len = -1;
+
+ if (len > -1) {
ctx->msgbuf.data = realloc(ctx->msgbuf.data, len * sizeof(char));
if (ctx->msgbuf.data)
ctx->msgbuf_data_len = len;
void __hidden ubus_handle_data(struct uloop_fd *u, unsigned int events)
{
struct ubus_context *ctx = container_of(u, struct ubus_context, sock);
- struct ubus_msghdr *hdr = &ctx->msgbuf.hdr;
int recv_fd = -1;
while (get_next_msg(ctx, &recv_fd)) {
- ubus_process_msg(ctx, hdr, recv_fd);
+ ubus_process_msg(ctx, &ctx->msgbuf, recv_fd);
if (uloop_cancelled)
break;
}
goto out_free;
ret = UBUS_STATUS_OK;
- fcntl(ctx->sock.fd, F_SETFL, fcntl(ctx->sock.fd, F_GETFL) | O_NONBLOCK);
+ fcntl(ctx->sock.fd, F_SETFL, fcntl(ctx->sock.fd, F_GETFL) | O_NONBLOCK | O_CLOEXEC);
ubus_refresh_state(ctx);