From dcdae6b743b1cfc2dceff0b95b3236dd83742f61 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Sat, 8 May 2010 16:34:18 -0400 Subject: [PATCH] Make evbuffer_add_file() work on windows Right now only the add_file() mode is supported, when it would be nicer to have mmap support. Perhaps for Libevent 2.1.x. --- buffer.c | 59 ++++++++++++++++++++++++++++++++++++++++++- test/regress_buffer.c | 2 ++ 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/buffer.c b/buffer.c index 66a27c4b..5a488023 100644 --- a/buffer.c +++ b/buffer.c @@ -141,6 +141,13 @@ static int evbuffer_ptr_memcmp(const struct evbuffer *buf, static struct evbuffer_chain *evbuffer_expand_singlechain(struct evbuffer *buf, size_t datlen); +#ifdef WIN32 +static int evbuffer_readfile(struct evbuffer *buf, evutil_socket_t fd, + int howmuch); +#else +#define evbuffer_readfile evbuffer_read +#endif + static struct evbuffer_chain * evbuffer_chain_new(size_t size) { @@ -1998,6 +2005,56 @@ done: return result; } +#ifdef WIN32 +static int +evbuffer_readfile(struct evbuffer *buf, evutil_socket_t fd, int howmuch) +{ + int result; + int nchains, n; + struct evbuffer_iovec v[2]; + + EVBUFFER_LOCK(buf); + + if (buf->freeze_end) { + result = -1; + goto done; + } + + if (howmuch < 0) + howmuch = 16384; + + + /* XXX we _will_ waste some space here if there is any space left + * over on buf->last. */ + nchains = evbuffer_reserve_space(buf, howmuch, v, 2); + if (nchains < 1 || nchains > 2) { + result = -1; + goto done; + } + n = read(fd, v[0].iov_base, v[0].iov_len); + if (n <= 0) { + result = n; + goto done; + } + v[0].iov_len = n; + if (nchains > 1) { + n = read(fd, v[1].iov_base, v[1].iov_len); + if (n <= 0) { + result = v[0].iov_len; + evbuffer_commit_space(buf, v, 1); + goto done; + } + v[1].iov_len = n; + } + evbuffer_commit_space(buf, v, nchains); + + result = n; +done: + EVBUFFER_UNLOCK(buf); + return result; +} +#endif + #ifdef USE_IOVEC_IMPL static inline int evbuffer_write_iovec(struct evbuffer *buffer, evutil_socket_t fd, @@ -2592,7 +2649,7 @@ evbuffer_add_file(struct evbuffer *outbuf, int fd, * can abort without side effects if the read fails. */ while (length) { - read = evbuffer_read(tmp, fd, length); + read = evbuffer_readfile(tmp, fd, length); if (read == -1) { evbuffer_free(tmp); return (-1); diff --git a/test/regress_buffer.c b/test/regress_buffer.c index fa24738e..057a0a21 100644 --- a/test/regress_buffer.c +++ b/test/regress_buffer.c @@ -596,6 +596,8 @@ test_evbuffer_add_file(void *ptr) const char *compare; evutil_socket_t fd, pair[2]; + /* Add a test for a big file. XXXX */ + tt_assert(impl); if (!strcmp(impl, "sendfile")) { if (!_evbuffer_testing_use_sendfile()) -- 2.40.0