]> granicus.if.org Git - libevent/commitdiff
Add a new evbuffer_write_atmost() functino to write no more than a given number of...
authorNick Mathewson <nickm@torproject.org>
Mon, 12 Jan 2009 20:42:19 +0000 (20:42 +0000)
committerNick Mathewson <nickm@torproject.org>
Mon, 12 Jan 2009 20:42:19 +0000 (20:42 +0000)
svn:r993

ChangeLog
buffer.c
include/event2/buffer.h

index 19e3afc52781177da30b61e1e856a1115a7e85f6..cba9b9db038a74dad9e2b5f7b566044cd56cb994 100644 (file)
--- 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.
index 5e4d4295bf6c103f73deadb17232039b8491f08d..7d7af92fc11b4c6031babbc19edadbb3f1adb8f0 100644 (file)
--- 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)
 {
index b011c6c91c1ebb5b80ad18f8303cbeae04119b5c..4f34a3b3a0d58b5f34dba93987ba8f98e7dc386d 100644 (file)
@@ -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.
 */