From 99db0e7f72ecbc81de2d73da98e3f9be66db1e68 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 12 Jan 2009 20:42:19 +0000 Subject: [PATCH] Add a new evbuffer_write_atmost() functino to write no more than a given number of bytes to an fd. svn:r993 --- ChangeLog | 1 + buffer.c | 33 ++++++++++++++++++++++++++------- include/event2/buffer.h | 18 +++++++++++++++--- 3 files changed, 42 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 19e3afc5..cba9b9db 100644 --- a/ChangeLog +++ b/ChangeLog @@ -135,6 +135,7 @@ Changes in current version: o Restructure the event backends so that they do not need to keep track of events themselves, as a side effect multiple events can use the same fd or signal. o Add generic implementations for parsing and emiting IPv6 addresses on platforms that do not have inet_ntop and/or inet_pton. o Allow DNS servers that have IPv6 addresses. + o Add an evbuffer_write_atmost() function to write a limited number of bytes to an fd. Changes in 1.4.0: o allow \r or \n individually to separate HTTP headers instead of the standard "\r\n"; from Charles Kerr. diff --git a/buffer.c b/buffer.c index 5e4d4295..7d7af92f 100644 --- a/buffer.c +++ b/buffer.c @@ -889,10 +889,15 @@ evbuffer_read(struct evbuffer *buf, evutil_socket_t fd, int howmuch) } int -evbuffer_write(struct evbuffer *buffer, evutil_socket_t fd) +evbuffer_write_atmost(struct evbuffer *buffer, evutil_socket_t fd, + ssize_t howmuch) { int n; + if (howmuch < 0) + howmuch = buffer->total_len; + + { #ifndef WIN32 #ifdef HAVE_SYS_UIO_H struct iovec iov[NUM_IOVEC]; @@ -901,21 +906,29 @@ evbuffer_write(struct evbuffer *buffer, evutil_socket_t fd) /* XXX make this top out at some maximal data length? if the buffer has * (say) 1MB in it, split over 128 chains, there's no way it all gets * written in one go. */ - while (chain != NULL && i < NUM_IOVEC) { + while (chain != NULL && i < NUM_IOVEC && howmuch) { iov[i].iov_base = chain->buffer + chain->misalign; - iov[i++].iov_len = chain->off; + if (howmuch >= chain->off) { + iov[i++].iov_len = chain->off; + howmuch -= chain->off; + } else { + iov[i++].iov_len = howmuch; + break; + } chain = chain->next; } n = writev(fd, iov, i); #else /* !HAVE_SYS_UIO_H */ - void *p = evbuffer_pullup(buffer, -1); - n = write(fd, p, buffer->total_len, 0); + void *p = evbuffer_pullup(buffer, howmuch); + n = write(fd, p, howmuch, 0); #endif #else /* XXX(niels): investigate if windows has writev */ - void *p = evbuffer_pullup(buffer, -1); - n = send(fd, p, buffer->total_len, 0); + void *p = evbuffer_pullup(buffer, howmuch); + n = send(fd, p, howmuch, 0); #endif + } + if (n == -1) return (-1); if (n == 0) @@ -925,6 +938,12 @@ evbuffer_write(struct evbuffer *buffer, evutil_socket_t fd) return (n); } +int +evbuffer_write(struct evbuffer *buffer, evutil_socket_t fd) +{ + return evbuffer_write_atmost(buffer, fd, -1); +} + unsigned char * evbuffer_find(struct evbuffer *buffer, const unsigned char *what, size_t len) { diff --git a/include/event2/buffer.h b/include/event2/buffer.h index b011c6c9..4f34a3b3 100644 --- a/include/event2/buffer.h +++ b/include/event2/buffer.h @@ -289,6 +289,21 @@ void evbuffer_drain(struct evbuffer *buf, size_t len); */ int evbuffer_write(struct evbuffer *buffer, evutil_socket_t fd); +/** + Write some of the contents of an evbuffer to a file descriptor. + + The evbuffer will be drained after the bytes have been successfully written. + + @param buffer the evbuffer to be written and drained + @param fd the file descriptor to be written to + @param howmuch the largest allowable number of bytes to write, or -1 + to write as many bytes as we can. + @return the number of bytes written, or -1 if an error occurred + @see evbuffer_read() + */ +int evbuffer_write_atmost(struct evbuffer *buffer, evutil_socket_t fd, + ssize_t howmuch); + /** Read from a file descriptor and store the result in an evbuffer. @@ -365,9 +380,6 @@ void evbuffer_prepend_buffer(struct evbuffer *dst, struct evbuffer* src); A better find-string that returns a smart offset structure rather than a pointer. It should also be able to start searching _at_ an offset. - A variant of evbuffer_write() that takes a maximum number of bytes to - write. - A check-representation functions for testing, so we can assert() that nothing has gone screwy inside an evbuffer. */ -- 2.50.1