commit - eaecb958183f6eb4fdb79b3258d465a4fd8cb72e
commit + 278c2ee8f22638aca522d05826589261d36409b8
blob - eac3e6ce0d139fe8d66e270264e48b4d3230572f
blob + fc8ef7dbd7609263755a10aec3f4dfb6ab8d94fb
--- compat/imsg-buffer.c
+++ compat/imsg-buffer.c
-/* $OpenBSD: imsg-buffer.c,v 1.28 2024/11/21 13:03:21 claudio Exp $ */
+/* $OpenBSD: imsg-buffer.c,v 1.31 2024/11/26 13:57:31 claudio Exp $ */
/*
* Copyright (c) 2023 Claudio Jeker <claudio@openbsd.org>
uint32_t queued;
char *rbuf;
struct ibuf *rpmsg;
- ssize_t (*readhdr)(struct ibuf *, void *);
+ struct ibuf *(*readhdr)(struct ibuf *, void *, int *);
void *rarg;
size_t roff;
size_t hdrsize;
}
struct msgbuf *
-msgbuf_new_reader(size_t hdrsz, ssize_t (*readhdr)(struct ibuf *, void *),
- void *arg)
+msgbuf_new_reader(size_t hdrsz,
+ struct ibuf *(*readhdr)(struct ibuf *, void *, int *), void *arg)
{
struct msgbuf *msgbuf;
char *buf;
void
msgbuf_free(struct msgbuf *msgbuf)
{
- if (msgbuf != NULL)
- msgbuf_clear(msgbuf);
+ if (msgbuf == NULL)
+ return;
+ msgbuf_clear(msgbuf);
free(msgbuf->rbuf);
free(msgbuf);
}
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;
- }
+ if (ibuf_size(&rbuf) < msgbuf->hdrsize)
break;
- }
/* get size from header */
ibuf_from_buffer(&msg, ibuf_data(&rbuf),
msgbuf->hdrsize);
- sz = msgbuf->readhdr(&msg, msgbuf->rarg);
- if (sz == -1)
+ if ((msgbuf->rpmsg = msgbuf->readhdr(&msg,
+ msgbuf->rarg, &fd)) == NULL)
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))
memmove(msgbuf->rbuf, ibuf_data(&rbuf), ibuf_size(&rbuf));
msgbuf->roff = ibuf_size(&rbuf);
+ if (fd != -1)
+ close(fd);
return (1);
fail:
- /* XXX cleanup */
+ /* XXX how to properly clean up is unclear */
+ if (fd != -1)
+ close(fd);
return (-1);
}
blob - ef796315dfbe8543a11eeff1b38a8d2b185ce7d3
blob + 89ac7fa4313e8d70079d81cc0f19f2ae2d8a02c3
--- compat/imsg.c
+++ compat/imsg.c
-/* $OpenBSD: imsg.c,v 1.36 2024/11/21 13:03:21 claudio Exp $ */
+/* $OpenBSD: imsg.c,v 1.37 2024/11/26 13:57:31 claudio Exp $ */
/*
* Copyright (c) 2023 Claudio Jeker <claudio@openbsd.org>
#include <sys/uio.h>
#include <errno.h>
+#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "imsg.h"
#define IMSG_ALLOW_FDPASS 0x01
+#define IMSG_FD_MARK 0x80000000U
-static ssize_t imsg_parse_hdr(struct ibuf *, void *);
+static struct ibuf *imsg_parse_hdr(struct ibuf *, void *, int *);
int
imsgbuf_init(struct imsgbuf *imsgbuf, int fd)
imsgbuf->flags |= IMSG_ALLOW_FDPASS;
}
-void
+int
imsgbuf_set_maxsize(struct imsgbuf *imsgbuf, uint32_t maxsize)
{
- if (maxsize < IMSG_HEADER_SIZE)
- return;
+ if (maxsize < IMSG_HEADER_SIZE || maxsize & IMSG_FD_MARK) {
+ errno = EINVAL;
+ return (-1);
+ }
imsgbuf->maxsize = maxsize;
+ return (0);
}
int
else
m.data = NULL;
m.buf = buf;
+ m.hdr.len &= ~IMSG_FD_MARK;
*imsg = m;
return (ibuf_size(buf) + IMSG_HEADER_SIZE);
imsg_forward(struct imsgbuf *imsgbuf, struct imsg *msg)
{
struct ibuf *wbuf;
- size_t len = 0;
+ size_t len;
ibuf_rewind(msg->buf);
ibuf_skip(msg->buf, sizeof(msg->hdr));
msg->hdr.pid, len)) == NULL)
return (-1);
- if (msg->buf != NULL) {
+ if (len != 0) {
if (ibuf_add_ibuf(wbuf, msg->buf) == -1) {
ibuf_free(wbuf);
return (-1);
imsg_close(struct imsgbuf *imsgbuf, struct ibuf *msg)
{
struct imsg_hdr *hdr;
+ uint32_t len;
- hdr = (struct imsg_hdr *)msg->buf;
- hdr->len = ibuf_size(msg);
+ len = ibuf_size(msg);
+ if (ibuf_fd_avail(msg))
+ len |= IMSG_FD_MARK;
+ (void)ibuf_set_h32(msg, offsetof(struct imsg_hdr, len), len);
ibuf_close(imsgbuf->w, msg);
}
ibuf_free(imsg->buf);
}
-static ssize_t
-imsg_parse_hdr(struct ibuf *buf, void *arg)
+static struct ibuf *
+imsg_parse_hdr(struct ibuf *buf, void *arg, int *fd)
{
struct imsgbuf *imsgbuf = arg;
struct imsg_hdr hdr;
+ struct ibuf *b;
+ uint32_t len;
if (ibuf_get(buf, &hdr, sizeof(hdr)) == -1)
- return -1;
- if (hdr.len < IMSG_HEADER_SIZE ||
- hdr.len > imsgbuf->maxsize) {
+ return (NULL);
+
+ len = hdr.len & ~IMSG_FD_MARK;
+
+ if (len < IMSG_HEADER_SIZE || len > imsgbuf->maxsize) {
errno = ERANGE;
- return (-1);
+ return (NULL);
}
- return hdr.len;
+ if ((b = ibuf_open(len)) == NULL)
+ return (NULL);
+ if (hdr.len & IMSG_FD_MARK) {
+ ibuf_fd_set(b, *fd);
+ *fd = -1;
+ }
+
+ return b;
}
blob - 8d78beb34ebecd8de026b31a3ac9e60c0f31edec
blob + 462bfc97ffccdfc7bc6deae66c8b185c4ae1621d
--- compat/imsg.h
+++ compat/imsg.h
-/* $OpenBSD: imsg.h,v 1.18 2024/11/21 13:03:21 claudio Exp $ */
+/* $OpenBSD: imsg.h,v 1.19 2024/11/26 13:57:31 claudio Exp $ */
/*
* Copyright (c) 2023 Claudio Jeker <claudio@openbsd.org>
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 *);
+struct msgbuf *msgbuf_new_reader(size_t,
+ struct ibuf *(*)(struct ibuf *, void *, int *), void *);
void msgbuf_free(struct msgbuf *);
void msgbuf_clear(struct msgbuf *);
uint32_t msgbuf_queuelen(struct msgbuf *);
/* imsg.c */
int imsgbuf_init(struct imsgbuf *, int);
void imsgbuf_allow_fdpass(struct imsgbuf *imsgbuf);
-void imsgbuf_set_maxsize(struct imsgbuf *, uint32_t);
+int imsgbuf_set_maxsize(struct imsgbuf *, uint32_t);
int imsgbuf_read(struct imsgbuf *);
int imsgbuf_write(struct imsgbuf *);
int imsgbuf_flush(struct imsgbuf *);