summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/libutil/Symbols.map6
-rw-r--r--lib/libutil/imsg-buffer.c247
-rw-r--r--lib/libutil/imsg.c228
-rw-r--r--lib/libutil/imsg.h29
4 files changed, 325 insertions, 185 deletions
diff --git a/lib/libutil/Symbols.map b/lib/libutil/Symbols.map
index 55d01cbba0e..79a3f2e524f 100644
--- a/lib/libutil/Symbols.map
+++ b/lib/libutil/Symbols.map
@@ -48,6 +48,7 @@
ibuf_get_string;
ibuf_left;
ibuf_open;
+ ibuf_read;
ibuf_reserve;
ibuf_rewind;
ibuf_seek;
@@ -79,11 +80,13 @@
imsg_get_len;
imsg_get_pid;
imsg_get_type;
+ imsgbuf_allow_fdpass;
imsgbuf_clear;
imsgbuf_flush;
imsgbuf_init;
imsgbuf_queuelen;
imsgbuf_read;
+ imsgbuf_set_maxsize;
imsgbuf_write;
isduid;
login;
@@ -94,8 +97,11 @@
logwtmp;
msgbuf_clear;
msgbuf_free;
+ msgbuf_get;
msgbuf_new;
+ msgbuf_new_reader;
msgbuf_queuelen;
+ msgbuf_read;
msgbuf_write;
ober_add_bitstring;
ober_add_boolean;
diff --git a/lib/libutil/imsg-buffer.c b/lib/libutil/imsg-buffer.c
index d0d5bbf5b6b..c43da77f8af 100644
--- a/lib/libutil/imsg-buffer.c
+++ b/lib/libutil/imsg-buffer.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: imsg-buffer.c,v 1.27 2024/11/21 13:01:07 claudio Exp $ */
+/* $OpenBSD: imsg-buffer.c,v 1.28 2024/11/21 13:03:21 claudio Exp $ */
/*
* Copyright (c) 2023 Claudio Jeker <claudio@openbsd.org>
@@ -34,9 +34,17 @@
struct msgbuf {
TAILQ_HEAD(, ibuf) bufs;
+ TAILQ_HEAD(, ibuf) rbufs;
uint32_t queued;
+ char *rbuf;
+ struct ibuf *rpmsg;
+ ssize_t (*readhdr)(struct ibuf *, void *);
+ void *rarg;
+ size_t roff;
+ size_t hdrsize;
};
+static void msgbuf_read_enqueue(struct msgbuf *, struct ibuf *);
static void msgbuf_enqueue(struct msgbuf *, struct ibuf *);
static void msgbuf_dequeue(struct msgbuf *, struct ibuf *);
static void msgbuf_drain(struct msgbuf *, size_t);
@@ -560,15 +568,46 @@ msgbuf_new(void)
return (NULL);
msgbuf->queued = 0;
TAILQ_INIT(&msgbuf->bufs);
+ TAILQ_INIT(&msgbuf->rbufs);
return msgbuf;
}
+struct msgbuf *
+msgbuf_new_reader(size_t hdrsz, ssize_t (*readhdr)(struct ibuf *, void *),
+ void *arg)
+{
+ struct msgbuf *msgbuf;
+ char *buf;
+
+ if (hdrsz == 0 || hdrsz > IBUF_READ_SIZE / 2) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ if ((buf = malloc(IBUF_READ_SIZE)) == NULL)
+ return (NULL);
+
+ msgbuf = msgbuf_new();
+ if (msgbuf == NULL) {
+ free(buf);
+ return (NULL);
+ }
+
+ msgbuf->rbuf = buf;
+ msgbuf->hdrsize = hdrsz;
+ msgbuf->readhdr = readhdr;
+ msgbuf->rarg = arg;
+
+ return (msgbuf);
+}
+
void
msgbuf_free(struct msgbuf *msgbuf)
{
if (msgbuf != NULL)
msgbuf_clear(msgbuf);
+ free(msgbuf->rbuf);
free(msgbuf);
}
@@ -583,8 +622,29 @@ msgbuf_clear(struct msgbuf *msgbuf)
{
struct ibuf *buf;
+ /* write side */
while ((buf = TAILQ_FIRST(&msgbuf->bufs)) != NULL)
msgbuf_dequeue(msgbuf, buf);
+ msgbuf->queued = 0;
+
+ /* read side */
+ while ((buf = TAILQ_FIRST(&msgbuf->rbufs)) != NULL) {
+ TAILQ_REMOVE(&msgbuf->rbufs, buf, entry);
+ ibuf_free(buf);
+ }
+ msgbuf->roff = 0;
+ ibuf_free(msgbuf->rpmsg);
+ msgbuf->rpmsg = NULL;
+}
+
+struct ibuf *
+msgbuf_get(struct msgbuf *msgbuf)
+{
+ struct ibuf *buf;
+
+ if ((buf = TAILQ_FIRST(&msgbuf->rbufs)) != NULL)
+ TAILQ_REMOVE(&msgbuf->rbufs, buf, entry);
+ return buf;
}
int
@@ -606,7 +666,7 @@ ibuf_write(int fd, struct msgbuf *msgbuf)
if (i == 0)
return (0); /* nothing queued */
-again:
+ again:
if ((n = writev(fd, iov, i)) == -1) {
if (errno == EINTR)
goto again;
@@ -665,7 +725,7 @@ msgbuf_write(int fd, struct msgbuf *msgbuf)
*(int *)CMSG_DATA(cmsg) = buf0->fd;
}
-again:
+ again:
if ((n = sendmsg(fd, &msg, 0)) == -1) {
if (errno == EINTR)
goto again;
@@ -689,6 +749,187 @@ again:
return (0);
}
+static int
+ibuf_read_process(struct msgbuf *msgbuf, int fd)
+{
+ struct ibuf rbuf, msg;
+ ssize_t sz;
+
+ ibuf_from_buffer(&rbuf, msgbuf->rbuf, msgbuf->roff);
+
+ /* fds must be passed at start of message of at least hdrsize bytes */
+ if (msgbuf->rpmsg != NULL && fd != -1) {
+ close(fd);
+ fd = -1;
+ }
+
+ do {
+ if (msgbuf->rpmsg == NULL) {
+ if (ibuf_size(&rbuf) < msgbuf->hdrsize) {
+ if (fd != -1) {
+ close(fd);
+ fd = -1;
+ }
+ break;
+ }
+ /* get size from header */
+ ibuf_from_buffer(&msg, ibuf_data(&rbuf),
+ msgbuf->hdrsize);
+ sz = msgbuf->readhdr(&msg, msgbuf->rarg);
+ if (sz == -1)
+ goto fail;
+ if ((msgbuf->rpmsg = ibuf_open(sz)) == NULL)
+ goto fail;
+ if (fd != -1) {
+ ibuf_fd_set(msgbuf->rpmsg, fd);
+ fd = -1;
+ }
+ }
+
+ if (ibuf_left(msgbuf->rpmsg) <= ibuf_size(&rbuf))
+ sz = ibuf_left(msgbuf->rpmsg);
+ else
+ sz = ibuf_size(&rbuf);
+
+ /* neither call below can fail */
+ if (ibuf_get_ibuf(&rbuf, sz, &msg) == -1 ||
+ ibuf_add_ibuf(msgbuf->rpmsg, &msg) == -1)
+ goto fail;
+
+ if (ibuf_left(msgbuf->rpmsg) == 0) {
+ msgbuf_read_enqueue(msgbuf, msgbuf->rpmsg);
+ msgbuf->rpmsg = NULL;
+ }
+ } while (ibuf_size(&rbuf) > 0);
+
+ if (ibuf_size(&rbuf) > 0)
+ memmove(msgbuf->rbuf, ibuf_data(&rbuf), ibuf_size(&rbuf));
+ msgbuf->roff = ibuf_size(&rbuf);
+
+ return (1);
+
+ fail:
+ /* XXX cleanup */
+ return (-1);
+}
+
+int
+ibuf_read(int fd, struct msgbuf *msgbuf)
+{
+ struct iovec iov;
+ ssize_t n;
+
+ if (msgbuf->rbuf == NULL) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ iov.iov_base = msgbuf->rbuf + msgbuf->roff;
+ iov.iov_len = IBUF_READ_SIZE - msgbuf->roff;
+
+ again:
+ if ((n = readv(fd, &iov, 1)) == -1) {
+ if (errno == EINTR)
+ goto again;
+ if (errno == EAGAIN)
+ /* lets retry later again */
+ return (1);
+ return (-1);
+ }
+ if (n == 0) /* connection closed */
+ return (0);
+
+ msgbuf->roff += n;
+ /* new data arrived, try to process it */
+ return (ibuf_read_process(msgbuf, -1));
+}
+
+int
+msgbuf_read(int fd, struct msgbuf *msgbuf)
+{
+ struct msghdr msg;
+ struct cmsghdr *cmsg;
+ union {
+ struct cmsghdr hdr;
+ char buf[CMSG_SPACE(sizeof(int) * 1)];
+ } cmsgbuf;
+ struct iovec iov;
+ ssize_t n;
+ int fdpass = -1;
+
+ if (msgbuf->rbuf == NULL) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ memset(&msg, 0, sizeof(msg));
+ memset(&cmsgbuf, 0, sizeof(cmsgbuf));
+
+ iov.iov_base = msgbuf->rbuf + msgbuf->roff;
+ iov.iov_len = IBUF_READ_SIZE - msgbuf->roff;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = &cmsgbuf.buf;
+ msg.msg_controllen = sizeof(cmsgbuf.buf);
+
+again:
+ if ((n = recvmsg(fd, &msg, 0)) == -1) {
+ if (errno == EINTR)
+ goto again;
+ if (errno == EMSGSIZE)
+ /*
+ * Not enough fd slots: fd passing failed, retry
+ * to receive the message without fd.
+ * imsg_get_fd() will return -1 in that case.
+ */
+ goto again;
+ if (errno == EAGAIN)
+ /* lets retry later again */
+ return (1);
+ return (-1);
+ }
+ if (n == 0) /* connection closed */
+ return (0);
+
+ msgbuf->roff += n;
+
+ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
+ cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+ if (cmsg->cmsg_level == SOL_SOCKET &&
+ cmsg->cmsg_type == SCM_RIGHTS) {
+ int i, j, f;
+
+ /*
+ * We only accept one file descriptor. Due to C
+ * padding rules, our control buffer might contain
+ * more than one fd, and we must close them.
+ */
+ j = ((char *)cmsg + cmsg->cmsg_len -
+ (char *)CMSG_DATA(cmsg)) / sizeof(int);
+ for (i = 0; i < j; i++) {
+ f = ((int *)CMSG_DATA(cmsg))[i];
+ if (i == 0)
+ fdpass = f;
+ else
+ close(f);
+ }
+ }
+ /* we do not handle other ctl data level */
+ }
+
+ /* new data arrived, try to process it */
+ return (ibuf_read_process(msgbuf, fdpass));
+}
+
+static void
+msgbuf_read_enqueue(struct msgbuf *msgbuf, struct ibuf *buf)
+{
+ /* if buf lives on the stack abort before causing more harm */
+ if (buf->fd == IBUF_FD_MARK_ON_STACK)
+ abort();
+ TAILQ_INSERT_TAIL(&msgbuf->rbufs, buf, entry);
+}
+
static void
msgbuf_enqueue(struct msgbuf *msgbuf, struct ibuf *buf)
{
diff --git a/lib/libutil/imsg.c b/lib/libutil/imsg.c
index 4e5e9041d83..73ac5d4bd5c 100644
--- a/lib/libutil/imsg.c
+++ b/lib/libutil/imsg.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: imsg.c,v 1.35 2024/11/21 13:01:07 claudio Exp $ */
+/* $OpenBSD: imsg.c,v 1.36 2024/11/21 13:03:21 claudio Exp $ */
/*
* Copyright (c) 2023 Claudio Jeker <claudio@openbsd.org>
@@ -29,115 +29,54 @@
#include "imsg.h"
-struct imsg_fd {
- TAILQ_ENTRY(imsg_fd) entry;
- int fd;
-};
+#define IMSG_ALLOW_FDPASS 0x01
-static int imsg_dequeue_fd(struct imsgbuf *);
+static ssize_t imsg_parse_hdr(struct ibuf *, void *);
-void
+int
imsgbuf_init(struct imsgbuf *imsgbuf, int fd)
{
- imsgbuf->w = msgbuf_new();
- memset(&imsgbuf->r, 0, sizeof(imsgbuf->r));
- imsgbuf->fd = fd;
+ imsgbuf->w = msgbuf_new_reader(IMSG_HEADER_SIZE, imsg_parse_hdr,
+ imsgbuf);
+ if (imsgbuf->w == NULL)
+ return (-1);
imsgbuf->pid = getpid();
- TAILQ_INIT(&imsgbuf->fds);
+ imsgbuf->maxsize = MAX_IMSGSIZE;
+ imsgbuf->fd = fd;
+ imsgbuf->flags = 0;
+ return (0);
}
-int
-imsgbuf_read(struct imsgbuf *imsgbuf)
+void
+imsgbuf_allow_fdpass(struct imsgbuf *imsgbuf)
{
- struct msghdr msg;
- struct cmsghdr *cmsg;
- union {
- struct cmsghdr hdr;
- char buf[CMSG_SPACE(sizeof(int) * 1)];
- } cmsgbuf;
- struct iovec iov;
- ssize_t n;
- int fd;
- struct imsg_fd *ifd;
-
- memset(&msg, 0, sizeof(msg));
- memset(&cmsgbuf, 0, sizeof(cmsgbuf));
-
- iov.iov_base = imsgbuf->r.buf + imsgbuf->r.wpos;
- iov.iov_len = sizeof(imsgbuf->r.buf) - imsgbuf->r.wpos;
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_control = &cmsgbuf.buf;
- msg.msg_controllen = sizeof(cmsgbuf.buf);
-
- if ((ifd = calloc(1, sizeof(struct imsg_fd))) == NULL)
- return (-1);
-
-again:
- if ((n = recvmsg(imsgbuf->fd, &msg, 0)) == -1) {
- if (errno == EINTR)
- goto again;
- if (errno == EMSGSIZE)
- /*
- * Not enough fd slots: fd passing failed, retry
- * to receive the message without fd.
- * imsg_get_fd() will return -1 in that case.
- */
- goto again;
- if (errno == EAGAIN) {
- free(ifd);
- return (1);
- }
- goto fail;
- }
-
- if (n == 0) { /* connection closed */
- free(ifd);
- return (0);
- }
-
- imsgbuf->r.wpos += n;
-
- for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
- cmsg = CMSG_NXTHDR(&msg, cmsg)) {
- if (cmsg->cmsg_level == SOL_SOCKET &&
- cmsg->cmsg_type == SCM_RIGHTS) {
- int i;
- int j;
-
- /*
- * We only accept one file descriptor. Due to C
- * padding rules, our control buffer might contain
- * more than one fd, and we must close them.
- */
- j = ((char *)cmsg + cmsg->cmsg_len -
- (char *)CMSG_DATA(cmsg)) / sizeof(int);
- for (i = 0; i < j; i++) {
- fd = ((int *)CMSG_DATA(cmsg))[i];
- if (ifd != NULL) {
- ifd->fd = fd;
- TAILQ_INSERT_TAIL(&imsgbuf->fds, ifd,
- entry);
- ifd = NULL;
- } else
- close(fd);
- }
- }
- /* we do not handle other ctl data level */
- }
+ imsgbuf->flags |= IMSG_ALLOW_FDPASS;
+}
- free(ifd);
- return (1);
+void
+imsgbuf_set_maxsize(struct imsgbuf *imsgbuf, uint32_t maxsize)
+{
+ if (maxsize < IMSG_HEADER_SIZE)
+ return;
+ imsgbuf->maxsize = maxsize;
+}
-fail:
- free(ifd);
- return (-1);
+int
+imsgbuf_read(struct imsgbuf *imsgbuf)
+{
+ if (imsgbuf->flags & IMSG_ALLOW_FDPASS)
+ return msgbuf_read(imsgbuf->fd, imsgbuf->w);
+ else
+ return ibuf_read(imsgbuf->fd, imsgbuf->w);
}
int
imsgbuf_write(struct imsgbuf *imsgbuf)
{
- return msgbuf_write(imsgbuf->fd, imsgbuf->w);
+ if (imsgbuf->flags & IMSG_ALLOW_FDPASS)
+ return msgbuf_write(imsgbuf->fd, imsgbuf->w);
+ else
+ return ibuf_write(imsgbuf->fd, imsgbuf->w);
}
int
@@ -153,13 +92,8 @@ imsgbuf_flush(struct imsgbuf *imsgbuf)
void
imsgbuf_clear(struct imsgbuf *imsgbuf)
{
- int fd;
-
- msgbuf_clear(imsgbuf->w);
msgbuf_free(imsgbuf->w);
imsgbuf->w = NULL;
- while ((fd = imsg_dequeue_fd(imsgbuf)) != -1)
- close(fd);
}
uint32_t
@@ -172,56 +106,28 @@ ssize_t
imsg_get(struct imsgbuf *imsgbuf, struct imsg *imsg)
{
struct imsg m;
- size_t av, left, datalen;
-
- av = imsgbuf->r.wpos;
+ struct ibuf *buf;
- if (IMSG_HEADER_SIZE > av)
+ if ((buf = msgbuf_get(imsgbuf->w)) == NULL)
return (0);
- memcpy(&m.hdr, imsgbuf->r.buf, sizeof(m.hdr));
- if (m.hdr.len < IMSG_HEADER_SIZE ||
- m.hdr.len > MAX_IMSGSIZE) {
- errno = ERANGE;
+ if (ibuf_get(buf, &m.hdr, sizeof(m.hdr)) == -1)
return (-1);
- }
- if (m.hdr.len > av)
- return (0);
-
- m.data = NULL;
- datalen = m.hdr.len - IMSG_HEADER_SIZE;
- imsgbuf->r.rptr = imsgbuf->r.buf + IMSG_HEADER_SIZE;
-
- if ((m.buf = ibuf_open(datalen)) == NULL)
- return (-1);
- if (datalen != 0) {
- if (ibuf_add(m.buf, imsgbuf->r.rptr, datalen) == -1) {
- /* this should never fail */
- ibuf_free(m.buf);
- return (-1);
- }
- m.data = ibuf_data(m.buf);
- }
-
- if (m.hdr.flags & IMSGF_HASFD)
- ibuf_fd_set(m.buf, imsg_dequeue_fd(imsgbuf));
-
- if (m.hdr.len < av) {
- left = av - m.hdr.len;
- memmove(&imsgbuf->r.buf, imsgbuf->r.buf + m.hdr.len, left);
- imsgbuf->r.wpos = left;
- } else
- imsgbuf->r.wpos = 0;
+ if (ibuf_size(buf))
+ m.data = ibuf_data(buf);
+ else
+ m.data = NULL;
+ m.buf = buf;
*imsg = m;
- return (datalen + IMSG_HEADER_SIZE);
+ return (ibuf_size(buf) + IMSG_HEADER_SIZE);
}
int
imsg_get_ibuf(struct imsg *imsg, struct ibuf *ibuf)
{
- if (imsg->buf == NULL) {
+ if (ibuf_size(imsg->buf) == 0) {
errno = EBADMSG;
return (-1);
}
@@ -235,7 +141,7 @@ imsg_get_data(struct imsg *imsg, void *data, size_t len)
errno = EINVAL;
return (-1);
}
- if (imsg->buf == NULL || ibuf_size(imsg->buf) != len) {
+ if (ibuf_size(imsg->buf) != len) {
errno = EBADMSG;
return (-1);
}
@@ -257,8 +163,6 @@ imsg_get_id(struct imsg *imsg)
size_t
imsg_get_len(struct imsg *imsg)
{
- if (imsg->buf == NULL)
- return 0;
return ibuf_size(imsg->buf);
}
@@ -328,14 +232,13 @@ imsg_compose_ibuf(struct imsgbuf *imsgbuf, uint32_t type, uint32_t id,
struct imsg_hdr hdr;
int save_errno;
- if (ibuf_size(buf) + IMSG_HEADER_SIZE > MAX_IMSGSIZE) {
+ if (ibuf_size(buf) + IMSG_HEADER_SIZE > imsgbuf->maxsize) {
errno = ERANGE;
goto fail;
}
hdr.type = type;
hdr.len = ibuf_size(buf) + IMSG_HEADER_SIZE;
- hdr.flags = 0;
hdr.peerid = id;
if ((hdr.pid = pid) == 0)
hdr.pid = imsgbuf->pid;
@@ -366,10 +269,9 @@ imsg_forward(struct imsgbuf *imsgbuf, struct imsg *msg)
struct ibuf *wbuf;
size_t len = 0;
- if (msg->buf != NULL) {
- ibuf_rewind(msg->buf);
- len = ibuf_size(msg->buf);
- }
+ ibuf_rewind(msg->buf);
+ ibuf_skip(msg->buf, sizeof(msg->hdr));
+ len = ibuf_size(msg->buf);
if ((wbuf = imsg_create(imsgbuf, msg->hdr.type, msg->hdr.peerid,
msg->hdr.pid, len)) == NULL)
@@ -394,17 +296,16 @@ imsg_create(struct imsgbuf *imsgbuf, uint32_t type, uint32_t id, pid_t pid,
struct imsg_hdr hdr;
datalen += IMSG_HEADER_SIZE;
- if (datalen > MAX_IMSGSIZE) {
+ if (datalen > imsgbuf->maxsize) {
errno = ERANGE;
return (NULL);
}
hdr.type = type;
- hdr.flags = 0;
hdr.peerid = id;
if ((hdr.pid = pid) == 0)
hdr.pid = imsgbuf->pid;
- if ((wbuf = ibuf_dynamic(datalen, MAX_IMSGSIZE)) == NULL) {
+ if ((wbuf = ibuf_dynamic(datalen, imsgbuf->maxsize)) == NULL) {
return (NULL);
}
if (imsg_add(wbuf, &hdr, sizeof(hdr)) == -1)
@@ -430,12 +331,7 @@ imsg_close(struct imsgbuf *imsgbuf, struct ibuf *msg)
struct imsg_hdr *hdr;
hdr = (struct imsg_hdr *)msg->buf;
-
- hdr->flags &= ~IMSGF_HASFD;
- if (ibuf_fd_avail(msg))
- hdr->flags |= IMSGF_HASFD;
hdr->len = ibuf_size(msg);
-
ibuf_close(imsgbuf->w, msg);
}
@@ -445,18 +341,18 @@ imsg_free(struct imsg *imsg)
ibuf_free(imsg->buf);
}
-static int
-imsg_dequeue_fd(struct imsgbuf *imsgbuf)
+static ssize_t
+imsg_parse_hdr(struct ibuf *buf, void *arg)
{
- int fd;
- struct imsg_fd *ifd;
+ struct imsgbuf *imsgbuf = arg;
+ struct imsg_hdr hdr;
- if ((ifd = TAILQ_FIRST(&imsgbuf->fds)) == NULL)
+ if (ibuf_get(buf, &hdr, sizeof(hdr)) == -1)
+ return -1;
+ if (hdr.len < IMSG_HEADER_SIZE ||
+ hdr.len > imsgbuf->maxsize) {
+ errno = ERANGE;
return (-1);
-
- fd = ifd->fd;
- TAILQ_REMOVE(&imsgbuf->fds, ifd, entry);
- free(ifd);
-
- return (fd);
+ }
+ return hdr.len;
}
diff --git a/lib/libutil/imsg.h b/lib/libutil/imsg.h
index 995c3666206..8d78beb34eb 100644
--- a/lib/libutil/imsg.h
+++ b/lib/libutil/imsg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: imsg.h,v 1.17 2024/11/21 13:01:07 claudio Exp $ */
+/* $OpenBSD: imsg.h,v 1.18 2024/11/21 13:03:21 claudio Exp $ */
/*
* Copyright (c) 2023 Claudio Jeker <claudio@openbsd.org>
@@ -38,29 +38,19 @@ struct ibuf {
int fd;
};
-struct ibuf_read {
- unsigned char buf[IBUF_READ_SIZE];
- unsigned char *rptr;
- size_t wpos;
-};
-
struct msgbuf;
-struct imsg_fd;
struct imsgbuf {
- TAILQ_HEAD(, imsg_fd) fds;
- struct ibuf_read r;
struct msgbuf *w;
- int fd;
pid_t pid;
+ uint32_t maxsize;
+ int fd;
+ int flags;
};
-#define IMSGF_HASFD 1
-
struct imsg_hdr {
uint32_t type;
- uint16_t len;
- uint16_t flags;
+ uint32_t len;
uint32_t peerid;
uint32_t pid;
};
@@ -120,14 +110,21 @@ int ibuf_fd_avail(struct ibuf *);
int ibuf_fd_get(struct ibuf *);
void ibuf_fd_set(struct ibuf *, int);
struct msgbuf *msgbuf_new(void);
+struct msgbuf *msgbuf_new_reader(size_t, ssize_t (*)(struct ibuf *, void *),
+ void *);
void msgbuf_free(struct msgbuf *);
void msgbuf_clear(struct msgbuf *);
uint32_t msgbuf_queuelen(struct msgbuf *);
int ibuf_write(int, struct msgbuf *);
int msgbuf_write(int, struct msgbuf *);
+int ibuf_read(int, struct msgbuf *);
+int msgbuf_read(int, struct msgbuf *);
+struct ibuf *msgbuf_get(struct msgbuf *);
/* imsg.c */
-void imsgbuf_init(struct imsgbuf *, int);
+int imsgbuf_init(struct imsgbuf *, int);
+void imsgbuf_allow_fdpass(struct imsgbuf *imsgbuf);
+void imsgbuf_set_maxsize(struct imsgbuf *, uint32_t);
int imsgbuf_read(struct imsgbuf *);
int imsgbuf_write(struct imsgbuf *);
int imsgbuf_flush(struct imsgbuf *);