Add a new evbuffer_write_atmost() functino to write no more than a given number of bytes to an fd.

svn:r993
This commit is contained in:
Nick Mathewson 2009-01-12 20:42:19 +00:00
parent f446f1493a
commit 99db0e7f72
3 changed files with 42 additions and 10 deletions

View File

@ -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.

View File

@ -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)
{

View 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.
*/