Work around libevent bug 306 in evbuffer_add_file.

See <https://github.com/libevent/libevent/issues/306> for details.
This commit is contained in:
Scott Lamb 2016-01-09 22:51:27 -08:00
parent bb7fb95b57
commit eed2a69f7a
2 changed files with 30 additions and 0 deletions

View File

@ -76,12 +76,25 @@ TEST(EvBufferTest, AddFileTest) {
// Ensure adding the whole file succeeds.
EvBuffer buf1;
ASSERT_TRUE(buf1.AddFile(in_fd, 0, 3, &error_message)) << error_message;
in_fd = -1;
EXPECT_EQ(3u, evbuffer_get_length(buf1.get()));
// Ensure adding an empty region succeeds.
EvBuffer buf2;
ASSERT_TRUE(buf2.AddFile(in_fd, 0, 0, &error_message)) << error_message;
EXPECT_EQ(0u, evbuffer_get_length(buf2.get()));
// Ensure adding part of a file after another string succeeds.
in_fd = open(foo_filename.c_str(), O_RDONLY);
EvBuffer buf3;
buf3.Add("1234");
ASSERT_TRUE(buf3.AddFile(in_fd, 1, 2, &error_message)) << error_message;
auto size3 = evbuffer_get_length(buf3.get());
EXPECT_EQ(6u, size3);
std::string buf3_contents = std::string(
reinterpret_cast<const char *>(evbuffer_pullup(buf3.get(), size3)),
size3);
EXPECT_EQ("1234oo", buf3_contents);
}
class FileSlicesTest : public testing::Test {

View File

@ -176,6 +176,23 @@ bool EvBuffer::AddFile(int fd, ev_off_t offset, ev_off_t length,
return true;
}
if (evbuffer_get_length(buf_) > 0) {
// Work around https://github.com/libevent/libevent/issues/306 by using a
// fresh buffer for evbuffer_add_file.
EvBuffer fresh_buffer;
if (!fresh_buffer.AddFile(fd, offset, length, error_message)) {
return false;
}
// Crash if evbuffer_add_buffer fails, because the ownership of |fd| has
// already been transferred, and it's too confusing to support some
// failures in which the caller still owns |fd| and some in which it does
// not.
CHECK_EQ(0, evbuffer_add_buffer(buf_, fresh_buffer.buf_))
<< "evbuffer_add_buffer failed: " << strerror(errno);
return true;
}
if (evbuffer_add_file(buf_, fd, offset, length) != 0) {
int err = errno;
*error_message = StrCat("evbuffer_add_file failed with offset ", offset,