summaryrefslogtreecommitdiff
path: root/usr.sbin/bgpd/buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/bgpd/buffer.c')
-rw-r--r--usr.sbin/bgpd/buffer.c44
1 files changed, 36 insertions, 8 deletions
diff --git a/usr.sbin/bgpd/buffer.c b/usr.sbin/bgpd/buffer.c
index f7026dec044..7eff2add24c 100644
--- a/usr.sbin/bgpd/buffer.c
+++ b/usr.sbin/bgpd/buffer.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: buffer.c,v 1.13 2004/01/10 21:02:54 henning Exp $ */
+/* $OpenBSD: buffer.c,v 1.14 2004/01/10 23:25:44 henning Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -17,6 +17,7 @@
*/
#include <sys/types.h>
+#include <sys/uio.h>
#include <stdio.h>
#include <stdlib.h>
@@ -140,15 +141,42 @@ msgbuf_write(struct msgbuf *msgbuf)
* we MUST return and NOT try to write out stuff from later buffers -
* the socket might have become writeable again
*/
- struct buf *buf;
- int n;
+ struct iovec iov[IOV_MAX];
+ struct buf *buf, *next;
+ int i = 0;
+ ssize_t n;
+
+ TAILQ_FOREACH(buf, &msgbuf->bufs, entries) {
+ if (i >= IOV_MAX)
+ break;
+ iov[i].iov_base = buf->buf + buf->rpos;
+ iov[i].iov_len = buf->size - buf->rpos;
+ i++;
+ }
- buf = TAILQ_FIRST(&msgbuf->bufs);
- if ((n = buf_write(msgbuf->sock, buf)) < 0)
- return (n);
+ if ((n = writev(msgbuf->sock, iov, i)) == -1) {
+ if (errno == EAGAIN) /* cannot write immediately */
+ return (0);
+ else
+ return (-1);
+ }
- if (n == 1) /* everything written out */
- buf_dequeue(msgbuf, buf);
+ 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, entries);
+ if (n >= buf->size - buf->rpos) {
+ n -= buf->size - buf->rpos;
+ buf_dequeue(msgbuf, buf);
+ } else {
+ buf->rpos += n;
+ n = 0;
+ }
+ }
return (0);
}