summaryrefslogtreecommitdiff
path: root/devel/got/files/openbsd-compat/imsg-buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'devel/got/files/openbsd-compat/imsg-buffer.c')
-rw-r--r--devel/got/files/openbsd-compat/imsg-buffer.c264
1 files changed, 235 insertions, 29 deletions
diff --git a/devel/got/files/openbsd-compat/imsg-buffer.c b/devel/got/files/openbsd-compat/imsg-buffer.c
index 8bac2a0531ae..5c874fc56002 100644
--- a/devel/got/files/openbsd-compat/imsg-buffer.c
+++ b/devel/got/files/openbsd-compat/imsg-buffer.c
@@ -1,6 +1,7 @@
-/* $OpenBSD: imsg-buffer.c,v 1.16 2023/06/19 17:19:50 claudio Exp $ */
+/* $OpenBSD: imsg-buffer.c,v 1.18 2023/12/12 15:47:41 claudio Exp $ */
/*
+ * Copyright (c) 2023 Claudio Jeker <claudio@openbsd.org>
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -24,6 +25,7 @@
#include <limits.h>
#include <errno.h>
#include <endian.h>
+#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -63,7 +65,7 @@ ibuf_dynamic(size_t len, size_t max)
{
struct ibuf *buf;
- if (max < len) {
+ if (max == 0 || max < len) {
errno = EINVAL;
return (NULL);
}
@@ -108,7 +110,7 @@ ibuf_reserve(struct ibuf *buf, size_t len)
{
void *b;
- if (len > SIZE_MAX - buf->wpos) {
+ if (len > SIZE_MAX - buf->wpos || buf->max == 0) {
errno = ERANGE;
return (NULL);
}
@@ -119,7 +121,6 @@ ibuf_reserve(struct ibuf *buf, size_t len)
b = buf->buf + buf->wpos;
buf->wpos += len;
- memset(b, 0, len);
return (b);
}
@@ -136,9 +137,16 @@ ibuf_add(struct ibuf *buf, const void *data, size_t len)
}
int
+ibuf_add_ibuf(struct ibuf *buf, const struct ibuf *from)
+{
+ return ibuf_add(buf, ibuf_data(from), ibuf_size(from));
+}
+
+/* remove after tree is converted */
+int
ibuf_add_buf(struct ibuf *buf, const struct ibuf *from)
{
- return ibuf_add(buf, from->buf, from->wpos);
+ return ibuf_add_ibuf(buf, from);
}
int
@@ -188,25 +196,59 @@ ibuf_add_n64(struct ibuf *buf, uint64_t value)
}
int
+ibuf_add_h16(struct ibuf *buf, uint64_t value)
+{
+ uint16_t v;
+
+ if (value > UINT16_MAX) {
+ errno = EINVAL;
+ return (-1);
+ }
+ v = value;
+ return ibuf_add(buf, &v, sizeof(v));
+}
+
+int
+ibuf_add_h32(struct ibuf *buf, uint64_t value)
+{
+ uint32_t v;
+
+ if (value > UINT32_MAX) {
+ errno = EINVAL;
+ return (-1);
+ }
+ v = value;
+ return ibuf_add(buf, &v, sizeof(v));
+}
+
+int
+ibuf_add_h64(struct ibuf *buf, uint64_t value)
+{
+ return ibuf_add(buf, &value, sizeof(value));
+}
+
+int
ibuf_add_zero(struct ibuf *buf, size_t len)
{
void *b;
if ((b = ibuf_reserve(buf, len)) == NULL)
return (-1);
+ memset(b, 0, len);
return (0);
}
void *
ibuf_seek(struct ibuf *buf, size_t pos, size_t len)
{
- /* only allowed to seek in already written parts */
- if (len > SIZE_MAX - pos || pos + len > buf->wpos) {
+ /* only allow seeking between rpos and wpos */
+ if (ibuf_size(buf) < pos || SIZE_MAX - pos < len ||
+ ibuf_size(buf) < pos + len) {
errno = ERANGE;
return (NULL);
}
- return (buf->buf + pos);
+ return (buf->buf + buf->rpos + pos);
}
int
@@ -267,24 +309,79 @@ ibuf_set_n64(struct ibuf *buf, size_t pos, uint64_t value)
return (ibuf_set(buf, pos, &value, sizeof(value)));
}
+int
+ibuf_set_h16(struct ibuf *buf, size_t pos, uint64_t value)
+{
+ uint16_t v;
+
+ if (value > UINT16_MAX) {
+ errno = EINVAL;
+ return (-1);
+ }
+ v = value;
+ return (ibuf_set(buf, pos, &v, sizeof(v)));
+}
+
+int
+ibuf_set_h32(struct ibuf *buf, size_t pos, uint64_t value)
+{
+ uint32_t v;
+
+ if (value > UINT32_MAX) {
+ errno = EINVAL;
+ return (-1);
+ }
+ v = value;
+ return (ibuf_set(buf, pos, &v, sizeof(v)));
+}
+
+int
+ibuf_set_h64(struct ibuf *buf, size_t pos, uint64_t value)
+{
+ return (ibuf_set(buf, pos, &value, sizeof(value)));
+}
+
void *
-ibuf_data(struct ibuf *buf)
+ibuf_data(const struct ibuf *buf)
{
- return (buf->buf);
+ return (buf->buf + buf->rpos);
}
size_t
-ibuf_size(struct ibuf *buf)
+ibuf_size(const struct ibuf *buf)
{
- return (buf->wpos);
+ return (buf->wpos - buf->rpos);
}
size_t
-ibuf_left(struct ibuf *buf)
+ibuf_left(const struct ibuf *buf)
{
+ if (buf->max == 0)
+ return (0);
return (buf->max - buf->wpos);
}
+int
+ibuf_truncate(struct ibuf *buf, size_t len)
+{
+ if (ibuf_size(buf) >= len) {
+ buf->wpos = buf->rpos + len;
+ return (0);
+ }
+ if (buf->max == 0) {
+ /* only allow to truncate down */
+ errno = ERANGE;
+ return (-1);
+ }
+ return ibuf_add_zero(buf, len - ibuf_size(buf));
+}
+
+void
+ibuf_rewind(struct ibuf *buf)
+{
+ buf->rpos = 0;
+}
+
void
ibuf_close(struct msgbuf *msgbuf, struct ibuf *buf)
{
@@ -292,14 +389,121 @@ ibuf_close(struct msgbuf *msgbuf, struct ibuf *buf)
}
void
+ibuf_from_buffer(struct ibuf *buf, void *data, size_t len)
+{
+ memset(buf, 0, sizeof(*buf));
+ buf->buf = data;
+ buf->size = buf->wpos = len;
+ buf->fd = -1;
+}
+
+void
+ibuf_from_ibuf(struct ibuf *buf, const struct ibuf *from)
+{
+ ibuf_from_buffer(buf, ibuf_data(from), ibuf_size(from));
+}
+
+int
+ibuf_get(struct ibuf *buf, void *data, size_t len)
+{
+ if (ibuf_size(buf) < len) {
+ errno = EBADMSG;
+ return (-1);
+ }
+
+ memcpy(data, ibuf_data(buf), len);
+ buf->rpos += len;
+ return (0);
+}
+
+int
+ibuf_get_ibuf(struct ibuf *buf, size_t len, struct ibuf *new)
+{
+ if (ibuf_size(buf) < len) {
+ errno = EBADMSG;
+ return (-1);
+ }
+
+ ibuf_from_buffer(new, ibuf_data(buf), len);
+ buf->rpos += len;
+ return (0);
+}
+
+int
+ibuf_get_n8(struct ibuf *buf, uint8_t *value)
+{
+ return ibuf_get(buf, value, sizeof(*value));
+}
+
+int
+ibuf_get_n16(struct ibuf *buf, uint16_t *value)
+{
+ int rv;
+
+ rv = ibuf_get(buf, value, sizeof(*value));
+ *value = be16toh(*value);
+ return (rv);
+}
+
+int
+ibuf_get_n32(struct ibuf *buf, uint32_t *value)
+{
+ int rv;
+
+ rv = ibuf_get(buf, value, sizeof(*value));
+ *value = be32toh(*value);
+ return (rv);
+}
+
+int
+ibuf_get_n64(struct ibuf *buf, uint64_t *value)
+{
+ int rv;
+
+ rv = ibuf_get(buf, value, sizeof(*value));
+ *value = be64toh(*value);
+ return (rv);
+}
+
+int
+ibuf_get_h16(struct ibuf *buf, uint16_t *value)
+{
+ return ibuf_get(buf, value, sizeof(*value));
+}
+
+int
+ibuf_get_h32(struct ibuf *buf, uint32_t *value)
+{
+ return ibuf_get(buf, value, sizeof(*value));
+}
+
+int
+ibuf_get_h64(struct ibuf *buf, uint64_t *value)
+{
+ return ibuf_get(buf, value, sizeof(*value));
+}
+
+int
+ibuf_skip(struct ibuf *buf, size_t len)
+{
+ if (ibuf_size(buf) < len) {
+ errno = EBADMSG;
+ return (-1);
+ }
+
+ buf->rpos += len;
+ return (0);
+}
+
+void
ibuf_free(struct ibuf *buf)
{
if (buf == NULL)
return;
-#ifdef NOTYET
+ if (buf->max == 0) /* if buf lives on the stack */
+ abort(); /* abort before causing more harm */
if (buf->fd != -1)
close(buf->fd);
-#endif
freezero(buf->buf, buf->size);
free(buf);
}
@@ -316,15 +520,15 @@ ibuf_fd_get(struct ibuf *buf)
int fd;
fd = buf->fd;
-#ifdef NOTYET
buf->fd = -1;
-#endif
return (fd);
}
void
ibuf_fd_set(struct ibuf *buf, int fd)
{
+ if (buf->max == 0) /* if buf lives on the stack */
+ abort(); /* abort before causing more harm */
if (buf->fd != -1)
close(buf->fd);
buf->fd = fd;
@@ -342,8 +546,8 @@ ibuf_write(struct msgbuf *msgbuf)
TAILQ_FOREACH(buf, &msgbuf->bufs, entry) {
if (i >= IOV_MAX)
break;
- iov[i].iov_base = buf->buf + buf->rpos;
- iov[i].iov_len = buf->wpos - buf->rpos;
+ iov[i].iov_base = ibuf_data(buf);
+ iov[i].iov_len = ibuf_size(buf);
i++;
}
@@ -382,8 +586,8 @@ msgbuf_drain(struct msgbuf *msgbuf, size_t n)
for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0;
buf = next) {
next = TAILQ_NEXT(buf, entry);
- if (n >= buf->wpos - buf->rpos) {
- n -= buf->wpos - buf->rpos;
+ if (n >= ibuf_size(buf)) {
+ n -= ibuf_size(buf);
ibuf_dequeue(msgbuf, buf);
} else {
buf->rpos += n;
@@ -423,8 +627,8 @@ msgbuf_write(struct msgbuf *msgbuf)
break;
if (i > 0 && buf->fd != -1)
break;
- iov[i].iov_base = buf->buf + buf->rpos;
- iov[i].iov_len = buf->wpos - buf->rpos;
+ iov[i].iov_base = ibuf_data(buf);
+ iov[i].iov_len = ibuf_size(buf);
i++;
if (buf->fd != -1)
buf0 = buf;
@@ -471,9 +675,17 @@ again:
return (1);
}
+uint32_t
+msgbuf_queuelen(struct msgbuf *msgbuf)
+{
+ return (msgbuf->queued);
+}
+
static void
ibuf_enqueue(struct msgbuf *msgbuf, struct ibuf *buf)
{
+ if (buf->max == 0) /* if buf lives on the stack */
+ abort(); /* abort before causing more harm */
TAILQ_INSERT_TAIL(&msgbuf->bufs, buf, entry);
msgbuf->queued++;
}
@@ -482,12 +694,6 @@ static void
ibuf_dequeue(struct msgbuf *msgbuf, struct ibuf *buf)
{
TAILQ_REMOVE(&msgbuf->bufs, buf, entry);
-
- if (buf->fd != -1) {
- close(buf->fd);
- buf->fd = -1;
- }
-
msgbuf->queued--;
ibuf_free(buf);
}