FreeBSD Bugzilla – Attachment 199723 Details for
Bug 233699
[update] libutil/imsg api proposal
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Differential to update to 2017's version
diff (text/plain), 13.75 KB, created by
David Carlier
on 2018-12-01 20:19:10 UTC
(
hide
)
Description:
Differential to update to 2017's version
Filename:
MIME Type:
Creator:
David Carlier
Created:
2018-12-01 20:19:10 UTC
Size:
13.75 KB
patch
obsolete
>diff --git a/lib/libopenbsd/imsg-buffer.c b/lib/libopenbsd/imsg-buffer.c >index 2ea4d20b9fc..50740c190d3 100644 >--- a/lib/libopenbsd/imsg-buffer.c >+++ b/lib/libopenbsd/imsg-buffer.c >@@ -1,309 +1,312 @@ >-/* $OpenBSD: imsg-buffer.c,v 1.7 2015/07/12 18:40:49 nicm Exp $ */ >+/* $OpenBSD: imsg-buffer.c,v 1.11 2017/12/14 09:27:44 kettenis Exp $ */ > > /* > * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> > * > * Permission to use, copy, modify, and distribute this software for any > * purpose with or without fee is hereby granted, provided that the above > * copyright notice and this permission notice appear in all copies. > * > * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES > * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF > * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR > * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES > * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN > * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF > * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. > * > * $FreeBSD$ > */ > > #include <sys/types.h> > #include <sys/queue.h> > #include <sys/socket.h> > #include <sys/uio.h> > > #include <limits.h> > #include <errno.h> > #include <stdlib.h> > #include <string.h> > #include <unistd.h> > > #include "imsg.h" > >-int ibuf_realloc(struct ibuf *, size_t); >-void ibuf_enqueue(struct msgbuf *, struct ibuf *); >-void ibuf_dequeue(struct msgbuf *, struct ibuf *); >+static int ibuf_realloc(struct ibuf *, size_t); >+static void ibuf_enqueue(struct msgbuf *, struct ibuf *); >+static void ibuf_dequeue(struct msgbuf *, struct ibuf *); > > struct ibuf * > ibuf_open(size_t len) > { > struct ibuf *buf; > > if ((buf = calloc(1, sizeof(struct ibuf))) == NULL) > return (NULL); > if ((buf->buf = malloc(len)) == NULL) { > free(buf); > return (NULL); > } > buf->size = buf->max = len; > buf->fd = -1; > > return (buf); > } > > struct ibuf * > ibuf_dynamic(size_t len, size_t max) > { > struct ibuf *buf; > > if (max < len) > return (NULL); > > if ((buf = ibuf_open(len)) == NULL) > return (NULL); > > if (max > 0) > buf->max = max; > > return (buf); > } > >-int >+static int > ibuf_realloc(struct ibuf *buf, size_t len) > { > u_char *b; > > /* on static buffers max is eq size and so the following fails */ > if (buf->wpos + len > buf->max) { > errno = ERANGE; > return (-1); > } > >- b = realloc(buf->buf, buf->wpos + len); >+ b = reallocarray(buf->buf, buf->wpos + len, 1); > if (b == NULL) > return (-1); >+ memset(b, 0, buf->wpos + len); > buf->buf = b; > buf->size = buf->wpos + len; > > return (0); > } > > int > ibuf_add(struct ibuf *buf, const void *data, size_t len) > { > 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) > { > void *b; > > if (buf->wpos + len > buf->size) > if (ibuf_realloc(buf, len) == -1) > return (NULL); > > b = buf->buf + buf->wpos; > buf->wpos += len; > return (b); > } > > void * > ibuf_seek(struct ibuf *buf, size_t pos, size_t len) > { > /* only allowed to seek in already written parts */ > if (pos + len > buf->wpos) > return (NULL); > > return (buf->buf + pos); > } > > size_t > ibuf_size(struct ibuf *buf) > { > return (buf->wpos); > } > > size_t > ibuf_left(struct ibuf *buf) > { > return (buf->max - buf->wpos); > } > > void > ibuf_close(struct msgbuf *msgbuf, struct ibuf *buf) > { > ibuf_enqueue(msgbuf, buf); > } > > int > ibuf_write(struct msgbuf *msgbuf) > { > struct iovec iov[IOV_MAX]; > struct ibuf *buf; > unsigned int i = 0; > ssize_t n; > > memset(&iov, 0, sizeof(iov)); > 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; > i++; > } > > again: > if ((n = writev(msgbuf->fd, iov, i)) == -1) { > if (errno == EINTR) > goto again; > if (errno == ENOBUFS) > errno = EAGAIN; > return (-1); > } > > if (n == 0) { /* connection closed */ > errno = 0; > return (0); > } > > msgbuf_drain(msgbuf, n); > > return (1); > } > > void > ibuf_free(struct ibuf *buf) > { >+ if (buf == NULL) >+ return; > free(buf->buf); > free(buf); > } > > void > msgbuf_init(struct msgbuf *msgbuf) > { > msgbuf->queued = 0; > msgbuf->fd = -1; > TAILQ_INIT(&msgbuf->bufs); > } > > void > msgbuf_drain(struct msgbuf *msgbuf, size_t n) > { > struct ibuf *buf, *next; > > for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0; > buf = next) { > next = TAILQ_NEXT(buf, entry); > if (buf->rpos + n >= buf->wpos) { > n -= buf->wpos - buf->rpos; > ibuf_dequeue(msgbuf, buf); > } else { > buf->rpos += n; > n = 0; > } > } > } > > void > msgbuf_clear(struct msgbuf *msgbuf) > { > struct ibuf *buf; > > while ((buf = TAILQ_FIRST(&msgbuf->bufs)) != NULL) > ibuf_dequeue(msgbuf, buf); > } > > int > msgbuf_write(struct msgbuf *msgbuf) > { > struct iovec iov[IOV_MAX]; > struct ibuf *buf; > unsigned int i = 0; > ssize_t n; > struct msghdr msg; > struct cmsghdr *cmsg; > union { > struct cmsghdr hdr; > char buf[CMSG_SPACE(sizeof(int))]; > } cmsgbuf; > > memset(&iov, 0, sizeof(iov)); > memset(&msg, 0, sizeof(msg)); > memset(&cmsgbuf, 0, sizeof(cmsgbuf)); > 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; > i++; > if (buf->fd != -1) > break; > } > > msg.msg_iov = iov; > msg.msg_iovlen = i; > > if (buf != NULL && buf->fd != -1) { > msg.msg_control = (caddr_t)&cmsgbuf.buf; > msg.msg_controllen = sizeof(cmsgbuf.buf); > cmsg = CMSG_FIRSTHDR(&msg); > cmsg->cmsg_len = CMSG_LEN(sizeof(int)); > cmsg->cmsg_level = SOL_SOCKET; > cmsg->cmsg_type = SCM_RIGHTS; > *(int *)CMSG_DATA(cmsg) = buf->fd; > } > > again: > if ((n = sendmsg(msgbuf->fd, &msg, 0)) == -1) { > if (errno == EINTR) > goto again; > if (errno == ENOBUFS) > errno = EAGAIN; > return (-1); > } > > if (n == 0) { /* connection closed */ > errno = 0; > return (0); > } > > /* > * assumption: fd got sent if sendmsg sent anything > * this works because fds are passed one at a time > */ > if (buf != NULL && buf->fd != -1) { > close(buf->fd); > buf->fd = -1; > } > > msgbuf_drain(msgbuf, n); > > return (1); > } > >-void >+static void > ibuf_enqueue(struct msgbuf *msgbuf, struct ibuf *buf) > { > TAILQ_INSERT_TAIL(&msgbuf->bufs, buf, entry); > msgbuf->queued++; > } > >-void >+static void > ibuf_dequeue(struct msgbuf *msgbuf, struct ibuf *buf) > { > TAILQ_REMOVE(&msgbuf->bufs, buf, entry); > > if (buf->fd != -1) > close(buf->fd); > > msgbuf->queued--; > ibuf_free(buf); > } >diff --git a/lib/libopenbsd/imsg.c b/lib/libopenbsd/imsg.c >index 279ab63e524..0d301b28624 100644 >--- a/lib/libopenbsd/imsg.c >+++ b/lib/libopenbsd/imsg.c >@@ -1,304 +1,302 @@ >-/* $OpenBSD: imsg.c,v 1.13 2015/12/09 11:54:12 tb Exp $ */ >+/* $OpenBSD: imsg.c,v 1.16 2017/12/14 09:27:44 kettenis Exp $ */ > > /* > * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> > * > * Permission to use, copy, modify, and distribute this software for any > * purpose with or without fee is hereby granted, provided that the above > * copyright notice and this permission notice appear in all copies. > * > * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES > * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF > * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR > * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES > * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN > * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF > * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. >- * >- * $FreeBSD$ > */ > > #include <sys/types.h> > #include <sys/queue.h> > #include <sys/socket.h> > #include <sys/uio.h> > > #include <errno.h> > #include <stdlib.h> > #include <string.h> > #include <unistd.h> > > #include "imsg.h" > > int imsg_fd_overhead = 0; > >-int imsg_get_fd(struct imsgbuf *); >+static int imsg_get_fd(struct imsgbuf *); > > void > imsg_init(struct imsgbuf *ibuf, int fd) > { > msgbuf_init(&ibuf->w); > memset(&ibuf->r, 0, sizeof(ibuf->r)); > ibuf->fd = fd; > ibuf->w.fd = fd; > ibuf->pid = getpid(); > TAILQ_INIT(&ibuf->fds); > } > > ssize_t > imsg_read(struct imsgbuf *ibuf) > { > struct msghdr msg; > struct cmsghdr *cmsg; > union { > struct cmsghdr hdr; > char buf[CMSG_SPACE(sizeof(int) * 1)]; > } cmsgbuf; > struct iovec iov; > ssize_t n = -1; > int fd; > struct imsg_fd *ifd; > > memset(&msg, 0, sizeof(msg)); > memset(&cmsgbuf, 0, sizeof(cmsgbuf)); > > iov.iov_base = ibuf->r.buf + ibuf->r.wpos; > iov.iov_len = sizeof(ibuf->r.buf) - ibuf->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 (getdtablecount() + imsg_fd_overhead + > (int)((CMSG_SPACE(sizeof(int))-CMSG_SPACE(0))/sizeof(int)) > >= getdtablesize()) { > errno = EAGAIN; > free(ifd); > return (-1); > } > > if ((n = recvmsg(ibuf->fd, &msg, 0)) == -1) { > if (errno == EINTR) > goto again; > goto fail; > } > > ibuf->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(&ibuf->fds, ifd, > entry); > ifd = NULL; > } else > close(fd); > } > } > /* we do not handle other ctl data level */ > } > > fail: > free(ifd); > return (n); > } > > ssize_t > imsg_get(struct imsgbuf *ibuf, struct imsg *imsg) > { > size_t av, left, datalen; > > av = ibuf->r.wpos; > > if (IMSG_HEADER_SIZE > av) > return (0); > > memcpy(&imsg->hdr, ibuf->r.buf, sizeof(imsg->hdr)); > if (imsg->hdr.len < IMSG_HEADER_SIZE || > imsg->hdr.len > MAX_IMSGSIZE) { > errno = ERANGE; > return (-1); > } > if (imsg->hdr.len > av) > return (0); > datalen = imsg->hdr.len - IMSG_HEADER_SIZE; > ibuf->r.rptr = ibuf->r.buf + IMSG_HEADER_SIZE; > if (datalen == 0) > imsg->data = NULL; > else if ((imsg->data = malloc(datalen)) == NULL) > return (-1); > > if (imsg->hdr.flags & IMSGF_HASFD) > imsg->fd = imsg_get_fd(ibuf); > else > imsg->fd = -1; > > memcpy(imsg->data, ibuf->r.rptr, datalen); > > if (imsg->hdr.len < av) { > left = av - imsg->hdr.len; > memmove(&ibuf->r.buf, ibuf->r.buf + imsg->hdr.len, left); > ibuf->r.wpos = left; > } else > ibuf->r.wpos = 0; > > return (datalen + IMSG_HEADER_SIZE); > } > > int >-imsg_compose(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid, >- pid_t pid, int fd, const void *data, u_int16_t datalen) >+imsg_compose(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid, pid_t pid, >+ int fd, const void *data, uint16_t datalen) > { > struct ibuf *wbuf; > > if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL) > return (-1); > > if (imsg_add(wbuf, data, datalen) == -1) > return (-1); > > wbuf->fd = fd; > > imsg_close(ibuf, wbuf); > > return (1); > } > > int >-imsg_composev(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid, >- pid_t pid, int fd, const struct iovec *iov, int iovcnt) >+imsg_composev(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid, pid_t pid, >+ int fd, const struct iovec *iov, int iovcnt) > { > struct ibuf *wbuf; > int i, datalen = 0; > > for (i = 0; i < iovcnt; i++) > datalen += iov[i].iov_len; > > if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL) > return (-1); > > for (i = 0; i < iovcnt; i++) > if (imsg_add(wbuf, iov[i].iov_base, iov[i].iov_len) == -1) > return (-1); > > wbuf->fd = fd; > > imsg_close(ibuf, wbuf); > > return (1); > } > > /* ARGSUSED */ > struct ibuf * >-imsg_create(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid, >- pid_t pid, u_int16_t datalen) >+imsg_create(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid, pid_t pid, >+ uint16_t datalen) > { > struct ibuf *wbuf; > struct imsg_hdr hdr; > > datalen += IMSG_HEADER_SIZE; > if (datalen > MAX_IMSGSIZE) { > errno = ERANGE; > return (NULL); > } > > hdr.type = type; > hdr.flags = 0; > hdr.peerid = peerid; > if ((hdr.pid = pid) == 0) > hdr.pid = ibuf->pid; > if ((wbuf = ibuf_dynamic(datalen, MAX_IMSGSIZE)) == NULL) { > return (NULL); > } > if (imsg_add(wbuf, &hdr, sizeof(hdr)) == -1) > return (NULL); > > return (wbuf); > } > > int >-imsg_add(struct ibuf *msg, const void *data, u_int16_t datalen) >+imsg_add(struct ibuf *msg, const void *data, uint16_t datalen) > { > if (datalen) > if (ibuf_add(msg, data, datalen) == -1) { > ibuf_free(msg); > return (-1); > } > return (datalen); > } > > void > imsg_close(struct imsgbuf *ibuf, struct ibuf *msg) > { > struct imsg_hdr *hdr; > > hdr = (struct imsg_hdr *)msg->buf; > > hdr->flags &= ~IMSGF_HASFD; > if (msg->fd != -1) > hdr->flags |= IMSGF_HASFD; > >- hdr->len = (u_int16_t)msg->wpos; >+ hdr->len = (uint16_t)msg->wpos; > > ibuf_close(&ibuf->w, msg); > } > > void > imsg_free(struct imsg *imsg) > { > free(imsg->data); > } > >-int >+static int > imsg_get_fd(struct imsgbuf *ibuf) > { > int fd; > struct imsg_fd *ifd; > > if ((ifd = TAILQ_FIRST(&ibuf->fds)) == NULL) > return (-1); > > fd = ifd->fd; > TAILQ_REMOVE(&ibuf->fds, ifd, entry); > free(ifd); > > return (fd); > } > > int > imsg_flush(struct imsgbuf *ibuf) > { > while (ibuf->w.queued) > if (msgbuf_write(&ibuf->w) <= 0) > return (-1); > return (0); > } > > void > imsg_clear(struct imsgbuf *ibuf) > { > int fd; > > msgbuf_clear(&ibuf->w); > while ((fd = imsg_get_fd(ibuf)) != -1) > close(fd); > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 233699
:
199722
| 199723