diff options
author | Pierre-Yves Ritschard <pyr@cvs.openbsd.org> | 2009-06-06 05:52:02 +0000 |
---|---|---|
committer | Pierre-Yves Ritschard <pyr@cvs.openbsd.org> | 2009-06-06 05:52:02 +0000 |
commit | 8d0733a46ab21b9a74bb53e474cab34e0e458771 (patch) | |
tree | e95f633833861d3b804667bdb7cb0eb67331294b /usr.sbin/snmpd/buffer.c | |
parent | f4e5d68bcd3927bf4124d5b83fe246911d8c0c92 (diff) |
sync snmpd with the common imsg code, making it lib ready as well.
ok eric@
Diffstat (limited to 'usr.sbin/snmpd/buffer.c')
-rw-r--r-- | usr.sbin/snmpd/buffer.c | 91 |
1 files changed, 75 insertions, 16 deletions
diff --git a/usr.sbin/snmpd/buffer.c b/usr.sbin/snmpd/buffer.c index d7f3505bc20..c7de4476655 100644 --- a/usr.sbin/snmpd/buffer.c +++ b/usr.sbin/snmpd/buffer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: buffer.c,v 1.6 2008/10/03 15:20:29 eric Exp $ */ +/* $OpenBSD: buffer.c,v 1.7 2009/06/06 05:52:01 pyr Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -16,24 +16,17 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <sys/types.h> +#include <sys/param.h> #include <sys/queue.h> #include <sys/socket.h> #include <sys/uio.h> -#include <sys/param.h> -#include <sys/tree.h> - -#include <net/if.h> #include <errno.h> -#include <event.h> -#include <limits.h> -#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> -#include "snmpd.h" +#include "imsg.h" int buf_realloc(struct buf *, size_t); void buf_enqueue(struct msgbuf *, struct buf *); @@ -94,7 +87,7 @@ buf_realloc(struct buf *buf, size_t len) } int -buf_add(struct buf *buf, void *data, size_t len) +buf_add(struct buf *buf, const void *data, size_t len) { if (buf->wpos + len > buf->size) if (buf_realloc(buf, len) == -1) @@ -119,11 +112,77 @@ buf_reserve(struct buf *buf, size_t len) return (b); } -int +void * +buf_seek(struct buf *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 +buf_size(struct buf *buf) +{ + return (buf->wpos); +} + +size_t +buf_left(struct buf *buf) +{ + return (buf->max - buf->wpos); +} + +void buf_close(struct msgbuf *msgbuf, struct buf *buf) { buf_enqueue(msgbuf, buf); - return (1); +} + +int +buf_write(struct msgbuf *msgbuf) +{ + struct iovec iov[IOV_MAX]; + struct buf *buf, *next; + unsigned int i = 0; + ssize_t n; + + bzero(&iov, 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->size - buf->rpos; + i++; + } + + if ((n = writev(msgbuf->fd, iov, i)) == -1) { + if (errno == EAGAIN || errno == ENOBUFS || + errno == EINTR) /* try later */ + return (0); + else + return (-1); + } + + if (n == 0) { /* connection closed */ + errno = 0; + return (-2); + } + + for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0; + buf = next) { + next = TAILQ_NEXT(buf, entry); + if (buf->rpos + n >= buf->size) { + n -= buf->size - buf->rpos; + buf_dequeue(msgbuf, buf); + } else { + buf->rpos += n; + n = 0; + } + } + + return (0); } void @@ -170,7 +229,7 @@ msgbuf_write(struct msgbuf *msgbuf) if (i >= IOV_MAX) break; iov[i].iov_base = buf->buf + buf->rpos; - iov[i].iov_len = buf->size - buf->rpos; + iov[i].iov_len = buf->wpos - buf->rpos; i++; if (buf->fd != -1) break; @@ -214,8 +273,8 @@ msgbuf_write(struct msgbuf *msgbuf) for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0; buf = next) { next = TAILQ_NEXT(buf, entry); - if (buf->rpos + n >= buf->size) { - n -= buf->size - buf->rpos; + if (buf->rpos + n >= buf->wpos) { + n -= buf->wpos - buf->rpos; buf_dequeue(msgbuf, buf); } else { buf->rpos += n; |