getptmfd;
getrawpartition;
ibuf_add;
+ ibuf_add_buf;
+ ibuf_add_n8;
+ ibuf_add_n16;
+ ibuf_add_n32;
+ ibuf_add_n64;
+ ibuf_add_zero;
ibuf_close;
+ ibuf_data;
ibuf_dynamic;
+ ibuf_fd_avail;
+ ibuf_fd_get;
+ ibuf_fd_set;
ibuf_free;
ibuf_left;
ibuf_open;
ibuf_reserve;
ibuf_seek;
+ ibuf_set;
+ ibuf_set_n8;
+ ibuf_set_n16;
+ ibuf_set_n32;
+ ibuf_set_n64;
ibuf_size;
ibuf_write;
imsg_add;
imsg_close;
imsg_compose;
imsg_composev;
+ imsg_compose_ibuf;
imsg_create;
imsg_fd_overhead;
imsg_flush;
logout;
logwtmp;
msgbuf_clear;
- msgbuf_drain;
msgbuf_init;
msgbuf_write;
ober_add_bitstring;
-/* $OpenBSD: imsg-buffer.c,v 1.15 2023/05/23 12:41:28 claudio Exp $ */
+/* $OpenBSD: imsg-buffer.c,v 1.16 2023/06/19 17:19:50 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
#include <limits.h>
#include <errno.h>
+#include <endian.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static int ibuf_realloc(struct ibuf *, size_t);
static void ibuf_enqueue(struct msgbuf *, struct ibuf *);
static void ibuf_dequeue(struct msgbuf *, struct ibuf *);
+static void msgbuf_drain(struct msgbuf *, size_t);
struct ibuf *
ibuf_open(size_t len)
return (0);
}
-int
-ibuf_add(struct ibuf *buf, const void *data, size_t len)
-{
- if (len > SIZE_MAX - buf->wpos) {
- errno = ERANGE;
- return (-1);
- }
-
- if (buf->wpos + len > buf->size)
- if (ibuf_realloc(buf, len) == -1)
- return (-1);
-
- memcpy(buf->buf + buf->wpos, data, len);
- buf->wpos += len;
- return (0);
-}
-
void *
ibuf_reserve(struct ibuf *buf, size_t len)
{
return (b);
}
+int
+ibuf_add(struct ibuf *buf, const void *data, size_t len)
+{
+ void *b;
+
+ if ((b = ibuf_reserve(buf, len)) == NULL)
+ return (-1);
+
+ memcpy(b, data, len);
+ return (0);
+}
+
+int
+ibuf_add_buf(struct ibuf *buf, const struct ibuf *from)
+{
+ return ibuf_add(buf, from->buf, from->wpos);
+}
+
+int
+ibuf_add_n8(struct ibuf *buf, uint64_t value)
+{
+ uint8_t v;
+
+ if (value > UINT8_MAX) {
+ errno = EINVAL;
+ return (-1);
+ }
+ v = value;
+ return ibuf_add(buf, &v, sizeof(v));
+}
+
+int
+ibuf_add_n16(struct ibuf *buf, uint64_t value)
+{
+ uint16_t v;
+
+ if (value > UINT16_MAX) {
+ errno = EINVAL;
+ return (-1);
+ }
+ v = htobe16(value);
+ return ibuf_add(buf, &v, sizeof(v));
+}
+
+int
+ibuf_add_n32(struct ibuf *buf, uint64_t value)
+{
+ uint32_t v;
+
+ if (value > UINT32_MAX) {
+ errno = EINVAL;
+ return (-1);
+ }
+ v = htobe32(value);
+ return ibuf_add(buf, &v, sizeof(v));
+}
+
+int
+ibuf_add_n64(struct ibuf *buf, uint64_t value)
+{
+ value = htobe64(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);
+ 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)
+ if (len > SIZE_MAX - pos || pos + len > buf->wpos) {
+ errno = ERANGE;
return (NULL);
+ }
return (buf->buf + pos);
}
+int
+ibuf_set(struct ibuf *buf, size_t pos, const void *data, size_t len)
+{
+ void *b;
+
+ if ((b = ibuf_seek(buf, pos, len)) == NULL)
+ return (-1);
+
+ memcpy(b, data, len);
+ return (0);
+}
+
+int
+ibuf_set_n8(struct ibuf *buf, size_t pos, uint64_t value)
+{
+ uint8_t v;
+
+ if (value > UINT8_MAX) {
+ errno = EINVAL;
+ return (-1);
+ }
+ v = value;
+ return (ibuf_set(buf, pos, &v, sizeof(v)));
+}
+
+int
+ibuf_set_n16(struct ibuf *buf, size_t pos, uint64_t value)
+{
+ uint16_t v;
+
+ if (value > UINT16_MAX) {
+ errno = EINVAL;
+ return (-1);
+ }
+ v = htobe16(value);
+ return (ibuf_set(buf, pos, &v, sizeof(v)));
+}
+
+int
+ibuf_set_n32(struct ibuf *buf, size_t pos, uint64_t value)
+{
+ uint32_t v;
+
+ if (value > UINT32_MAX) {
+ errno = EINVAL;
+ return (-1);
+ }
+ v = htobe32(value);
+ return (ibuf_set(buf, pos, &v, sizeof(v)));
+}
+
+int
+ibuf_set_n64(struct ibuf *buf, size_t pos, uint64_t value)
+{
+ value = htobe64(value);
+ return (ibuf_set(buf, pos, &value, sizeof(value)));
+}
+
+void *
+ibuf_data(struct ibuf *buf)
+{
+ return (buf->buf);
+}
+
size_t
ibuf_size(struct ibuf *buf)
{
ibuf_enqueue(msgbuf, buf);
}
+void
+ibuf_free(struct ibuf *buf)
+{
+ if (buf == NULL)
+ return;
+#ifdef NOTYET
+ if (buf->fd != -1)
+ close(buf->fd);
+#endif
+ freezero(buf->buf, buf->size);
+ free(buf);
+}
+
+int
+ibuf_fd_avail(struct ibuf *buf)
+{
+ return (buf->fd != -1);
+}
+
+int
+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->fd != -1)
+ close(buf->fd);
+ buf->fd = fd;
+}
+
int
ibuf_write(struct msgbuf *msgbuf)
{
return (1);
}
-void
-ibuf_free(struct ibuf *buf)
-{
- if (buf == NULL)
- return;
- freezero(buf->buf, buf->size);
- free(buf);
-}
-
void
msgbuf_init(struct msgbuf *msgbuf)
{
TAILQ_INIT(&msgbuf->bufs);
}
-void
+static void
msgbuf_drain(struct msgbuf *msgbuf, size_t n)
{
struct ibuf *buf, *next;
{
TAILQ_REMOVE(&msgbuf->bufs, buf, entry);
- if (buf->fd != -1)
+ if (buf->fd != -1) {
close(buf->fd);
+ buf->fd = -1;
+ }
msgbuf->queued--;
ibuf_free(buf);
-/* $OpenBSD: imsg.c,v 1.18 2023/03/08 04:43:05 guenther Exp $ */
+/* $OpenBSD: imsg.c,v 1.19 2023/06/19 17:19:50 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
if (imsg_add(wbuf, data, datalen) == -1)
return (-1);
- wbuf->fd = fd;
-
+ ibuf_fd_set(wbuf, fd);
imsg_close(ibuf, wbuf);
return (1);
if (imsg_add(wbuf, iov[i].iov_base, iov[i].iov_len) == -1)
return (-1);
- wbuf->fd = fd;
-
+ ibuf_fd_set(wbuf, fd);
imsg_close(ibuf, wbuf);
return (1);
}
+int
+imsg_compose_ibuf(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid,
+ pid_t pid, struct ibuf *buf)
+{
+ struct ibuf *wbuf = NULL;
+ struct imsg_hdr hdr;
+ int save_errno;
+
+ if (ibuf_size(buf) + IMSG_HEADER_SIZE > MAX_IMSGSIZE) {
+ errno = ERANGE;
+ goto fail;
+ }
+
+ hdr.type = type;
+ hdr.len = ibuf_size(buf) + IMSG_HEADER_SIZE;
+ hdr.flags = 0;
+ hdr.peerid = peerid;
+ if ((hdr.pid = pid) == 0)
+ hdr.pid = ibuf->pid;
+
+ if ((wbuf = ibuf_open(IMSG_HEADER_SIZE)) == NULL)
+ goto fail;
+ if (imsg_add(wbuf, &hdr, sizeof(hdr)) == -1)
+ goto fail;
+
+ ibuf_close(&ibuf->w, wbuf);
+ ibuf_close(&ibuf->w, buf);
+ return (1);
+
+ fail:
+ save_errno = errno;
+ ibuf_free(buf);
+ ibuf_free(wbuf);
+ errno = save_errno;
+ return (-1);
+}
+
struct ibuf *
imsg_create(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid, pid_t pid,
uint16_t datalen)
hdr = (struct imsg_hdr *)msg->buf;
hdr->flags &= ~IMSGF_HASFD;
- if (msg->fd != -1)
+ if (ibuf_fd_avail(msg))
hdr->flags |= IMSGF_HASFD;
-
- hdr->len = (uint16_t)msg->wpos;
+ hdr->len = ibuf_size(msg);
ibuf_close(&ibuf->w, msg);
}
-/* $OpenBSD: imsg.h,v 1.6 2021/01/13 09:56:28 claudio Exp $ */
+/* $OpenBSD: imsg.h,v 1.7 2023/06/19 17:19:50 claudio Exp $ */
/*
* Copyright (c) 2006, 2007 Pierre-Yves Ritschard <pyr@openbsd.org>
struct iovec;
-/* buffer.c */
+/* imsg-buffer.c */
struct ibuf *ibuf_open(size_t);
struct ibuf *ibuf_dynamic(size_t, size_t);
int ibuf_add(struct ibuf *, const void *, size_t);
+int ibuf_add_buf(struct ibuf *, const struct ibuf *);
+int ibuf_add_zero(struct ibuf *, size_t);
+int ibuf_add_n8(struct ibuf *, uint64_t);
+int ibuf_add_n16(struct ibuf *, uint64_t);
+int ibuf_add_n32(struct ibuf *, uint64_t);
+int ibuf_add_n64(struct ibuf *, uint64_t);
void *ibuf_reserve(struct ibuf *, size_t);
void *ibuf_seek(struct ibuf *, size_t, size_t);
+int ibuf_set(struct ibuf *, size_t, const void *, size_t);
+int ibuf_set_n8(struct ibuf *, size_t, uint64_t);
+int ibuf_set_n16(struct ibuf *, size_t, uint64_t);
+int ibuf_set_n32(struct ibuf *, size_t, uint64_t);
+int ibuf_set_n64(struct ibuf *, size_t, uint64_t);
+void *ibuf_data(struct ibuf *);
size_t ibuf_size(struct ibuf *);
size_t ibuf_left(struct ibuf *);
void ibuf_close(struct msgbuf *, struct ibuf *);
-int ibuf_write(struct msgbuf *);
void ibuf_free(struct ibuf *);
+int ibuf_fd_avail(struct ibuf *);
+int ibuf_fd_get(struct ibuf *);
+void ibuf_fd_set(struct ibuf *, int);
+int ibuf_write(struct msgbuf *);
void msgbuf_init(struct msgbuf *);
void msgbuf_clear(struct msgbuf *);
int msgbuf_write(struct msgbuf *);
-void msgbuf_drain(struct msgbuf *, size_t);
/* imsg.c */
void imsg_init(struct imsgbuf *, int);
const void *, uint16_t);
int imsg_composev(struct imsgbuf *, uint32_t, uint32_t, pid_t, int,
const struct iovec *, int);
+int imsg_compose_ibuf(struct imsgbuf *, uint32_t, uint32_t, pid_t,
+ struct ibuf *);
struct ibuf *imsg_create(struct imsgbuf *, uint32_t, uint32_t, pid_t, uint16_t);
int imsg_add(struct ibuf *, const void *, uint16_t);
void imsg_close(struct imsgbuf *, struct ibuf *);
-.\" $OpenBSD: imsg_init.3,v 1.25 2022/05/19 08:05:23 stsp Exp $
+.\" $OpenBSD: imsg_init.3,v 1.26 2023/06/19 17:19:50 claudio Exp $
.\"
.\" Copyright (c) 2010 Nicholas Marriott <nicm@openbsd.org>
.\"
.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: May 19 2022 $
+.Dd $Mdocdate: June 19 2023 $
.Dt IMSG_INIT 3
.Os
.Sh NAME
.Nm imsg_get ,
.Nm imsg_compose ,
.Nm imsg_composev ,
+.Nm imsg_compose_ibuf ,
.Nm imsg_create ,
.Nm imsg_add ,
.Nm imsg_close ,
.Nm ibuf_open ,
.Nm ibuf_dynamic ,
.Nm ibuf_add ,
+.Nm ibuf_add_buf ,
+.Nm ibuf_add_n8 ,
+.Nm ibuf_add_n16 ,
+.Nm ibuf_add_n32 ,
+.Nm ibuf_add_n64 ,
+.Nm ibuf_add_zero ,
.Nm ibuf_reserve ,
.Nm ibuf_seek ,
+.Nm ibuf_set ,
+.Nm ibuf_set_n8 ,
+.Nm ibuf_set_n16 ,
+.Nm ibuf_set_n32 ,
+.Nm ibuf_set_n64 ,
+.Nm ibuf_data ,
.Nm ibuf_size ,
.Nm ibuf_left ,
.Nm ibuf_close ,
-.Nm ibuf_write ,
.Nm ibuf_free ,
+.Nm ibuf_fd_avail ,
+.Nm ibuf_fd_get ,
+.Nm ibuf_fd_set ,
+.Nm ibuf_write ,
.Nm msgbuf_init ,
.Nm msgbuf_clear ,
-.Nm msgbuf_write ,
-.Nm msgbuf_drain
+.Nm msgbuf_write
.Nd IPC messaging functions
.Sh SYNOPSIS
.In sys/types.h
.Ft int
.Fn imsg_composev "struct imsgbuf *ibuf" "uint32_t type" "uint32_t peerid" \
"pid_t pid" "int fd" "const struct iovec *iov" "int iovcnt"
+.Ft int
+.Fn imsg_compose_ibuf "struct imsgbuf *ibuf" "uint32_t type" "uint32_t peerid" \
+ "pid_t pid" "struct ibuf *buf"
.Ft "struct ibuf *"
.Fn imsg_create "struct imsgbuf *ibuf" "uint32_t type" "uint32_t peerid" \
"pid_t pid" "uint16_t datalen"
.Fn ibuf_dynamic "size_t len" "size_t max"
.Ft int
.Fn ibuf_add "struct ibuf *buf" "const void *data" "size_t len"
+.Ft int
+.Fn ibuf_add_buf "struct ibuf *buf" "const struct ibuf *from"
+.Ft int
+.Fn ibuf_add_n8 "struct ibuf *buf" "uint64_t value"
+.Ft int
+.Fn ibuf_add_n16 "struct ibuf *buf" "uint64_t value"
+.Ft int
+.Fn ibuf_add_n32 "struct ibuf *buf" "uint64_t value"
+.Ft int
+.Fn ibuf_add_n64 "struct ibuf *buf" "uint64_t value"
+.Ft int
+.Fn ibuf_add_zero "struct ibuf *buf" "size_t len"
.Ft "void *"
.Fn ibuf_reserve "struct ibuf *buf" "size_t len"
.Ft "void *"
.Fn ibuf_seek "struct ibuf *buf" "size_t pos" "size_t len"
+.Ft int
+.Fn ibuf_set "struct ibuf *buf" "size_t pos" "const void *data" \
+ "size_t len"
+.Ft int
+.Fn ibuf_set_n8 "struct ibuf *buf" "size_t pos" "uint64_t value"
+.Ft int
+.Fn ibuf_set_n16 "struct ibuf *buf" "size_t pos" "uint64_t value"
+.Ft int
+.Fn ibuf_set_n32 "struct ibuf *buf" "size_t pos" "uint64_t value"
+.Ft int
+.Fn ibuf_set_n64 "struct ibuf *buf" "size_t pos" "uint64_t value"
+.Ft "void *"
+.Fn ibuf_data "struct ibuf *buf"
.Ft size_t
.Fn ibuf_size "struct ibuf *buf"
.Ft size_t
.Fn ibuf_left "struct ibuf *buf"
.Ft void
.Fn ibuf_close "struct msgbuf *msgbuf" "struct ibuf *buf"
-.Ft int
-.Fn ibuf_write "struct msgbuf *msgbuf"
.Ft void
.Fn ibuf_free "struct ibuf *buf"
+.Ft int
+.Fn ibuf_fd_avail "struct ibuf *buf"
+.Ft int
+.Fn ibuf_fd_get "struct ibuf *buf"
+.Ft void
+.Fn ibuf_fd_set "struct ibuf *buf" "int fd"
+.Ft int
+.Fn ibuf_write "struct msgbuf *msgbuf"
.Ft void
.Fn msgbuf_init "struct msgbuf *msgbuf"
.Ft void
.Fn msgbuf_clear "struct msgbuf *msgbuf"
.Ft int
.Fn msgbuf_write "struct msgbuf *msgbuf"
-.Ft void
-.Fn msgbuf_drain "struct msgbuf *msgbuf" "size_t n"
.Sh DESCRIPTION
The
.Nm imsg
.Ed
.Pp
.Fn imsg_init
-is a routine which initializes
+initializes
.Fa ibuf
as one side of a channel associated with
.Fa fd .
output buffer.
.Pp
.Fn imsg_compose
-is a routine which is used to quickly create and queue an imsg.
+is used to quickly create and queue an imsg.
It takes the same parameters as the
.Fn imsg_create ,
.Fn imsg_add
by
.Fa iovec .
.Pp
+.Fn imsg_compose_ibuf
+is similar to
+.Fn imsg_compose .
+It takes the same parameters, except that the ancillary data buffer is specified
+by an ibuf
+.Fa buf .
+This routine returns 1 if it succeeds, \-1 otherwise.
+In either case the buffer
+.Fa buf
+is consumed by the function.
+.Pp
.Fn imsg_flush
-is a function which calls
+calls
.Fn msgbuf_write
in a loop until all imsgs in the output buffer are sent.
It returns 0 if it succeeds, \-1 otherwise.
are automatically grown if necessary when data is added.
.Pp
.Fn ibuf_add
-is a routine which appends a block of data to
+appends a block of data to
+.Fa buf .
+0 is returned on success and \-1 on failure.
+.Pp
+.Fn ibuf_add_buf
+appends the buffer
+.Fa from
+to
+.Fa buf .
+0 is returned on success and \-1 on failure.
+.Pp
+.Fn ibuf_add_n8 ,
+.Fn ibuf_add_n16 ,
+.Fn ibuf_add_n32 ,
+and
+.Fn ibuf_add_n64
+add a 1-byte, 2-byte, 4-byte, and 8-byte
+.Fa value
+to
+.Fa buf
+in network byte order.
+This function checks
+.Fa value
+to not overflow.
+0 is returned on success and \-1 on failure.
+.Pp
+.Fn ibuf_add_zero
+appends a block of zeros to
.Fa buf .
0 is returned on success and \-1 on failure.
.Pp
A pointer to the start of the reserved space is returned, or NULL on error.
.Pp
.Fn ibuf_seek
-is a function which returns a pointer to the part of the buffer at offset
+returns a pointer to the part of the buffer at offset
.Fa pos
and of extent
.Fa len .
NULL is returned if the requested range is outside the part of the buffer
in use.
.Pp
+.Fn ibuf_set
+replaces a part of
+.Fa buf
+at offset
+.Fa pos
+with the data of extent
+.Fa len .
+0 is returned on success and \-1 on failure.
+.Pp
+.Fn ibuf_set_n8 ,
+.Fn ibuf_set_n16 ,
+.Fn ibuf_seek_set_n32
+and
+.Fn ibuf_seek_set_n64
+replace a 1-byte, 2-byte, 4-byte or 8-byte
+.Fa value
+at offset
+.Fa pos
+in the buffer
+.Fa buf
+in network byte order.
+This function checks
+.Fa value
+to not overflow.
+0 is returned on success and \-1 on failure.
+.Pp
+.Fn ibuf_data
+returns the pointer to the internal buffer.
+This function should only be used together with
+.Fn ibuf_size
+to process a previously generated buffer.
+.Pp
.Fn ibuf_size
and
.Fn ibuf_left
.Fa msgbuf
ready to be sent.
.Pp
+.Fn ibuf_fd_avail ,
+.Fn ibuf_fd_get
+and
+.Fn ibuf_fd_set
+are functions to check, get and set the filedescriptor assigned to
+.Fa buf .
+After calling
+.Fn ibuf_fd_set
+the filedescriptor is part of the
+.Fa buf
+and will be transmitted or closed by the ibuf API.
+Any previously set filedescriptor will be closed before assigning a
+new descriptor.
+.Fn ibuf_fd_get
+returns the filedescriptor and passes the responsibilty to track the
+descriptor back to the program.
+.Fn ibuf_fd_avail
+returns true if there is a filedescriptor set on
+.Fa buf
+.Pp
+.Fn ibuf_free
+frees
+.Fa buf
+and any associated storage, and closes any filedescriptor set with
+.Fn ibuf_fd_set .
+If
+.Fa buf
+is a NULL pointer, no action occurs.
+.Pp
The
.Fn ibuf_write
routine transmits as many pending buffers as possible from
.Er EAGAIN
and require the application to retry again in the future.
.Pp
-.Fn ibuf_free
-frees
-.Fa buf
-and any associated storage.
-If
-.Fa buf
-is a NULL pointer, no action occurs.
-.Pp
The
.Fn msgbuf_init
function initializes
Temporary resource shortages are returned with errno
.Er EAGAIN
and require the application to retry again in the future.
-.Pp
-.Fn msgbuf_drain
-discards data from buffers queued in
-.Fa msgbuf
-until
-.Fa n
-bytes have been removed or
-.Fa msgbuf
-is empty.
.Sh EXAMPLES
In a typical program, a channel between two processes is created with
.Xr socketpair 2 ,
-major=16
+major=17
minor=0
-/* $OpenBSD: iked.h,v 1.217 2023/06/16 10:28:43 tb Exp $ */
+/* $OpenBSD: iked.h,v 1.218 2023/06/19 17:19:50 claudio Exp $ */
/*
* Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
int ibuf_cat(struct ibuf *, struct ibuf *);
size_t ibuf_length(struct ibuf *);
int ibuf_setsize(struct ibuf *, size_t);
-void *ibuf_data(struct ibuf *);
void *ibuf_getdata(struct ibuf *, size_t);
struct ibuf *
ibuf_get(struct ibuf *, size_t);
-/* $OpenBSD: imsg_util.c,v 1.18 2023/06/12 09:02:32 claudio Exp $ */
+/* $OpenBSD: imsg_util.c,v 1.19 2023/06/19 17:19:50 claudio Exp $ */
/*
* Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
return (ibuf_size(buf));
}
-void *
-ibuf_data(struct ibuf *buf)
-{
- return (ibuf_seek(buf, 0, 0));
-}
-
void *
ibuf_getdata(struct ibuf *buf, size_t len)
{