summaryrefslogtreecommitdiffstats
path: root/compat
diff options
context:
space:
mode:
authorNicholas Marriott <nicholas.marriott@gmail.com>2017-03-24 10:05:53 +0000
committerNicholas Marriott <nicholas.marriott@gmail.com>2017-03-24 10:05:53 +0000
commit2e5664d2df02a902300f8f67b4eefe0309bde5b9 (patch)
tree0696b121ca98ddf1f011bd307040634f9464d096 /compat
parente87d808594e48a4c80d201d07fb86fbb9548409e (diff)
Update imsg*.[ch] from OpenBSD, add some compat bits it needs and remove some
bits it doesn't.
Diffstat (limited to 'compat')
-rw-r--r--compat/asprintf.c9
-rw-r--r--compat/explicit_bzero.c15
-rw-r--r--compat/getdtablecount.c55
-rw-r--r--compat/imsg-buffer.c6
-rw-r--r--compat/imsg.c72
-rw-r--r--compat/imsg.h27
-rw-r--r--compat/recallocarray.c82
7 files changed, 192 insertions, 74 deletions
diff --git a/compat/asprintf.c b/compat/asprintf.c
index 2b53dbe2..95d78430 100644
--- a/compat/asprintf.c
+++ b/compat/asprintf.c
@@ -14,15 +14,14 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include <sys/types.h>
+
#include <stdarg.h>
#include <stdio.h>
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#else
-#include <inttypes.h>
-#endif
#include <string.h>
+#include "compat.h"
+
int
asprintf(char **ret, const char *fmt, ...)
{
diff --git a/compat/explicit_bzero.c b/compat/explicit_bzero.c
new file mode 100644
index 00000000..e8bc5b36
--- /dev/null
+++ b/compat/explicit_bzero.c
@@ -0,0 +1,15 @@
+/* $OpenBSD: explicit_bzero.c,v 1.4 2015/08/31 02:53:57 guenther Exp $ */
+/*
+ * Public domain.
+ * Written by Matthew Dempsky.
+ */
+
+#include <string.h>
+
+#include "compat.h"
+
+void
+explicit_bzero(void *buf, size_t len)
+{
+ memset(buf, 0, len);
+}
diff --git a/compat/getdtablecount.c b/compat/getdtablecount.c
new file mode 100644
index 00000000..3ccab650
--- /dev/null
+++ b/compat/getdtablecount.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2017 Nicholas Marriott <nicholas.marriott@gmail.com>
+ *
+ * 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 MIND, 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.
+ */
+
+#include <sys/types.h>
+
+#include <glob.h>
+#include <unistd.h>
+
+#include "compat.h"
+
+void fatal(const char *, ...);
+void fatalx(const char *, ...);
+
+#ifdef HAVE_PROC_PID
+int
+getdtablecount(void)
+{
+ char path[PATH_MAX];
+ glob_t g;
+ int n;
+
+ if (snprintf(path, sizeof path, "/proc/%ld/fd/*", (long)getpid()) < 0)
+ fatal("snprintf overflow");
+ switch (glob(path, 0, NULL, &g)) {
+ case GLOB_NOMATCH:
+ return (0);
+ case 0:
+ break;
+ default:
+ fatal("glob(\"%s\") failed", path);
+ }
+ n = g.gl_pathc;
+ globfree(&g);
+ return (n);
+}
+#else
+int
+getdtablecount(void)
+{
+ return (0);
+}
+#endif
diff --git a/compat/imsg-buffer.c b/compat/imsg-buffer.c
index 4c8d5e2c..3576d5f0 100644
--- a/compat/imsg-buffer.c
+++ b/compat/imsg-buffer.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: imsg-buffer.c,v 1.7 2015/07/12 18:40:49 nicm Exp $ */
+/* $OpenBSD: imsg-buffer.c,v 1.9 2017/03/17 14:51:26 deraadt Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -78,7 +78,7 @@ ibuf_realloc(struct ibuf *buf, size_t len)
return (-1);
}
- b = realloc(buf->buf, buf->wpos + len);
+ b = recallocarray(buf->buf, buf->size, buf->wpos + len, 1);
if (b == NULL)
return (-1);
buf->buf = b;
@@ -180,6 +180,8 @@ again:
void
ibuf_free(struct ibuf *buf)
{
+ if (buf == NULL)
+ return;
free(buf->buf);
free(buf);
}
diff --git a/compat/imsg.c b/compat/imsg.c
index 422f37ab..987284b3 100644
--- a/compat/imsg.c
+++ b/compat/imsg.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: imsg.c,v 1.9 2015/07/12 18:40:49 nicm Exp $ */
+/* $OpenBSD: imsg.c,v 1.14 2017/03/24 09:34:12 nicm Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -32,40 +32,6 @@ int imsg_fd_overhead = 0;
int imsg_get_fd(struct imsgbuf *);
-int available_fds(unsigned int);
-
-/*
- * The original code calls getdtablecount() which is OpenBSD specific. Use
- * available_fds() from OpenSMTPD instead.
- */
-int
-available_fds(unsigned int n)
-{
- unsigned int i;
- int ret, fds[256];
-
- if (n > (sizeof(fds)/sizeof(fds[0])))
- return (1);
-
- ret = 0;
- for (i = 0; i < n; i++) {
- fds[i] = -1;
- if ((fds[i] = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
- if (errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT)
- fds[i] = socket(AF_INET6, SOCK_DGRAM, 0);
- if (fds[i] < 0) {
- ret = 1;
- break;
- }
- }
- }
-
- for (i = 0; i < n && fds[i] >= 0; i++)
- close(fds[i]);
-
- return (ret);
-}
-
void
imsg_init(struct imsgbuf *ibuf, int fd)
{
@@ -105,19 +71,18 @@ imsg_read(struct imsgbuf *ibuf)
return (-1);
again:
- if (available_fds(imsg_fd_overhead +
- (CMSG_SPACE(sizeof(int))-CMSG_SPACE(0))/sizeof(int))) {
+ 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 == EMSGSIZE)
- goto fail;
- if (errno != EINTR && errno != EAGAIN)
- goto fail;
- goto again;
+ if (errno == EINTR)
+ goto again;
+ goto fail;
}
ibuf->r.wpos += n;
@@ -151,8 +116,7 @@ again:
}
fail:
- if (ifd)
- free(ifd);
+ free(ifd);
return (n);
}
@@ -176,7 +140,9 @@ imsg_get(struct imsgbuf *ibuf, struct imsg *imsg)
return (0);
datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
ibuf->r.rptr = ibuf->r.buf + IMSG_HEADER_SIZE;
- if ((imsg->data = malloc(datalen)) == NULL)
+ if (datalen == 0)
+ imsg->data = NULL;
+ else if ((imsg->data = malloc(datalen)) == NULL)
return (-1);
if (imsg->hdr.flags & IMSGF_HASFD)
@@ -197,8 +163,8 @@ imsg_get(struct imsgbuf *ibuf, struct imsg *imsg)
}
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;
@@ -216,8 +182,8 @@ imsg_compose(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid,
}
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;
@@ -241,8 +207,8 @@ imsg_composev(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid,
/* 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;
@@ -268,7 +234,7 @@ imsg_create(struct imsgbuf *ibuf, u_int32_t type, u_int32_t peerid,
}
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) {
@@ -289,7 +255,7 @@ imsg_close(struct imsgbuf *ibuf, struct ibuf *msg)
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);
}
diff --git a/compat/imsg.h b/compat/imsg.h
index 89946578..8bf94147 100644
--- a/compat/imsg.h
+++ b/compat/imsg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: imsg.h,v 1.3 2013/12/26 17:32:33 eric Exp $ */
+/* $OpenBSD: imsg.h,v 1.4 2017/03/24 09:34:12 nicm Exp $ */
/*
* Copyright (c) 2006, 2007 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -37,7 +37,7 @@ struct ibuf {
struct msgbuf {
TAILQ_HEAD(, ibuf) bufs;
- u_int32_t queued;
+ uint32_t queued;
int fd;
};
@@ -63,11 +63,11 @@ struct imsgbuf {
#define IMSGF_HASFD 1
struct imsg_hdr {
- u_int32_t type;
- u_int16_t len;
- u_int16_t flags;
- u_int32_t peerid;
- u_int32_t pid;
+ uint32_t type;
+ uint16_t len;
+ uint16_t flags;
+ uint32_t peerid;
+ uint32_t pid;
};
struct imsg {
@@ -97,13 +97,12 @@ void msgbuf_drain(struct msgbuf *, size_t);
void imsg_init(struct imsgbuf *, int);
ssize_t imsg_read(struct imsgbuf *);
ssize_t imsg_get(struct imsgbuf *, struct imsg *);
-int imsg_compose(struct imsgbuf *, u_int32_t, u_int32_t, pid_t,
- int, const void *, u_int16_t);
-int imsg_composev(struct imsgbuf *, u_int32_t, u_int32_t, pid_t,
- int, const struct iovec *, int);
-struct ibuf *imsg_create(struct imsgbuf *, u_int32_t, u_int32_t, pid_t,
- u_int16_t);
-int imsg_add(struct ibuf *, const void *, u_int16_t);
+int imsg_compose(struct imsgbuf *, uint32_t, uint32_t, pid_t, int,
+ const void *, uint16_t);
+int imsg_composev(struct imsgbuf *, uint32_t, uint32_t, pid_t, int,
+ const struct iovec *, int);
+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 *);
void imsg_free(struct imsg *);
int imsg_flush(struct imsgbuf *);
diff --git a/compat/recallocarray.c b/compat/recallocarray.c
new file mode 100644
index 00000000..74a919a1
--- /dev/null
+++ b/compat/recallocarray.c
@@ -0,0 +1,82 @@
+/* $OpenBSD: recallocarray.c,v 1.1 2017/03/06 18:44:21 otto Exp $ */
+/*
+ * Copyright (c) 2008, 2017 Otto Moerbeek <otto@drijf.net>
+ *
+ * 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.
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "compat.h"
+
+/*
+ * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
+ * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
+ */
+#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
+
+void *
+recallocarray(void *ptr, size_t oldnmemb, size_t newnmemb, size_t size)
+{
+ size_t oldsize, newsize;
+ void *newptr;
+
+ if (ptr == NULL)
+ return calloc(newnmemb, size);
+
+ if ((newnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
+ newnmemb > 0 && SIZE_MAX / newnmemb < size) {
+ errno = ENOMEM;
+ return NULL;
+ }
+ newsize = newnmemb * size;
+
+ if ((oldnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
+ oldnmemb > 0 && SIZE_MAX / oldnmemb < size) {
+ errno = EINVAL;
+ return NULL;
+ }
+ oldsize = oldnmemb * size;
+
+ /*
+ * Don't bother too much if we're shrinking just a bit,
+ * we do not shrink for series of small steps, oh well.
+ */
+ if (newsize <= oldsize) {
+ size_t d = oldsize - newsize;
+
+ if (d < oldsize / 2 && d < (size_t)getpagesize()) {
+ memset((char *)ptr + newsize, 0, d);
+ return ptr;
+ }
+ }
+
+ newptr = malloc(newsize);
+ if (newptr == NULL)
+ return NULL;
+
+ if (newsize > oldsize) {
+ memcpy(newptr, ptr, oldsize);
+ memset((char *)newptr + oldsize, 0, newsize - oldsize);
+ } else
+ memcpy(newptr, ptr, newsize);
+
+ explicit_bzero(ptr, oldsize);
+ free(ptr);
+
+ return newptr;
+}