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.
}
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];
/* 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)
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)
{
*/
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.
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.
*/