xref: /freebsd/contrib/ntp/sntp/libevent/test/regress_buffer.c (revision a0ee8cc636cd5c2374ec44ca71226564ea0bca95)
1 /*
2  * Copyright (c) 2003-2007 Niels Provos <provos@citi.umich.edu>
3  * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. The name of the author may not be used to endorse or promote products
14  *    derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 #include "util-internal.h"
28 
29 #ifdef _WIN32
30 #include <winsock2.h>
31 #include <windows.h>
32 #endif
33 
34 #include "event2/event-config.h"
35 
36 #include <sys/types.h>
37 #include <sys/stat.h>
38 #ifdef EVENT__HAVE_SYS_TIME_H
39 #include <sys/time.h>
40 #endif
41 #include <sys/queue.h>
42 #ifndef _WIN32
43 #include <sys/socket.h>
44 #include <sys/wait.h>
45 #include <signal.h>
46 #include <unistd.h>
47 #include <netdb.h>
48 #endif
49 #include <stdlib.h>
50 #include <stdio.h>
51 #include <string.h>
52 #include <errno.h>
53 #include <assert.h>
54 
55 #include "event2/event.h"
56 #include "event2/buffer.h"
57 #include "event2/buffer_compat.h"
58 #include "event2/util.h"
59 
60 #include "defer-internal.h"
61 #include "evbuffer-internal.h"
62 #include "log-internal.h"
63 
64 #include "regress.h"
65 
66 /* Validates that an evbuffer is good. Returns false if it isn't, true if it
67  * is*/
68 static int
69 evbuffer_validate_(struct evbuffer *buf)
70 {
71 	struct evbuffer_chain *chain;
72 	size_t sum = 0;
73 	int found_last_with_datap = 0;
74 
75 	if (buf->first == NULL) {
76 		tt_assert(buf->last == NULL);
77 		tt_assert(buf->total_len == 0);
78 	}
79 
80 	chain = buf->first;
81 
82 	tt_assert(buf->last_with_datap);
83 	if (buf->last_with_datap == &buf->first)
84 		found_last_with_datap = 1;
85 
86 	while (chain != NULL) {
87 		if (&chain->next == buf->last_with_datap)
88 			found_last_with_datap = 1;
89 		sum += chain->off;
90 		if (chain->next == NULL) {
91 			tt_assert(buf->last == chain);
92 		}
93 		tt_assert(chain->buffer_len >= chain->misalign + chain->off);
94 		chain = chain->next;
95 	}
96 
97 	if (buf->first)
98 		tt_assert(*buf->last_with_datap);
99 
100 	if (*buf->last_with_datap) {
101 		chain = *buf->last_with_datap;
102 		if (chain->off == 0 || buf->total_len == 0) {
103 			tt_assert(chain->off == 0)
104 			tt_assert(chain == buf->first);
105 			tt_assert(buf->total_len == 0);
106 		}
107 		chain = chain->next;
108 		while (chain != NULL) {
109 			tt_assert(chain->off == 0);
110 			chain = chain->next;
111 		}
112 	} else {
113 		tt_assert(buf->last_with_datap == &buf->first);
114 	}
115 	tt_assert(found_last_with_datap);
116 
117 	tt_assert(sum == buf->total_len);
118 	return 1;
119  end:
120 	return 0;
121 }
122 
123 static void
124 evbuffer_get_waste(struct evbuffer *buf, size_t *allocatedp, size_t *wastedp, size_t *usedp)
125 {
126 	struct evbuffer_chain *chain;
127 	size_t a, w, u;
128 	int n = 0;
129 	u = a = w = 0;
130 
131 	chain = buf->first;
132 	/* skip empty at start */
133 	while (chain && chain->off==0) {
134 		++n;
135 		a += chain->buffer_len;
136 		chain = chain->next;
137 	}
138 	/* first nonempty chain: stuff at the end only is wasted. */
139 	if (chain) {
140 		++n;
141 		a += chain->buffer_len;
142 		u += chain->off;
143 		if (chain->next && chain->next->off)
144 			w += (size_t)(chain->buffer_len - (chain->misalign + chain->off));
145 		chain = chain->next;
146 	}
147 	/* subsequent nonempty chains */
148 	while (chain && chain->off) {
149 		++n;
150 		a += chain->buffer_len;
151 		w += (size_t)chain->misalign;
152 		u += chain->off;
153 		if (chain->next && chain->next->off)
154 			w += (size_t) (chain->buffer_len - (chain->misalign + chain->off));
155 		chain = chain->next;
156 	}
157 	/* subsequent empty chains */
158 	while (chain) {
159 		++n;
160 		a += chain->buffer_len;
161 	}
162 	*allocatedp = a;
163 	*wastedp = w;
164 	*usedp = u;
165 }
166 
167 #define evbuffer_validate(buf)			\
168 	TT_STMT_BEGIN if (!evbuffer_validate_(buf)) TT_DIE(("Buffer format invalid")); TT_STMT_END
169 
170 static void
171 test_evbuffer(void *ptr)
172 {
173 	static char buffer[512], *tmp;
174 	struct evbuffer *evb = evbuffer_new();
175 	struct evbuffer *evb_two = evbuffer_new();
176 	size_t sz_tmp;
177 	int i;
178 
179 	evbuffer_validate(evb);
180 	evbuffer_add_printf(evb, "%s/%d", "hello", 1);
181 	evbuffer_validate(evb);
182 
183 	tt_assert(evbuffer_get_length(evb) == 7);
184 	tt_assert(!memcmp((char*)EVBUFFER_DATA(evb), "hello/1", 1));
185 
186 	evbuffer_add_buffer(evb, evb_two);
187 	evbuffer_validate(evb);
188 
189 	evbuffer_drain(evb, strlen("hello/"));
190 	evbuffer_validate(evb);
191 	tt_assert(evbuffer_get_length(evb) == 1);
192 	tt_assert(!memcmp((char*)EVBUFFER_DATA(evb), "1", 1));
193 
194 	evbuffer_add_printf(evb_two, "%s", "/hello");
195 	evbuffer_validate(evb);
196 	evbuffer_add_buffer(evb, evb_two);
197 	evbuffer_validate(evb);
198 
199 	tt_assert(evbuffer_get_length(evb_two) == 0);
200 	tt_assert(evbuffer_get_length(evb) == 7);
201 	tt_assert(!memcmp((char*)EVBUFFER_DATA(evb), "1/hello", 7) != 0);
202 
203 	memset(buffer, 0, sizeof(buffer));
204 	evbuffer_add(evb, buffer, sizeof(buffer));
205 	evbuffer_validate(evb);
206 	tt_assert(evbuffer_get_length(evb) == 7 + 512);
207 
208 	tmp = (char *)evbuffer_pullup(evb, 7 + 512);
209 	tt_assert(tmp);
210 	tt_assert(!strncmp(tmp, "1/hello", 7));
211 	tt_assert(!memcmp(tmp + 7, buffer, sizeof(buffer)));
212 	evbuffer_validate(evb);
213 
214 	evbuffer_prepend(evb, "something", 9);
215 	evbuffer_validate(evb);
216 	evbuffer_prepend(evb, "else", 4);
217 	evbuffer_validate(evb);
218 
219 	tmp = (char *)evbuffer_pullup(evb, 4 + 9 + 7);
220 	tt_assert(!strncmp(tmp, "elsesomething1/hello", 4 + 9 + 7));
221 	evbuffer_validate(evb);
222 
223 	evbuffer_drain(evb, -1);
224 	evbuffer_validate(evb);
225 	evbuffer_drain(evb_two, -1);
226 	evbuffer_validate(evb);
227 
228 	for (i = 0; i < 3; ++i) {
229 		evbuffer_add(evb_two, buffer, sizeof(buffer));
230 		evbuffer_validate(evb_two);
231 		evbuffer_add_buffer(evb, evb_two);
232 		evbuffer_validate(evb);
233 		evbuffer_validate(evb_two);
234 	}
235 
236 	tt_assert(evbuffer_get_length(evb_two) == 0);
237 	tt_assert(evbuffer_get_length(evb) == i * sizeof(buffer));
238 
239 	/* test remove buffer */
240 	sz_tmp = (size_t)(sizeof(buffer)*2.5);
241 	evbuffer_remove_buffer(evb, evb_two, sz_tmp);
242 	tt_assert(evbuffer_get_length(evb_two) == sz_tmp);
243 	tt_assert(evbuffer_get_length(evb) == sizeof(buffer) / 2);
244 	evbuffer_validate(evb);
245 
246 	if (memcmp(evbuffer_pullup(
247 			   evb, -1), buffer, sizeof(buffer) / 2) != 0 ||
248 	    memcmp(evbuffer_pullup(
249 			   evb_two, -1), buffer, sizeof(buffer)) != 0)
250 		tt_abort_msg("Pullup did not preserve content");
251 
252 	evbuffer_validate(evb);
253 
254 
255 	/* testing one-vector reserve and commit */
256 	{
257 		struct evbuffer_iovec v[1];
258 		char *buf;
259 		int i, j, r;
260 
261 		for (i = 0; i < 3; ++i) {
262 			r = evbuffer_reserve_space(evb, 10000, v, 1);
263 			tt_int_op(r, ==, 1);
264 			tt_assert(v[0].iov_len >= 10000);
265 			tt_assert(v[0].iov_base != NULL);
266 
267 			evbuffer_validate(evb);
268 			buf = v[0].iov_base;
269 			for (j = 0; j < 10000; ++j) {
270 				buf[j] = j;
271 			}
272 			evbuffer_validate(evb);
273 
274 			tt_int_op(evbuffer_commit_space(evb, v, 1), ==, 0);
275 			evbuffer_validate(evb);
276 
277 			tt_assert(evbuffer_get_length(evb) >= 10000);
278 
279 			evbuffer_drain(evb, j * 5000);
280 			evbuffer_validate(evb);
281 		}
282 	}
283 
284  end:
285 	evbuffer_free(evb);
286 	evbuffer_free(evb_two);
287 }
288 
289 static void
290 no_cleanup(const void *data, size_t datalen, void *extra)
291 {
292 }
293 
294 static void
295 test_evbuffer_remove_buffer_with_empty(void *ptr)
296 {
297     struct evbuffer *src = evbuffer_new();
298     struct evbuffer *dst = evbuffer_new();
299     char buf[2];
300 
301     evbuffer_validate(src);
302     evbuffer_validate(dst);
303 
304     /* setup the buffers */
305     /* we need more data in src than we will move later */
306     evbuffer_add_reference(src, buf, sizeof(buf), no_cleanup, NULL);
307     evbuffer_add_reference(src, buf, sizeof(buf), no_cleanup, NULL);
308     /* we need one buffer in dst and one empty buffer at the end */
309     evbuffer_add(dst, buf, sizeof(buf));
310     evbuffer_add_reference(dst, buf, 0, no_cleanup, NULL);
311 
312     evbuffer_validate(src);
313     evbuffer_validate(dst);
314 
315     /* move three bytes over */
316     evbuffer_remove_buffer(src, dst, 3);
317 
318     evbuffer_validate(src);
319     evbuffer_validate(dst);
320 
321 end:
322     evbuffer_free(src);
323     evbuffer_free(dst);
324 }
325 
326 static void
327 test_evbuffer_reserve2(void *ptr)
328 {
329 	/* Test the two-vector cases of reserve/commit. */
330 	struct evbuffer *buf = evbuffer_new();
331 	int n, i;
332 	struct evbuffer_iovec v[2];
333 	size_t remaining;
334 	char *cp, *cp2;
335 
336 	/* First chunk will necessarily be one chunk. Use 512 bytes of it.*/
337 	n = evbuffer_reserve_space(buf, 1024, v, 2);
338 	tt_int_op(n, ==, 1);
339 	tt_int_op(evbuffer_get_length(buf), ==, 0);
340 	tt_assert(v[0].iov_base != NULL);
341 	tt_int_op(v[0].iov_len, >=, 1024);
342 	memset(v[0].iov_base, 'X', 512);
343 	cp = v[0].iov_base;
344 	remaining = v[0].iov_len - 512;
345 	v[0].iov_len = 512;
346 	evbuffer_validate(buf);
347 	tt_int_op(0, ==, evbuffer_commit_space(buf, v, 1));
348 	tt_int_op(evbuffer_get_length(buf), ==, 512);
349 	evbuffer_validate(buf);
350 
351 	/* Ask for another same-chunk request, in an existing chunk. Use 8
352 	 * bytes of it. */
353 	n = evbuffer_reserve_space(buf, 32, v, 2);
354 	tt_int_op(n, ==, 1);
355 	tt_assert(cp + 512 == v[0].iov_base);
356 	tt_int_op(remaining, ==, v[0].iov_len);
357 	memset(v[0].iov_base, 'Y', 8);
358 	v[0].iov_len = 8;
359 	tt_int_op(0, ==, evbuffer_commit_space(buf, v, 1));
360 	tt_int_op(evbuffer_get_length(buf), ==, 520);
361 	remaining -= 8;
362 	evbuffer_validate(buf);
363 
364 	/* Now ask for a request that will be split. Use only one byte of it,
365 	   though. */
366 	n = evbuffer_reserve_space(buf, remaining+64, v, 2);
367 	tt_int_op(n, ==, 2);
368 	tt_assert(cp + 520 == v[0].iov_base);
369 	tt_int_op(remaining, ==, v[0].iov_len);
370 	tt_assert(v[1].iov_base);
371 	tt_assert(v[1].iov_len >= 64);
372 	cp2 = v[1].iov_base;
373 	memset(v[0].iov_base, 'Z', 1);
374 	v[0].iov_len = 1;
375 	tt_int_op(0, ==, evbuffer_commit_space(buf, v, 1));
376 	tt_int_op(evbuffer_get_length(buf), ==, 521);
377 	remaining -= 1;
378 	evbuffer_validate(buf);
379 
380 	/* Now ask for a request that will be split. Use some of the first
381 	 * part and some of the second. */
382 	n = evbuffer_reserve_space(buf, remaining+64, v, 2);
383 	evbuffer_validate(buf);
384 	tt_int_op(n, ==, 2);
385 	tt_assert(cp + 521 == v[0].iov_base);
386 	tt_int_op(remaining, ==, v[0].iov_len);
387 	tt_assert(v[1].iov_base == cp2);
388 	tt_assert(v[1].iov_len >= 64);
389 	memset(v[0].iov_base, 'W', 400);
390 	v[0].iov_len = 400;
391 	memset(v[1].iov_base, 'x', 60);
392 	v[1].iov_len = 60;
393 	tt_int_op(0, ==, evbuffer_commit_space(buf, v, 2));
394 	tt_int_op(evbuffer_get_length(buf), ==, 981);
395 	evbuffer_validate(buf);
396 
397 	/* Now peek to make sure stuff got made how we like. */
398 	memset(v,0,sizeof(v));
399 	n = evbuffer_peek(buf, -1, NULL, v, 2);
400 	tt_int_op(n, ==, 2);
401 	tt_int_op(v[0].iov_len, ==, 921);
402 	tt_int_op(v[1].iov_len, ==, 60);
403 
404 	cp = v[0].iov_base;
405 	for (i=0; i<512; ++i)
406 		tt_int_op(cp[i], ==, 'X');
407 	for (i=512; i<520; ++i)
408 		tt_int_op(cp[i], ==, 'Y');
409 	for (i=520; i<521; ++i)
410 		tt_int_op(cp[i], ==, 'Z');
411 	for (i=521; i<921; ++i)
412 		tt_int_op(cp[i], ==, 'W');
413 
414 	cp = v[1].iov_base;
415 	for (i=0; i<60; ++i)
416 		tt_int_op(cp[i], ==, 'x');
417 
418 end:
419 	evbuffer_free(buf);
420 }
421 
422 static void
423 test_evbuffer_reserve_many(void *ptr)
424 {
425 	/* This is a glass-box test to handle expanding a buffer with more
426 	 * chunks and reallocating chunks as needed */
427 	struct evbuffer *buf = evbuffer_new();
428 	struct evbuffer_iovec v[8];
429 	int n;
430 	size_t sz;
431 	int add_data = ptr && !strcmp(ptr, "add");
432 	int fill_first = ptr && !strcmp(ptr, "fill");
433 	char *cp1, *cp2;
434 
435 	/* When reserving the the first chunk, we just allocate it */
436 	n = evbuffer_reserve_space(buf, 128, v, 2);
437 	evbuffer_validate(buf);
438 	tt_int_op(n, ==, 1);
439 	tt_assert(v[0].iov_len >= 128);
440 	sz = v[0].iov_len;
441 	cp1 = v[0].iov_base;
442 	if (add_data) {
443 		*(char*)v[0].iov_base = 'X';
444 		v[0].iov_len = 1;
445 		n = evbuffer_commit_space(buf, v, 1);
446 		tt_int_op(n, ==, 0);
447 	} else if (fill_first) {
448 		memset(v[0].iov_base, 'X', v[0].iov_len);
449 		n = evbuffer_commit_space(buf, v, 1);
450 		tt_int_op(n, ==, 0);
451 		n = evbuffer_reserve_space(buf, 128, v, 2);
452 		tt_int_op(n, ==, 1);
453 		sz = v[0].iov_len;
454 		tt_assert(v[0].iov_base != cp1);
455 		cp1 = v[0].iov_base;
456 	}
457 
458 	/* Make another chunk get added. */
459 	n = evbuffer_reserve_space(buf, sz+128, v, 2);
460 	evbuffer_validate(buf);
461 	tt_int_op(n, ==, 2);
462 	sz = v[0].iov_len + v[1].iov_len;
463 	tt_int_op(sz, >=, v[0].iov_len+128);
464 	if (add_data) {
465 		tt_assert(v[0].iov_base == cp1 + 1);
466 	} else {
467 		tt_assert(v[0].iov_base == cp1);
468 	}
469 	cp1 = v[0].iov_base;
470 	cp2 = v[1].iov_base;
471 
472 	/* And a third chunk. */
473 	n = evbuffer_reserve_space(buf, sz+128, v, 3);
474 	evbuffer_validate(buf);
475 	tt_int_op(n, ==, 3);
476 	tt_assert(cp1 == v[0].iov_base);
477 	tt_assert(cp2 == v[1].iov_base);
478 	sz = v[0].iov_len + v[1].iov_len + v[2].iov_len;
479 
480 	/* Now force a reallocation by asking for more space in only 2
481 	 * buffers. */
482 	n = evbuffer_reserve_space(buf, sz+128, v, 2);
483 	evbuffer_validate(buf);
484 	if (add_data) {
485 		tt_int_op(n, ==, 2);
486 		tt_assert(cp1 == v[0].iov_base);
487 	} else {
488 		tt_int_op(n, ==, 1);
489 	}
490 
491 end:
492 	evbuffer_free(buf);
493 }
494 
495 static void
496 test_evbuffer_expand(void *ptr)
497 {
498 	char data[4096];
499 	struct evbuffer *buf;
500 	size_t a,w,u;
501 	void *buffer;
502 
503 	memset(data, 'X', sizeof(data));
504 
505 	/* Make sure that expand() works on an empty buffer */
506 	buf = evbuffer_new();
507 	tt_int_op(evbuffer_expand(buf, 20000), ==, 0);
508 	evbuffer_validate(buf);
509 	a=w=u=0;
510 	evbuffer_get_waste(buf, &a,&w,&u);
511 	tt_assert(w == 0);
512 	tt_assert(u == 0);
513 	tt_assert(a >= 20000);
514 	tt_assert(buf->first);
515 	tt_assert(buf->first == buf->last);
516 	tt_assert(buf->first->off == 0);
517 	tt_assert(buf->first->buffer_len >= 20000);
518 
519 	/* Make sure that expand() works as a no-op when there's enough
520 	 * contiguous space already. */
521 	buffer = buf->first->buffer;
522 	evbuffer_add(buf, data, 1024);
523 	tt_int_op(evbuffer_expand(buf, 1024), ==, 0);
524 	tt_assert(buf->first->buffer == buffer);
525 	evbuffer_validate(buf);
526 	evbuffer_free(buf);
527 
528 	/* Make sure that expand() can work by moving misaligned data
529 	 * when it makes sense to do so. */
530 	buf = evbuffer_new();
531 	evbuffer_add(buf, data, 400);
532 	{
533 		int n = (int)(buf->first->buffer_len - buf->first->off - 1);
534 		tt_assert(n < (int)sizeof(data));
535 		evbuffer_add(buf, data, n);
536 	}
537 	tt_assert(buf->first == buf->last);
538 	tt_assert(buf->first->off == buf->first->buffer_len - 1);
539 	evbuffer_drain(buf, buf->first->off - 1);
540 	tt_assert(1 == evbuffer_get_length(buf));
541 	tt_assert(buf->first->misalign > 0);
542 	tt_assert(buf->first->off == 1);
543 	buffer = buf->first->buffer;
544 	tt_assert(evbuffer_expand(buf, 40) == 0);
545 	tt_assert(buf->first == buf->last);
546 	tt_assert(buf->first->off == 1);
547 	tt_assert(buf->first->buffer == buffer);
548 	tt_assert(buf->first->misalign == 0);
549 	evbuffer_validate(buf);
550 	evbuffer_free(buf);
551 
552 	/* add, expand, pull-up: This used to crash libevent. */
553 	buf = evbuffer_new();
554 
555 	evbuffer_add(buf, data, sizeof(data));
556 	evbuffer_add(buf, data, sizeof(data));
557 	evbuffer_add(buf, data, sizeof(data));
558 
559 	evbuffer_validate(buf);
560 	evbuffer_expand(buf, 1024);
561 	evbuffer_validate(buf);
562 	evbuffer_pullup(buf, -1);
563 	evbuffer_validate(buf);
564 
565 end:
566 	evbuffer_free(buf);
567 }
568 
569 
570 static int reference_cb_called;
571 static void
572 reference_cb(const void *data, size_t len, void *extra)
573 {
574 	tt_str_op(data, ==, "this is what we add as read-only memory.");
575 	tt_int_op(len, ==, strlen(data));
576 	tt_want(extra == (void *)0xdeadaffe);
577 	++reference_cb_called;
578 end:
579 	;
580 }
581 
582 static void
583 test_evbuffer_reference(void *ptr)
584 {
585 	struct evbuffer *src = evbuffer_new();
586 	struct evbuffer *dst = evbuffer_new();
587 	struct evbuffer_iovec v[1];
588 	const char *data = "this is what we add as read-only memory.";
589 	reference_cb_called = 0;
590 
591 	tt_assert(evbuffer_add_reference(src, data, strlen(data),
592 		 reference_cb, (void *)0xdeadaffe) != -1);
593 
594 	evbuffer_reserve_space(dst, strlen(data), v, 1);
595 	tt_assert(evbuffer_remove(src, v[0].iov_base, 10) != -1);
596 
597 	evbuffer_validate(src);
598 	evbuffer_validate(dst);
599 
600 	/* make sure that we don't write data at the beginning */
601 	evbuffer_prepend(src, "aaaaa", 5);
602 	evbuffer_validate(src);
603 	evbuffer_drain(src, 5);
604 
605 	tt_assert(evbuffer_remove(src, ((char*)(v[0].iov_base)) + 10,
606 		strlen(data) - 10) != -1);
607 
608 	v[0].iov_len = strlen(data);
609 
610 	evbuffer_commit_space(dst, v, 1);
611 	evbuffer_validate(src);
612 	evbuffer_validate(dst);
613 
614 	tt_int_op(reference_cb_called, ==, 1);
615 
616 	tt_assert(!memcmp(evbuffer_pullup(dst, strlen(data)),
617 			  data, strlen(data)));
618 	evbuffer_validate(dst);
619 
620  end:
621 	evbuffer_free(dst);
622 	evbuffer_free(src);
623 }
624 
625 static struct event_base *addfile_test_event_base = NULL;
626 static int addfile_test_done_writing = 0;
627 static int addfile_test_total_written = 0;
628 static int addfile_test_total_read = 0;
629 
630 static void
631 addfile_test_writecb(evutil_socket_t fd, short what, void *arg)
632 {
633 	struct evbuffer *b = arg;
634 	int r;
635 	evbuffer_validate(b);
636 	while (evbuffer_get_length(b)) {
637 		r = evbuffer_write(b, fd);
638 		if (r > 0) {
639 			addfile_test_total_written += r;
640 			TT_BLATHER(("Wrote %d/%d bytes", r, addfile_test_total_written));
641 		} else {
642 			int e = evutil_socket_geterror(fd);
643 			if (EVUTIL_ERR_RW_RETRIABLE(e))
644 				return;
645 			tt_fail_perror("write");
646 			event_base_loopexit(addfile_test_event_base,NULL);
647 		}
648 		evbuffer_validate(b);
649 	}
650 	addfile_test_done_writing = 1;
651 	return;
652 end:
653 	event_base_loopexit(addfile_test_event_base,NULL);
654 }
655 
656 static void
657 addfile_test_readcb(evutil_socket_t fd, short what, void *arg)
658 {
659 	struct evbuffer *b = arg;
660 	int e, r = 0;
661 	do {
662 		r = evbuffer_read(b, fd, 1024);
663 		if (r > 0) {
664 			addfile_test_total_read += r;
665 			TT_BLATHER(("Read %d/%d bytes", r, addfile_test_total_read));
666 		}
667 	} while (r > 0);
668 	if (r < 0) {
669 		e = evutil_socket_geterror(fd);
670 		if (! EVUTIL_ERR_RW_RETRIABLE(e)) {
671 			tt_fail_perror("read");
672 			event_base_loopexit(addfile_test_event_base,NULL);
673 		}
674 	}
675 	if (addfile_test_done_writing &&
676 	    addfile_test_total_read >= addfile_test_total_written) {
677 		event_base_loopexit(addfile_test_event_base,NULL);
678 	}
679 }
680 
681 static void
682 test_evbuffer_add_file(void *ptr)
683 {
684 	struct basic_test_data *testdata = ptr;
685 	const char *impl = testdata->setup_data;
686 	struct evbuffer *src = evbuffer_new(), *dest = evbuffer_new();
687 	char *tmpfilename = NULL;
688 	char *data = NULL;
689 	const char *expect_data;
690 	size_t datalen, expect_len;
691 	const char *compare;
692 	int fd = -1;
693 	int want_ismapping = -1, want_cansendfile = -1;
694 	unsigned flags = 0;
695 	int use_segment = 1, use_bigfile = 0, map_from_offset = 0,
696 	    view_from_offset = 0;
697 	struct evbuffer_file_segment *seg = NULL;
698 	ev_off_t starting_offset = 0, mapping_len = -1;
699 	ev_off_t segment_offset = 0, segment_len = -1;
700 	struct event *rev=NULL, *wev=NULL;
701 	struct event_base *base = testdata->base;
702 	evutil_socket_t pair[2] = {-1, -1};
703 	struct evutil_weakrand_state seed = { 123456789U };
704 
705 	/* This test is highly parameterized based on substrings of its
706 	 * argument.  The strings are: */
707 	tt_assert(impl);
708 	if (strstr(impl, "nosegment")) {
709 		/* If nosegment is set, use the older evbuffer_add_file
710 		 * interface */
711 		use_segment = 0;
712 	}
713 	if (strstr(impl, "bigfile")) {
714 		/* If bigfile is set, use a 512K file.  Else use a smaller
715 		 * one. */
716 		use_bigfile = 1;
717 	}
718 	if (strstr(impl, "map_offset")) {
719 		/* If map_offset is set, we build the file segment starting
720 		 * from a point other than byte 0 and ending somewhere other
721 		 * than the last byte.  Otherwise we map the whole thing */
722 		map_from_offset = 1;
723 	}
724 	if (strstr(impl, "offset_in_segment")) {
725 		/* If offset_in_segment is set, we add a subsection of the
726 		 * file semgment starting from a point other than byte 0 of
727 		 * the segment. */
728 		view_from_offset = 1;
729 	}
730 	if (strstr(impl, "sendfile")) {
731 		/* If sendfile is set, we try to use a sendfile/splice style
732 		 * backend. */
733 		flags = EVBUF_FS_DISABLE_MMAP;
734 		want_cansendfile = 1;
735 		want_ismapping = 0;
736 	} else if (strstr(impl, "mmap")) {
737 		/* If sendfile is set, we try to use a mmap/CreateFileMapping
738 		 * style backend. */
739 		flags = EVBUF_FS_DISABLE_SENDFILE;
740 		want_ismapping = 1;
741 		want_cansendfile = 0;
742 	} else if (strstr(impl, "linear")) {
743 		/* If linear is set, we try to use a read-the-whole-thing
744 		 * backend. */
745 		flags = EVBUF_FS_DISABLE_SENDFILE|EVBUF_FS_DISABLE_MMAP;
746 		want_ismapping = 0;
747 		want_cansendfile = 0;
748 	} else if (strstr(impl, "default")) {
749 		/* The caller doesn't care which backend we use. */
750 		;
751 	} else {
752 		/* The caller must choose a backend. */
753 		TT_DIE(("Didn't recognize the implementation"));
754 	}
755 
756 	if (use_bigfile) {
757 		unsigned int i;
758 		datalen = 1024*512;
759 		data = malloc(1024*512);
760 		tt_assert(data);
761 		for (i = 0; i < datalen; ++i)
762 			data[i] = (char)evutil_weakrand_(&seed);
763 	} else {
764 		data = strdup("here is a relatively small string.");
765 		tt_assert(data);
766 		datalen = strlen(data);
767 	}
768 
769 	fd = regress_make_tmpfile(data, datalen, &tmpfilename);
770 
771 	if (map_from_offset) {
772 		starting_offset = datalen/4 + 1;
773 		mapping_len = datalen / 2 - 1;
774 		expect_data = data + starting_offset;
775 		expect_len = mapping_len;
776 	} else {
777 		expect_data = data;
778 		expect_len = datalen;
779 	}
780 	if (view_from_offset) {
781 		tt_assert(use_segment); /* Can't do this with add_file*/
782 		segment_offset = expect_len / 3;
783 		segment_len = expect_len / 2;
784 		expect_data = expect_data + segment_offset;
785 		expect_len = segment_len;
786 	}
787 
788 	if (use_segment) {
789 		seg = evbuffer_file_segment_new(fd, starting_offset,
790 		    mapping_len, flags);
791 		tt_assert(seg);
792 		if (want_ismapping >= 0) {
793 			if (seg->is_mapping != (unsigned)want_ismapping)
794 				tt_skip();
795 		}
796 		if (want_cansendfile >= 0) {
797 			if (seg->can_sendfile != (unsigned)want_cansendfile)
798 				tt_skip();
799 		}
800 	}
801 
802 	/* Say that it drains to a fd so that we can use sendfile. */
803 	evbuffer_set_flags(src, EVBUFFER_FLAG_DRAINS_TO_FD);
804 
805 #if defined(EVENT__HAVE_SENDFILE) && defined(__sun__) && defined(__svr4__)
806 	/* We need to use a pair of AF_INET sockets, since Solaris
807 	   doesn't support sendfile() over AF_UNIX. */
808 	if (evutil_ersatz_socketpair_(AF_INET, SOCK_STREAM, 0, pair) == -1)
809 		tt_abort_msg("ersatz_socketpair failed");
810 #else
811 	if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1)
812 		tt_abort_msg("socketpair failed");
813 #endif
814 	evutil_make_socket_nonblocking(pair[0]);
815 	evutil_make_socket_nonblocking(pair[1]);
816 
817 	tt_assert(fd != -1);
818 
819 	if (use_segment) {
820 		tt_assert(evbuffer_add_file_segment(src, seg,
821 			segment_offset, segment_len)!=-1);
822 	} else {
823 		tt_assert(evbuffer_add_file(src, fd, starting_offset,
824 			mapping_len) != -1);
825 	}
826 
827 	evbuffer_validate(src);
828 
829 	addfile_test_event_base = base;
830 	wev = event_new(base, pair[0], EV_WRITE|EV_PERSIST,
831 	    addfile_test_writecb, src);
832 	rev = event_new(base, pair[1], EV_READ|EV_PERSIST,
833 	    addfile_test_readcb, dest);
834 
835 	event_add(wev, NULL);
836 	event_add(rev, NULL);
837 	event_base_dispatch(base);
838 
839 	evbuffer_validate(src);
840 	evbuffer_validate(dest);
841 
842 	tt_assert(addfile_test_done_writing);
843 	tt_int_op(addfile_test_total_written, ==, expect_len);
844 	tt_int_op(addfile_test_total_read, ==, expect_len);
845 
846 	compare = (char *)evbuffer_pullup(dest, expect_len);
847 	tt_assert(compare != NULL);
848 	if (memcmp(compare, expect_data, expect_len)) {
849 		tt_abort_msg("Data from add_file differs.");
850 	}
851 
852 	evbuffer_validate(dest);
853  end:
854 	if (data)
855 		free(data);
856 	if (seg)
857 		evbuffer_file_segment_free(seg);
858 	if (src)
859 		evbuffer_free(src);
860 	if (dest)
861 		evbuffer_free(dest);
862 	if (pair[0] >= 0)
863 		evutil_closesocket(pair[0]);
864 	if (pair[1] >= 0)
865 		evutil_closesocket(pair[1]);
866 	if (wev)
867 		event_free(wev);
868 	if (rev)
869 		event_free(rev);
870 	if (tmpfilename) {
871 		unlink(tmpfilename);
872 		free(tmpfilename);
873 	}
874 }
875 
876 static int file_segment_cleanup_cb_called_count = 0;
877 static struct evbuffer_file_segment const* file_segment_cleanup_cb_called_with = NULL;
878 static int file_segment_cleanup_cb_called_with_flags = 0;
879 static void* file_segment_cleanup_cb_called_with_arg = NULL;
880 static void
881 file_segment_cleanup_cp(struct evbuffer_file_segment const* seg, int flags, void* arg)
882 {
883 	++file_segment_cleanup_cb_called_count;
884 	file_segment_cleanup_cb_called_with = seg;
885 	file_segment_cleanup_cb_called_with_flags = flags;
886 	file_segment_cleanup_cb_called_with_arg = arg;
887 }
888 
889 static void
890 test_evbuffer_file_segment_add_cleanup_cb(void* ptr)
891 {
892 	char *tmpfilename = NULL;
893 	int fd = -1;
894 	struct evbuffer *evb = NULL;
895 	struct evbuffer_file_segment *seg = NULL, *segptr;
896 	char const* arg = "token";
897 
898 	fd = regress_make_tmpfile("file_segment_test_file", 22, &tmpfilename);
899 	tt_int_op(fd, >=, 0);
900 
901 	evb = evbuffer_new();
902 	tt_assert(evb);
903 
904 	segptr = seg = evbuffer_file_segment_new(fd, 0, -1, 0);
905 	tt_assert(seg);
906 
907 	evbuffer_file_segment_add_cleanup_cb(
908 	  seg, &file_segment_cleanup_cp, (void*)arg);
909 
910 	tt_assert(fd != -1);
911 
912 	tt_assert(evbuffer_add_file_segment(evb, seg, 0, -1)!=-1);
913 
914 	evbuffer_validate(evb);
915 
916 	tt_int_op(file_segment_cleanup_cb_called_count, ==, 0);
917 	evbuffer_file_segment_free(seg);
918 	seg = NULL; /* Prevent double-free. */
919 
920 	tt_int_op(file_segment_cleanup_cb_called_count, ==, 0);
921 	evbuffer_free(evb);
922 	evb = NULL; /* pevent double-free */
923 
924 	tt_int_op(file_segment_cleanup_cb_called_count, ==, 1);
925 	tt_assert(file_segment_cleanup_cb_called_with == segptr);
926 	tt_assert(file_segment_cleanup_cb_called_with_flags == 0);
927 	tt_assert(file_segment_cleanup_cb_called_with_arg == (void*)arg);
928 
929 end:
930 	if (evb)
931 		evbuffer_free(evb);
932 	if (seg)
933 		evbuffer_file_segment_free(seg);
934 	if (tmpfilename) {
935 		unlink(tmpfilename);
936 		free(tmpfilename);
937 	}
938 }
939 
940 #ifndef EVENT__DISABLE_MM_REPLACEMENT
941 static void *
942 failing_malloc(size_t how_much)
943 {
944 	errno = ENOMEM;
945 	return NULL;
946 }
947 #endif
948 
949 static void
950 test_evbuffer_readln(void *ptr)
951 {
952 	struct evbuffer *evb = evbuffer_new();
953 	struct evbuffer *evb_tmp = evbuffer_new();
954 	const char *s;
955 	char *cp = NULL;
956 	size_t sz;
957 
958 #define tt_line_eq(content)						\
959 	TT_STMT_BEGIN							\
960 	if (!cp || sz != strlen(content) || strcmp(cp, content)) {	\
961 		TT_DIE(("Wanted %s; got %s [%d]", content, cp, (int)sz)); \
962 	}								\
963 	TT_STMT_END
964 
965 	/* Test EOL_ANY. */
966 	s = "complex silly newline\r\n\n\r\n\n\rmore\0\n";
967 	evbuffer_add(evb, s, strlen(s)+2);
968 	evbuffer_validate(evb);
969 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY);
970 	tt_line_eq("complex silly newline");
971 	free(cp);
972 	evbuffer_validate(evb);
973 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY);
974 	if (!cp || sz != 5 || memcmp(cp, "more\0\0", 6))
975 		tt_abort_msg("Not as expected");
976 	tt_uint_op(evbuffer_get_length(evb), ==, 0);
977 	evbuffer_validate(evb);
978 	s = "\nno newline";
979 	evbuffer_add(evb, s, strlen(s));
980 	free(cp);
981 	evbuffer_validate(evb);
982 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY);
983 	tt_line_eq("");
984 	free(cp);
985 	evbuffer_validate(evb);
986 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY);
987 	tt_assert(!cp);
988 	evbuffer_validate(evb);
989 	evbuffer_drain(evb, evbuffer_get_length(evb));
990 	tt_assert(evbuffer_get_length(evb) == 0);
991 	evbuffer_validate(evb);
992 
993 	/* Test EOL_CRLF */
994 	s = "Line with\rin the middle\nLine with good crlf\r\n\nfinal\n";
995 	evbuffer_add(evb, s, strlen(s));
996 	evbuffer_validate(evb);
997 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
998 	tt_line_eq("Line with\rin the middle");
999 	free(cp);
1000 	evbuffer_validate(evb);
1001 
1002 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
1003 	tt_line_eq("Line with good crlf");
1004 	free(cp);
1005 	evbuffer_validate(evb);
1006 
1007 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
1008 	tt_line_eq("");
1009 	free(cp);
1010 	evbuffer_validate(evb);
1011 
1012 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
1013 	tt_line_eq("final");
1014 	s = "x";
1015 	evbuffer_validate(evb);
1016 	evbuffer_add(evb, s, 1);
1017 	evbuffer_validate(evb);
1018 	free(cp);
1019 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
1020 	tt_assert(!cp);
1021 	evbuffer_validate(evb);
1022 
1023 	/* Test CRLF_STRICT */
1024 	s = " and a bad crlf\nand a good one\r\n\r\nMore\r";
1025 	evbuffer_add(evb, s, strlen(s));
1026 	evbuffer_validate(evb);
1027 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1028 	tt_line_eq("x and a bad crlf\nand a good one");
1029 	free(cp);
1030 	evbuffer_validate(evb);
1031 
1032 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1033 	tt_line_eq("");
1034 	free(cp);
1035 	evbuffer_validate(evb);
1036 
1037 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1038 	tt_assert(!cp);
1039 	evbuffer_validate(evb);
1040 	evbuffer_add(evb, "\n", 1);
1041 	evbuffer_validate(evb);
1042 
1043 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1044 	tt_line_eq("More");
1045 	free(cp);
1046 	tt_assert(evbuffer_get_length(evb) == 0);
1047 	evbuffer_validate(evb);
1048 
1049 	s = "An internal CR\r is not an eol\r\nNor is a lack of one";
1050 	evbuffer_add(evb, s, strlen(s));
1051 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1052 	tt_line_eq("An internal CR\r is not an eol");
1053 	free(cp);
1054 	evbuffer_validate(evb);
1055 
1056 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1057 	tt_assert(!cp);
1058 	evbuffer_validate(evb);
1059 
1060 	evbuffer_add(evb, "\r\n", 2);
1061 	evbuffer_validate(evb);
1062 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1063 	tt_line_eq("Nor is a lack of one");
1064 	free(cp);
1065 	tt_assert(evbuffer_get_length(evb) == 0);
1066 	evbuffer_validate(evb);
1067 
1068 	/* Test LF */
1069 	s = "An\rand a nl\n\nText";
1070 	evbuffer_add(evb, s, strlen(s));
1071 	evbuffer_validate(evb);
1072 
1073 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
1074 	tt_line_eq("An\rand a nl");
1075 	free(cp);
1076 	evbuffer_validate(evb);
1077 
1078 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
1079 	tt_line_eq("");
1080 	free(cp);
1081 	evbuffer_validate(evb);
1082 
1083 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
1084 	tt_assert(!cp);
1085 	free(cp);
1086 	evbuffer_add(evb, "\n", 1);
1087 	evbuffer_validate(evb);
1088 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
1089 	tt_line_eq("Text");
1090 	free(cp);
1091 	evbuffer_validate(evb);
1092 
1093 	/* Test NUL */
1094 	tt_int_op(evbuffer_get_length(evb), ==, 0);
1095 	{
1096 		char x[] =
1097 		    "NUL\n\0\0"
1098 		    "The all-zeros character which may serve\0"
1099 		    "to accomplish time fill\0and media fill";
1100 		/* Add all but the final NUL of x. */
1101 		evbuffer_add(evb, x, sizeof(x)-1);
1102 	}
1103 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_NUL);
1104 	tt_line_eq("NUL\n");
1105 	free(cp);
1106 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_NUL);
1107 	tt_line_eq("");
1108 	free(cp);
1109 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_NUL);
1110 	tt_line_eq("The all-zeros character which may serve");
1111 	free(cp);
1112 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_NUL);
1113 	tt_line_eq("to accomplish time fill");
1114 	free(cp);
1115 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_NUL);
1116 	tt_ptr_op(cp, ==, NULL);
1117 	evbuffer_drain(evb, -1);
1118 
1119 	/* Test CRLF_STRICT - across boundaries*/
1120 	s = " and a bad crlf\nand a good one\r";
1121 	evbuffer_add(evb_tmp, s, strlen(s));
1122 	evbuffer_validate(evb);
1123 	evbuffer_add_buffer(evb, evb_tmp);
1124 	evbuffer_validate(evb);
1125 	s = "\n\r";
1126 	evbuffer_add(evb_tmp, s, strlen(s));
1127 	evbuffer_validate(evb);
1128 	evbuffer_add_buffer(evb, evb_tmp);
1129 	evbuffer_validate(evb);
1130 	s = "\nMore\r";
1131 	evbuffer_add(evb_tmp, s, strlen(s));
1132 	evbuffer_validate(evb);
1133 	evbuffer_add_buffer(evb, evb_tmp);
1134 	evbuffer_validate(evb);
1135 
1136 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1137 	tt_line_eq(" and a bad crlf\nand a good one");
1138 	free(cp);
1139 	evbuffer_validate(evb);
1140 
1141 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1142 	tt_line_eq("");
1143 	free(cp);
1144 	evbuffer_validate(evb);
1145 
1146 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1147 	tt_assert(!cp);
1148 	free(cp);
1149 	evbuffer_validate(evb);
1150 	evbuffer_add(evb, "\n", 1);
1151 	evbuffer_validate(evb);
1152 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1153 	tt_line_eq("More");
1154 	free(cp); cp = NULL;
1155 	evbuffer_validate(evb);
1156 	tt_assert(evbuffer_get_length(evb) == 0);
1157 
1158 	/* Test memory problem*/
1159 	s = "one line\ntwo line\nblue line";
1160 	evbuffer_add(evb_tmp, s, strlen(s));
1161 	evbuffer_validate(evb);
1162 	evbuffer_add_buffer(evb, evb_tmp);
1163 	evbuffer_validate(evb);
1164 
1165 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
1166 	tt_line_eq("one line");
1167 	free(cp); cp = NULL;
1168 	evbuffer_validate(evb);
1169 
1170 	/* the next call to readline should fail */
1171 #ifndef EVENT__DISABLE_MM_REPLACEMENT
1172 	event_set_mem_functions(failing_malloc, realloc, free);
1173 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
1174 	tt_assert(cp == NULL);
1175 	evbuffer_validate(evb);
1176 
1177 	/* now we should get the next line back */
1178 	event_set_mem_functions(malloc, realloc, free);
1179 #endif
1180 	cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
1181 	tt_line_eq("two line");
1182 	free(cp); cp = NULL;
1183 	evbuffer_validate(evb);
1184 
1185  end:
1186 	evbuffer_free(evb);
1187 	evbuffer_free(evb_tmp);
1188 	if (cp) free(cp);
1189 }
1190 
1191 static void
1192 test_evbuffer_search_eol(void *ptr)
1193 {
1194 	struct evbuffer *buf = evbuffer_new();
1195 	struct evbuffer_ptr ptr1, ptr2;
1196 	const char *s;
1197 	size_t eol_len;
1198 
1199 	s = "string! \r\n\r\nx\n";
1200 	evbuffer_add(buf, s, strlen(s));
1201 	eol_len = -1;
1202 	ptr1 = evbuffer_search_eol(buf, NULL, &eol_len, EVBUFFER_EOL_CRLF);
1203 	tt_int_op(ptr1.pos, ==, 8);
1204 	tt_int_op(eol_len, ==, 2);
1205 
1206 	eol_len = -1;
1207 	ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_CRLF);
1208 	tt_int_op(ptr2.pos, ==, 8);
1209 	tt_int_op(eol_len, ==, 2);
1210 
1211 	evbuffer_ptr_set(buf, &ptr1, 1, EVBUFFER_PTR_ADD);
1212 	eol_len = -1;
1213 	ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_CRLF);
1214 	tt_int_op(ptr2.pos, ==, 9);
1215 	tt_int_op(eol_len, ==, 1);
1216 
1217 	eol_len = -1;
1218 	ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_CRLF_STRICT);
1219 	tt_int_op(ptr2.pos, ==, 10);
1220 	tt_int_op(eol_len, ==, 2);
1221 
1222 	eol_len = -1;
1223 	ptr1 = evbuffer_search_eol(buf, NULL, &eol_len, EVBUFFER_EOL_LF);
1224 	tt_int_op(ptr1.pos, ==, 9);
1225 	tt_int_op(eol_len, ==, 1);
1226 
1227 	eol_len = -1;
1228 	ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_LF);
1229 	tt_int_op(ptr2.pos, ==, 9);
1230 	tt_int_op(eol_len, ==, 1);
1231 
1232 	evbuffer_ptr_set(buf, &ptr1, 1, EVBUFFER_PTR_ADD);
1233 	eol_len = -1;
1234 	ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_LF);
1235 	tt_int_op(ptr2.pos, ==, 11);
1236 	tt_int_op(eol_len, ==, 1);
1237 
1238 	tt_assert(evbuffer_ptr_set(buf, &ptr1, evbuffer_get_length(buf), EVBUFFER_PTR_SET) == 0);
1239 	eol_len = -1;
1240 	ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_LF);
1241 	tt_int_op(ptr2.pos, ==, -1);
1242 	tt_int_op(eol_len, ==, 0);
1243 
1244 end:
1245 	evbuffer_free(buf);
1246 }
1247 
1248 static void
1249 test_evbuffer_iterative(void *ptr)
1250 {
1251 	struct evbuffer *buf = evbuffer_new();
1252 	const char *abc = "abcdefghijklmnopqrstvuwxyzabcdefghijklmnopqrstvuwxyzabcdefghijklmnopqrstvuwxyzabcdefghijklmnopqrstvuwxyz";
1253 	unsigned i, j, sum, n;
1254 
1255 	sum = 0;
1256 	n = 0;
1257 	for (i = 0; i < 1000; ++i) {
1258 		for (j = 1; j < strlen(abc); ++j) {
1259 			char format[32];
1260 			evutil_snprintf(format, sizeof(format), "%%%u.%us", j, j);
1261 			evbuffer_add_printf(buf, format, abc);
1262 
1263 			/* Only check for rep violations every so often.
1264 			   Walking over the whole list of chains can get
1265 			   pretty expensive as it gets long.
1266 			 */
1267 			if ((n % 337) == 0)
1268 				evbuffer_validate(buf);
1269 
1270 			sum += j;
1271 			n++;
1272 		}
1273 	}
1274 	evbuffer_validate(buf);
1275 
1276 	tt_uint_op(sum, ==, evbuffer_get_length(buf));
1277 
1278 	{
1279 		size_t a,w,u;
1280 		a=w=u=0;
1281 		evbuffer_get_waste(buf, &a, &w, &u);
1282 		if (0)
1283 			printf("Allocated: %u.\nWasted: %u.\nUsed: %u.",
1284 			    (unsigned)a, (unsigned)w, (unsigned)u);
1285 		tt_assert( ((double)w)/a < .125);
1286 	}
1287  end:
1288 	evbuffer_free(buf);
1289 
1290 }
1291 
1292 static void
1293 test_evbuffer_find(void *ptr)
1294 {
1295 	u_char* p;
1296 	const char* test1 = "1234567890\r\n";
1297 	const char* test2 = "1234567890\r";
1298 #define EVBUFFER_INITIAL_LENGTH 256
1299 	char test3[EVBUFFER_INITIAL_LENGTH];
1300 	unsigned int i;
1301 	struct evbuffer * buf = evbuffer_new();
1302 
1303 	tt_assert(buf);
1304 
1305 	/* make sure evbuffer_find doesn't match past the end of the buffer */
1306 	evbuffer_add(buf, (u_char*)test1, strlen(test1));
1307 	evbuffer_validate(buf);
1308 	evbuffer_drain(buf, strlen(test1));
1309 	evbuffer_validate(buf);
1310 	evbuffer_add(buf, (u_char*)test2, strlen(test2));
1311 	evbuffer_validate(buf);
1312 	p = evbuffer_find(buf, (u_char*)"\r\n", 2);
1313 	tt_want(p == NULL);
1314 
1315 	/*
1316 	 * drain the buffer and do another find; in r309 this would
1317 	 * read past the allocated buffer causing a valgrind error.
1318 	 */
1319 	evbuffer_drain(buf, strlen(test2));
1320 	evbuffer_validate(buf);
1321 	for (i = 0; i < EVBUFFER_INITIAL_LENGTH; ++i)
1322 		test3[i] = 'a';
1323 	test3[EVBUFFER_INITIAL_LENGTH - 1] = 'x';
1324 	evbuffer_add(buf, (u_char *)test3, EVBUFFER_INITIAL_LENGTH);
1325 	evbuffer_validate(buf);
1326 	p = evbuffer_find(buf, (u_char *)"xy", 2);
1327 	tt_want(p == NULL);
1328 
1329 	/* simple test for match at end of allocated buffer */
1330 	p = evbuffer_find(buf, (u_char *)"ax", 2);
1331 	tt_assert(p != NULL);
1332 	tt_want(strncmp((char*)p, "ax", 2) == 0);
1333 
1334 end:
1335 	if (buf)
1336 		evbuffer_free(buf);
1337 }
1338 
1339 static void
1340 test_evbuffer_ptr_set(void *ptr)
1341 {
1342 	struct evbuffer *buf = evbuffer_new();
1343 	struct evbuffer_ptr pos;
1344 	struct evbuffer_iovec v[1];
1345 
1346 	tt_assert(buf);
1347 
1348 	tt_int_op(evbuffer_get_length(buf), ==, 0);
1349 
1350 	tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
1351 	tt_assert(pos.pos == 0);
1352 	tt_assert(evbuffer_ptr_set(buf, &pos, 1, EVBUFFER_PTR_ADD) == -1);
1353 	tt_assert(pos.pos == -1);
1354 	tt_assert(evbuffer_ptr_set(buf, &pos, 1, EVBUFFER_PTR_SET) == -1);
1355 	tt_assert(pos.pos == -1);
1356 
1357 	/* create some chains */
1358 	evbuffer_reserve_space(buf, 5000, v, 1);
1359 	v[0].iov_len = 5000;
1360 	memset(v[0].iov_base, 1, v[0].iov_len);
1361 	evbuffer_commit_space(buf, v, 1);
1362 	evbuffer_validate(buf);
1363 
1364 	evbuffer_reserve_space(buf, 4000, v, 1);
1365 	v[0].iov_len = 4000;
1366 	memset(v[0].iov_base, 2, v[0].iov_len);
1367 	evbuffer_commit_space(buf, v, 1);
1368 
1369 	evbuffer_reserve_space(buf, 3000, v, 1);
1370 	v[0].iov_len = 3000;
1371 	memset(v[0].iov_base, 3, v[0].iov_len);
1372 	evbuffer_commit_space(buf, v, 1);
1373 	evbuffer_validate(buf);
1374 
1375 	tt_int_op(evbuffer_get_length(buf), ==, 12000);
1376 
1377 	tt_assert(evbuffer_ptr_set(buf, &pos, 13000, EVBUFFER_PTR_SET) == -1);
1378 	tt_assert(pos.pos == -1);
1379 	tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
1380 	tt_assert(pos.pos == 0);
1381 	tt_assert(evbuffer_ptr_set(buf, &pos, 13000, EVBUFFER_PTR_ADD) == -1);
1382 
1383 	tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
1384 	tt_assert(pos.pos == 0);
1385 	tt_assert(evbuffer_ptr_set(buf, &pos, 10000, EVBUFFER_PTR_ADD) == 0);
1386 	tt_assert(pos.pos == 10000);
1387 	tt_assert(evbuffer_ptr_set(buf, &pos, 1000, EVBUFFER_PTR_ADD) == 0);
1388 	tt_assert(pos.pos == 11000);
1389 	tt_assert(evbuffer_ptr_set(buf, &pos, 1000, EVBUFFER_PTR_ADD) == 0);
1390 	tt_assert(pos.pos == 12000);
1391 	tt_assert(evbuffer_ptr_set(buf, &pos, 1000, EVBUFFER_PTR_ADD) == -1);
1392 	tt_assert(pos.pos == -1);
1393 
1394 end:
1395 	if (buf)
1396 		evbuffer_free(buf);
1397 }
1398 
1399 static void
1400 test_evbuffer_search(void *ptr)
1401 {
1402 	struct evbuffer *buf = evbuffer_new();
1403 	struct evbuffer *tmp = evbuffer_new();
1404 	struct evbuffer_ptr pos, end;
1405 
1406 	tt_assert(buf);
1407 	tt_assert(tmp);
1408 
1409 	pos = evbuffer_search(buf, "x", 1, NULL);
1410 	tt_int_op(pos.pos, ==, -1);
1411 	tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
1412 	pos = evbuffer_search(buf, "x", 1, &pos);
1413 	tt_int_op(pos.pos, ==, -1);
1414 	tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
1415 	pos = evbuffer_search_range(buf, "x", 1, &pos, &pos);
1416 	tt_int_op(pos.pos, ==, -1);
1417 	tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
1418 	pos = evbuffer_search_range(buf, "x", 1, &pos, NULL);
1419 	tt_int_op(pos.pos, ==, -1);
1420 
1421 	/* set up our chains */
1422 	evbuffer_add_printf(tmp, "hello");  /* 5 chars */
1423 	evbuffer_add_buffer(buf, tmp);
1424 	evbuffer_add_printf(tmp, "foo");    /* 3 chars */
1425 	evbuffer_add_buffer(buf, tmp);
1426 	evbuffer_add_printf(tmp, "cat");    /* 3 chars */
1427 	evbuffer_add_buffer(buf, tmp);
1428 	evbuffer_add_printf(tmp, "attack");
1429 	evbuffer_add_buffer(buf, tmp);
1430 
1431 	pos = evbuffer_search(buf, "attack", 6, NULL);
1432 	tt_int_op(pos.pos, ==, 11);
1433 	pos = evbuffer_search(buf, "attacker", 8, NULL);
1434 	tt_int_op(pos.pos, ==, -1);
1435 
1436 	/* test continuing search */
1437 	pos = evbuffer_search(buf, "oc", 2, NULL);
1438 	tt_int_op(pos.pos, ==, 7);
1439 	pos = evbuffer_search(buf, "cat", 3, &pos);
1440 	tt_int_op(pos.pos, ==, 8);
1441 	pos = evbuffer_search(buf, "tacking", 7, &pos);
1442 	tt_int_op(pos.pos, ==, -1);
1443 
1444 	evbuffer_ptr_set(buf, &pos, 5, EVBUFFER_PTR_SET);
1445 	pos = evbuffer_search(buf, "foo", 3, &pos);
1446 	tt_int_op(pos.pos, ==, 5);
1447 
1448 	evbuffer_ptr_set(buf, &pos, 2, EVBUFFER_PTR_ADD);
1449 	pos = evbuffer_search(buf, "tat", 3, &pos);
1450 	tt_int_op(pos.pos, ==, 10);
1451 
1452 	/* test bounded search. */
1453 	/* Set "end" to the first t in "attack". */
1454 	evbuffer_ptr_set(buf, &end, 12, EVBUFFER_PTR_SET);
1455 	pos = evbuffer_search_range(buf, "foo", 3, NULL, &end);
1456 	tt_int_op(pos.pos, ==, 5);
1457 	pos = evbuffer_search_range(buf, "foocata", 7, NULL, &end);
1458 	tt_int_op(pos.pos, ==, 5);
1459 	pos = evbuffer_search_range(buf, "foocatat", 8, NULL, &end);
1460 	tt_int_op(pos.pos, ==, -1);
1461 	pos = evbuffer_search_range(buf, "ack", 3, NULL, &end);
1462 	tt_int_op(pos.pos, ==, -1);
1463 
1464 	/* Set "end" after the last byte in the buffer. */
1465 	tt_assert(evbuffer_ptr_set(buf, &end, 17, EVBUFFER_PTR_SET) == 0);
1466 
1467 	pos = evbuffer_search_range(buf, "attack", 6, NULL, &end);
1468 	tt_int_op(pos.pos, ==, 11);
1469 	tt_assert(evbuffer_ptr_set(buf, &pos, 11, EVBUFFER_PTR_SET) == 0);
1470 	pos = evbuffer_search_range(buf, "attack", 6, &pos, &end);
1471 	tt_int_op(pos.pos, ==, 11);
1472 	tt_assert(evbuffer_ptr_set(buf, &pos, 17, EVBUFFER_PTR_SET) == 0);
1473 	pos = evbuffer_search_range(buf, "attack", 6, &pos, &end);
1474 	tt_int_op(pos.pos, ==, -1);
1475 	tt_assert(evbuffer_ptr_set(buf, &pos, 17, EVBUFFER_PTR_SET) == 0);
1476 	pos = evbuffer_search_range(buf, "attack", 6, &pos, NULL);
1477 	tt_int_op(pos.pos, ==, -1);
1478 
1479 end:
1480 	if (buf)
1481 		evbuffer_free(buf);
1482 	if (tmp)
1483 		evbuffer_free(tmp);
1484 }
1485 
1486 static void
1487 log_change_callback(struct evbuffer *buffer,
1488     const struct evbuffer_cb_info *cbinfo,
1489     void *arg)
1490 {
1491 
1492 	size_t old_len = cbinfo->orig_size;
1493 	size_t new_len = old_len + cbinfo->n_added - cbinfo->n_deleted;
1494 	struct evbuffer *out = arg;
1495 	evbuffer_add_printf(out, "%lu->%lu; ", (unsigned long)old_len,
1496 			    (unsigned long)new_len);
1497 }
1498 static void
1499 self_draining_callback(struct evbuffer *evbuffer, size_t old_len,
1500 		size_t new_len, void *arg)
1501 {
1502 	if (new_len > old_len)
1503 		evbuffer_drain(evbuffer, new_len);
1504 }
1505 
1506 static void
1507 test_evbuffer_callbacks(void *ptr)
1508 {
1509 	struct evbuffer *buf = evbuffer_new();
1510 	struct evbuffer *buf_out1 = evbuffer_new();
1511 	struct evbuffer *buf_out2 = evbuffer_new();
1512 	struct evbuffer_cb_entry *cb1, *cb2;
1513 
1514 	tt_assert(buf);
1515 	tt_assert(buf_out1);
1516 	tt_assert(buf_out2);
1517 
1518 	cb1 = evbuffer_add_cb(buf, log_change_callback, buf_out1);
1519 	cb2 = evbuffer_add_cb(buf, log_change_callback, buf_out2);
1520 
1521 	/* Let's run through adding and deleting some stuff from the buffer
1522 	 * and turning the callbacks on and off and removing them.  The callback
1523 	 * adds a summary of length changes to buf_out1/buf_out2 when called. */
1524 	/* size: 0-> 36. */
1525 	evbuffer_add_printf(buf, "The %d magic words are spotty pudding", 2);
1526 	evbuffer_validate(buf);
1527 	evbuffer_cb_clear_flags(buf, cb2, EVBUFFER_CB_ENABLED);
1528 	evbuffer_drain(buf, 10); /*36->26*/
1529 	evbuffer_validate(buf);
1530 	evbuffer_prepend(buf, "Hello", 5);/*26->31*/
1531 	evbuffer_cb_set_flags(buf, cb2, EVBUFFER_CB_ENABLED);
1532 	evbuffer_add_reference(buf, "Goodbye", 7, NULL, NULL); /*31->38*/
1533 	evbuffer_remove_cb_entry(buf, cb1);
1534 	evbuffer_validate(buf);
1535 	evbuffer_drain(buf, evbuffer_get_length(buf)); /*38->0*/;
1536 	tt_assert(-1 == evbuffer_remove_cb(buf, log_change_callback, NULL));
1537 	evbuffer_add(buf, "X", 1); /* 0->1 */
1538 	tt_assert(!evbuffer_remove_cb(buf, log_change_callback, buf_out2));
1539 	evbuffer_validate(buf);
1540 
1541 	tt_str_op((const char *) evbuffer_pullup(buf_out1, -1), ==,
1542 		  "0->36; 36->26; 26->31; 31->38; ");
1543 	tt_str_op((const char *) evbuffer_pullup(buf_out2, -1), ==,
1544 		  "0->36; 31->38; 38->0; 0->1; ");
1545 	evbuffer_drain(buf_out1, evbuffer_get_length(buf_out1));
1546 	evbuffer_drain(buf_out2, evbuffer_get_length(buf_out2));
1547 	/* Let's test the obsolete buffer_setcb function too. */
1548 	cb1 = evbuffer_add_cb(buf, log_change_callback, buf_out1);
1549 	tt_assert(cb1 != NULL);
1550 	cb2 = evbuffer_add_cb(buf, log_change_callback, buf_out2);
1551 	tt_assert(cb2 != NULL);
1552 	evbuffer_setcb(buf, self_draining_callback, NULL);
1553 	evbuffer_add_printf(buf, "This should get drained right away.");
1554 	tt_uint_op(evbuffer_get_length(buf), ==, 0);
1555 	tt_uint_op(evbuffer_get_length(buf_out1), ==, 0);
1556 	tt_uint_op(evbuffer_get_length(buf_out2), ==, 0);
1557 	evbuffer_setcb(buf, NULL, NULL);
1558 	evbuffer_add_printf(buf, "This will not.");
1559 	tt_str_op((const char *) evbuffer_pullup(buf, -1), ==, "This will not.");
1560 	evbuffer_validate(buf);
1561 	evbuffer_drain(buf, evbuffer_get_length(buf));
1562 	evbuffer_validate(buf);
1563 #if 0
1564 	/* Now let's try a suspended callback. */
1565 	cb1 = evbuffer_add_cb(buf, log_change_callback, buf_out1);
1566 	cb2 = evbuffer_add_cb(buf, log_change_callback, buf_out2);
1567 	evbuffer_cb_suspend(buf,cb2);
1568 	evbuffer_prepend(buf,"Hello world",11); /*0->11*/
1569 	evbuffer_validate(buf);
1570 	evbuffer_cb_suspend(buf,cb1);
1571 	evbuffer_add(buf,"more",4); /* 11->15 */
1572 	evbuffer_cb_unsuspend(buf,cb2);
1573 	evbuffer_drain(buf, 4); /* 15->11 */
1574 	evbuffer_cb_unsuspend(buf,cb1);
1575 	evbuffer_drain(buf, evbuffer_get_length(buf)); /* 11->0 */
1576 
1577 	tt_str_op(evbuffer_pullup(buf_out1, -1), ==,
1578 		  "0->11; 11->11; 11->0; ");
1579 	tt_str_op(evbuffer_pullup(buf_out2, -1), ==,
1580 		  "0->15; 15->11; 11->0; ");
1581 #endif
1582 
1583  end:
1584 	if (buf)
1585 		evbuffer_free(buf);
1586 	if (buf_out1)
1587 		evbuffer_free(buf_out1);
1588 	if (buf_out2)
1589 		evbuffer_free(buf_out2);
1590 }
1591 
1592 static int ref_done_cb_called_count = 0;
1593 static void *ref_done_cb_called_with = NULL;
1594 static const void *ref_done_cb_called_with_data = NULL;
1595 static size_t ref_done_cb_called_with_len = 0;
1596 static void ref_done_cb(const void *data, size_t len, void *info)
1597 {
1598 	++ref_done_cb_called_count;
1599 	ref_done_cb_called_with = info;
1600 	ref_done_cb_called_with_data = data;
1601 	ref_done_cb_called_with_len = len;
1602 }
1603 
1604 static void
1605 test_evbuffer_add_reference(void *ptr)
1606 {
1607 	const char chunk1[] = "If you have found the answer to such a problem";
1608 	const char chunk2[] = "you ought to write it up for publication";
1609 			  /* -- Knuth's "Notes on the Exercises" from TAOCP */
1610 	char tmp[16];
1611 	size_t len1 = strlen(chunk1), len2=strlen(chunk2);
1612 
1613 	struct evbuffer *buf1 = NULL, *buf2 = NULL;
1614 
1615 	buf1 = evbuffer_new();
1616 	tt_assert(buf1);
1617 
1618 	evbuffer_add_reference(buf1, chunk1, len1, ref_done_cb, (void*)111);
1619 	evbuffer_add(buf1, ", ", 2);
1620 	evbuffer_add_reference(buf1, chunk2, len2, ref_done_cb, (void*)222);
1621 	tt_int_op(evbuffer_get_length(buf1), ==, len1+len2+2);
1622 
1623 	/* Make sure we can drain a little from a reference. */
1624 	tt_int_op(evbuffer_remove(buf1, tmp, 6), ==, 6);
1625 	tt_int_op(memcmp(tmp, "If you", 6), ==, 0);
1626 	tt_int_op(evbuffer_remove(buf1, tmp, 5), ==, 5);
1627 	tt_int_op(memcmp(tmp, " have", 5), ==, 0);
1628 
1629 	/* Make sure that prepending does not meddle with immutable data */
1630 	tt_int_op(evbuffer_prepend(buf1, "I have ", 7), ==, 0);
1631 	tt_int_op(memcmp(chunk1, "If you", 6), ==, 0);
1632 	evbuffer_validate(buf1);
1633 
1634 	/* Make sure that when the chunk is over, the callback is invoked. */
1635 	evbuffer_drain(buf1, 7); /* Remove prepended stuff. */
1636 	evbuffer_drain(buf1, len1-11-1); /* remove all but one byte of chunk1 */
1637 	tt_int_op(ref_done_cb_called_count, ==, 0);
1638 	evbuffer_remove(buf1, tmp, 1);
1639 	tt_int_op(tmp[0], ==, 'm');
1640 	tt_assert(ref_done_cb_called_with == (void*)111);
1641 	tt_assert(ref_done_cb_called_with_data == chunk1);
1642 	tt_assert(ref_done_cb_called_with_len == len1);
1643 	tt_int_op(ref_done_cb_called_count, ==, 1);
1644 	evbuffer_validate(buf1);
1645 
1646 	/* Drain some of the remaining chunk, then add it to another buffer */
1647 	evbuffer_drain(buf1, 6); /* Remove the ", you ". */
1648 	buf2 = evbuffer_new();
1649 	tt_assert(buf2);
1650 	tt_int_op(ref_done_cb_called_count, ==, 1);
1651 	evbuffer_add(buf2, "I ", 2);
1652 
1653 	evbuffer_add_buffer(buf2, buf1);
1654 	tt_int_op(ref_done_cb_called_count, ==, 1);
1655 	evbuffer_remove(buf2, tmp, 16);
1656 	tt_int_op(memcmp("I ought to write", tmp, 16), ==, 0);
1657 	evbuffer_drain(buf2, evbuffer_get_length(buf2));
1658 	tt_int_op(ref_done_cb_called_count, ==, 2);
1659 	tt_assert(ref_done_cb_called_with == (void*)222);
1660 	evbuffer_validate(buf2);
1661 
1662 	/* Now add more stuff to buf1 and make sure that it gets removed on
1663 	 * free. */
1664 	evbuffer_add(buf1, "You shake and shake the ", 24);
1665 	evbuffer_add_reference(buf1, "ketchup bottle", 14, ref_done_cb,
1666 	    (void*)3333);
1667 	evbuffer_add(buf1, ". Nothing comes and then a lot'll.", 35);
1668 	evbuffer_free(buf1);
1669 	buf1 = NULL;
1670 	tt_int_op(ref_done_cb_called_count, ==, 3);
1671 	tt_assert(ref_done_cb_called_with == (void*)3333);
1672 
1673 end:
1674 	if (buf1)
1675 		evbuffer_free(buf1);
1676 	if (buf2)
1677 		evbuffer_free(buf2);
1678 }
1679 
1680 static void
1681 test_evbuffer_multicast(void *ptr)
1682 {
1683 	const char chunk1[] = "If you have found the answer to such a problem";
1684 	const char chunk2[] = "you ought to write it up for publication";
1685 			  /* -- Knuth's "Notes on the Exercises" from TAOCP */
1686 	char tmp[16];
1687 	size_t len1 = strlen(chunk1), len2=strlen(chunk2);
1688 
1689 	struct evbuffer *buf1 = NULL, *buf2 = NULL;
1690 
1691 	buf1 = evbuffer_new();
1692 	tt_assert(buf1);
1693 
1694 	evbuffer_add(buf1, chunk1, len1);
1695 	evbuffer_add(buf1, ", ", 2);
1696 	evbuffer_add(buf1, chunk2, len2);
1697 	tt_int_op(evbuffer_get_length(buf1), ==, len1+len2+2);
1698 
1699 	buf2 = evbuffer_new();
1700 	tt_assert(buf2);
1701 
1702 	tt_int_op(evbuffer_add_buffer_reference(buf2, buf1), ==, 0);
1703 	/* nested references are not allowed */
1704 	tt_int_op(evbuffer_add_buffer_reference(buf2, buf2), ==, -1);
1705 	tt_int_op(evbuffer_add_buffer_reference(buf1, buf2), ==, -1);
1706 
1707 	/* both buffers contain the same amount of data */
1708 	tt_int_op(evbuffer_get_length(buf1), ==, evbuffer_get_length(buf1));
1709 
1710 	/* Make sure we can drain a little from the first buffer. */
1711 	tt_int_op(evbuffer_remove(buf1, tmp, 6), ==, 6);
1712 	tt_int_op(memcmp(tmp, "If you", 6), ==, 0);
1713 	tt_int_op(evbuffer_remove(buf1, tmp, 5), ==, 5);
1714 	tt_int_op(memcmp(tmp, " have", 5), ==, 0);
1715 
1716 	/* Make sure that prepending does not meddle with immutable data */
1717 	tt_int_op(evbuffer_prepend(buf1, "I have ", 7), ==, 0);
1718 	tt_int_op(memcmp(chunk1, "If you", 6), ==, 0);
1719 	evbuffer_validate(buf1);
1720 
1721 	/* Make sure we can drain a little from the second buffer. */
1722 	tt_int_op(evbuffer_remove(buf2, tmp, 6), ==, 6);
1723 	tt_int_op(memcmp(tmp, "If you", 6), ==, 0);
1724 	tt_int_op(evbuffer_remove(buf2, tmp, 5), ==, 5);
1725 	tt_int_op(memcmp(tmp, " have", 5), ==, 0);
1726 
1727 	/* Make sure that prepending does not meddle with immutable data */
1728 	tt_int_op(evbuffer_prepend(buf2, "I have ", 7), ==, 0);
1729 	tt_int_op(memcmp(chunk1, "If you", 6), ==, 0);
1730 	evbuffer_validate(buf2);
1731 
1732 	/* Make sure the data can be read from the second buffer when the first is freed */
1733 	evbuffer_free(buf1);
1734 	buf1 = NULL;
1735 
1736 	tt_int_op(evbuffer_remove(buf2, tmp, 6), ==, 6);
1737 	tt_int_op(memcmp(tmp, "I have", 6), ==, 0);
1738 
1739 	tt_int_op(evbuffer_remove(buf2, tmp, 6), ==, 6);
1740 	tt_int_op(memcmp(tmp, "  foun", 6), ==, 0);
1741 
1742 end:
1743 	if (buf1)
1744 		evbuffer_free(buf1);
1745 	if (buf2)
1746 		evbuffer_free(buf2);
1747 }
1748 
1749 static void
1750 test_evbuffer_multicast_drain(void *ptr)
1751 {
1752 	const char chunk1[] = "If you have found the answer to such a problem";
1753 	const char chunk2[] = "you ought to write it up for publication";
1754 			  /* -- Knuth's "Notes on the Exercises" from TAOCP */
1755 	size_t len1 = strlen(chunk1), len2=strlen(chunk2);
1756 
1757 	struct evbuffer *buf1 = NULL, *buf2 = NULL;
1758 
1759 	buf1 = evbuffer_new();
1760 	tt_assert(buf1);
1761 
1762 	evbuffer_add(buf1, chunk1, len1);
1763 	evbuffer_add(buf1, ", ", 2);
1764 	evbuffer_add(buf1, chunk2, len2);
1765 	tt_int_op(evbuffer_get_length(buf1), ==, len1+len2+2);
1766 
1767 	buf2 = evbuffer_new();
1768 	tt_assert(buf2);
1769 
1770 	tt_int_op(evbuffer_add_buffer_reference(buf2, buf1), ==, 0);
1771 	tt_int_op(evbuffer_get_length(buf2), ==, len1+len2+2);
1772 	tt_int_op(evbuffer_drain(buf1, evbuffer_get_length(buf1)), ==, 0);
1773 	tt_int_op(evbuffer_get_length(buf2), ==, len1+len2+2);
1774 	tt_int_op(evbuffer_drain(buf2, evbuffer_get_length(buf2)), ==, 0);
1775 	evbuffer_validate(buf1);
1776 	evbuffer_validate(buf2);
1777 
1778 end:
1779 	if (buf1)
1780 		evbuffer_free(buf1);
1781 	if (buf2)
1782 		evbuffer_free(buf2);
1783 }
1784 
1785 /* Some cases that we didn't get in test_evbuffer() above, for more coverage. */
1786 static void
1787 test_evbuffer_prepend(void *ptr)
1788 {
1789 	struct evbuffer *buf1 = NULL, *buf2 = NULL;
1790 	char tmp[128];
1791 	int n;
1792 
1793 	buf1 = evbuffer_new();
1794 	tt_assert(buf1);
1795 
1796 	/* Case 0: The evbuffer is entirely empty. */
1797 	evbuffer_prepend(buf1, "This string has 29 characters", 29);
1798 	evbuffer_validate(buf1);
1799 
1800 	/* Case 1: Prepend goes entirely in new chunk. */
1801 	evbuffer_prepend(buf1, "Short.", 6);
1802 	evbuffer_validate(buf1);
1803 
1804 	/* Case 2: prepend goes entirely in first chunk. */
1805 	evbuffer_drain(buf1, 6+11);
1806 	evbuffer_prepend(buf1, "it", 2);
1807 	evbuffer_validate(buf1);
1808 	tt_assert(!memcmp(buf1->first->buffer+buf1->first->misalign,
1809 		"it has", 6));
1810 
1811 	/* Case 3: prepend is split over multiple chunks. */
1812 	evbuffer_prepend(buf1, "It is no longer true to say ", 28);
1813 	evbuffer_validate(buf1);
1814 	n = evbuffer_remove(buf1, tmp, sizeof(tmp)-1);
1815 	tt_int_op(n, >=, 0);
1816 	tmp[n]='\0';
1817 	tt_str_op(tmp,==,"It is no longer true to say it has 29 characters");
1818 
1819 	buf2 = evbuffer_new();
1820 	tt_assert(buf2);
1821 
1822 	/* Case 4: prepend a buffer to an empty buffer. */
1823 	n = 999;
1824 	evbuffer_add_printf(buf1, "Here is string %d. ", n++);
1825 	evbuffer_prepend_buffer(buf2, buf1);
1826 	evbuffer_validate(buf2);
1827 
1828 	/* Case 5: prepend a buffer to a nonempty buffer. */
1829 	evbuffer_add_printf(buf1, "Here is string %d. ", n++);
1830 	evbuffer_prepend_buffer(buf2, buf1);
1831 	evbuffer_validate(buf2);
1832 	evbuffer_validate(buf1);
1833 	n = evbuffer_remove(buf2, tmp, sizeof(tmp)-1);
1834 	tt_int_op(n, >=, 0);
1835 	tmp[n]='\0';
1836 	tt_str_op(tmp,==,"Here is string 1000. Here is string 999. ");
1837 
1838 end:
1839 	if (buf1)
1840 		evbuffer_free(buf1);
1841 	if (buf2)
1842 		evbuffer_free(buf2);
1843 
1844 }
1845 
1846 static void
1847 test_evbuffer_peek_first_gt(void *info)
1848 {
1849 	struct evbuffer *buf = NULL, *tmp_buf = NULL;
1850 	struct evbuffer_ptr ptr;
1851 	struct evbuffer_iovec v[2];
1852 
1853 	buf = evbuffer_new();
1854 	tmp_buf = evbuffer_new();
1855 	evbuffer_add_printf(tmp_buf, "Contents of chunk 100\n");
1856 	evbuffer_add_buffer(buf, tmp_buf);
1857 	evbuffer_add_printf(tmp_buf, "Contents of chunk 1\n");
1858 	evbuffer_add_buffer(buf, tmp_buf);
1859 
1860 	evbuffer_ptr_set(buf, &ptr, 0, EVBUFFER_PTR_SET);
1861 
1862 	/** The only case that matters*/
1863 	tt_int_op(evbuffer_peek(buf, -1, &ptr, NULL, 0), ==, 2);
1864 	/** Just in case */
1865 	tt_int_op(evbuffer_peek(buf, -1, &ptr, v, 2), ==, 2);
1866 
1867 	evbuffer_ptr_set(buf, &ptr, 20, EVBUFFER_PTR_ADD);
1868 	tt_int_op(evbuffer_peek(buf, -1, &ptr, NULL, 0), ==, 2);
1869 	tt_int_op(evbuffer_peek(buf, -1, &ptr, v, 2), ==, 2);
1870 	tt_int_op(evbuffer_peek(buf, 2, &ptr, NULL, 0), ==, 1);
1871 	tt_int_op(evbuffer_peek(buf, 2, &ptr, v, 2), ==, 1);
1872 	tt_int_op(evbuffer_peek(buf, 3, &ptr, NULL, 0), ==, 2);
1873 	tt_int_op(evbuffer_peek(buf, 3, &ptr, v, 2), ==, 2);
1874 
1875 end:
1876 	if (buf)
1877 		evbuffer_free(buf);
1878 	if (tmp_buf)
1879 		evbuffer_free(tmp_buf);
1880 }
1881 
1882 static void
1883 test_evbuffer_peek(void *info)
1884 {
1885 	struct evbuffer *buf = NULL, *tmp_buf = NULL;
1886 	int i;
1887 	struct evbuffer_iovec v[20];
1888 	struct evbuffer_ptr ptr;
1889 
1890 #define tt_iov_eq(v, s)						\
1891 	tt_int_op((v)->iov_len, ==, strlen(s));			\
1892 	tt_assert(!memcmp((v)->iov_base, (s), strlen(s)))
1893 
1894 	/* Let's make a very fragmented buffer. */
1895 	buf = evbuffer_new();
1896 	tmp_buf = evbuffer_new();
1897 	for (i = 0; i < 16; ++i) {
1898 		evbuffer_add_printf(tmp_buf, "Contents of chunk [%d]\n", i);
1899 		evbuffer_add_buffer(buf, tmp_buf);
1900 	}
1901 
1902 	/* How many chunks do we need for everything? */
1903 	i = evbuffer_peek(buf, -1, NULL, NULL, 0);
1904 	tt_int_op(i, ==, 16);
1905 
1906 	/* Simple peek: get everything. */
1907 	i = evbuffer_peek(buf, -1, NULL, v, 20);
1908 	tt_int_op(i, ==, 16); /* we used only 16 chunks. */
1909 	tt_iov_eq(&v[0], "Contents of chunk [0]\n");
1910 	tt_iov_eq(&v[3], "Contents of chunk [3]\n");
1911 	tt_iov_eq(&v[12], "Contents of chunk [12]\n");
1912 	tt_iov_eq(&v[15], "Contents of chunk [15]\n");
1913 
1914 	/* Just get one chunk worth. */
1915 	memset(v, 0, sizeof(v));
1916 	i = evbuffer_peek(buf, -1, NULL, v, 1);
1917 	tt_int_op(i, ==, 1);
1918 	tt_iov_eq(&v[0], "Contents of chunk [0]\n");
1919 	tt_assert(v[1].iov_base == NULL);
1920 
1921 	/* Suppose we want at least the first 40 bytes. */
1922 	memset(v, 0, sizeof(v));
1923 	i = evbuffer_peek(buf, 40, NULL, v, 16);
1924 	tt_int_op(i, ==, 2);
1925 	tt_iov_eq(&v[0], "Contents of chunk [0]\n");
1926 	tt_iov_eq(&v[1], "Contents of chunk [1]\n");
1927 	tt_assert(v[2].iov_base == NULL);
1928 
1929 	/* How many chunks do we need for 100 bytes? */
1930 	memset(v, 0, sizeof(v));
1931 	i = evbuffer_peek(buf, 100, NULL, NULL, 0);
1932 	tt_int_op(i, ==, 5);
1933 	tt_assert(v[0].iov_base == NULL);
1934 
1935 	/* Now we ask for more bytes than we provide chunks for */
1936 	memset(v, 0, sizeof(v));
1937 	i = evbuffer_peek(buf, 60, NULL, v, 1);
1938 	tt_int_op(i, ==, 3);
1939 	tt_iov_eq(&v[0], "Contents of chunk [0]\n");
1940 	tt_assert(v[1].iov_base == NULL);
1941 
1942 	/* Now we ask for more bytes than the buffer has. */
1943 	memset(v, 0, sizeof(v));
1944 	i = evbuffer_peek(buf, 65536, NULL, v, 20);
1945 	tt_int_op(i, ==, 16); /* we used only 16 chunks. */
1946 	tt_iov_eq(&v[0], "Contents of chunk [0]\n");
1947 	tt_iov_eq(&v[3], "Contents of chunk [3]\n");
1948 	tt_iov_eq(&v[12], "Contents of chunk [12]\n");
1949 	tt_iov_eq(&v[15], "Contents of chunk [15]\n");
1950 	tt_assert(v[16].iov_base == NULL);
1951 
1952 	/* What happens if we try an empty buffer? */
1953 	memset(v, 0, sizeof(v));
1954 	i = evbuffer_peek(tmp_buf, -1, NULL, v, 20);
1955 	tt_int_op(i, ==, 0);
1956 	tt_assert(v[0].iov_base == NULL);
1957 	memset(v, 0, sizeof(v));
1958 	i = evbuffer_peek(tmp_buf, 50, NULL, v, 20);
1959 	tt_int_op(i, ==, 0);
1960 	tt_assert(v[0].iov_base == NULL);
1961 
1962 	/* Okay, now time to have fun with pointers. */
1963 	memset(v, 0, sizeof(v));
1964 	evbuffer_ptr_set(buf, &ptr, 30, EVBUFFER_PTR_SET);
1965 	i = evbuffer_peek(buf, 50, &ptr, v, 20);
1966 	tt_int_op(i, ==, 3);
1967 	tt_iov_eq(&v[0], " of chunk [1]\n");
1968 	tt_iov_eq(&v[1], "Contents of chunk [2]\n");
1969 	tt_iov_eq(&v[2], "Contents of chunk [3]\n"); /*more than we asked for*/
1970 
1971 	/* advance to the start of another chain. */
1972 	memset(v, 0, sizeof(v));
1973 	evbuffer_ptr_set(buf, &ptr, 14, EVBUFFER_PTR_ADD);
1974 	i = evbuffer_peek(buf, 44, &ptr, v, 20);
1975 	tt_int_op(i, ==, 2);
1976 	tt_iov_eq(&v[0], "Contents of chunk [2]\n");
1977 	tt_iov_eq(&v[1], "Contents of chunk [3]\n"); /*more than we asked for*/
1978 
1979 	/* peek at the end of the buffer */
1980 	memset(v, 0, sizeof(v));
1981 	tt_assert(evbuffer_ptr_set(buf, &ptr, evbuffer_get_length(buf), EVBUFFER_PTR_SET) == 0);
1982 	i = evbuffer_peek(buf, 44, &ptr, v, 20);
1983 	tt_int_op(i, ==, 0);
1984 	tt_assert(v[0].iov_base == NULL);
1985 
1986 end:
1987 	if (buf)
1988 		evbuffer_free(buf);
1989 	if (tmp_buf)
1990 		evbuffer_free(tmp_buf);
1991 }
1992 
1993 /* Check whether evbuffer freezing works right.  This is called twice,
1994    once with the argument "start" and once with the argument "end".
1995    When we test "start", we freeze the start of an evbuffer and make sure
1996    that modifying the start of the buffer doesn't work.  When we test
1997    "end", we freeze the end of an evbuffer and make sure that modifying
1998    the end of the buffer doesn't work.
1999  */
2000 static void
2001 test_evbuffer_freeze(void *ptr)
2002 {
2003 	struct evbuffer *buf = NULL, *tmp_buf=NULL;
2004 	const char string[] = /* Year's End, Richard Wilbur */
2005 	    "I've known the wind by water banks to shake\n"
2006 	    "The late leaves down, which frozen where they fell\n"
2007 	    "And held in ice as dancers in a spell\n"
2008 	    "Fluttered all winter long into a lake...";
2009 	const int start = !strcmp(ptr, "start");
2010 	char *cp;
2011 	char charbuf[128];
2012 	int r;
2013 	size_t orig_length;
2014 	struct evbuffer_iovec v[1];
2015 
2016 	if (!start)
2017 		tt_str_op(ptr, ==, "end");
2018 
2019 	buf = evbuffer_new();
2020 	tmp_buf = evbuffer_new();
2021 	tt_assert(tmp_buf);
2022 
2023 	evbuffer_add(buf, string, strlen(string));
2024 	evbuffer_freeze(buf, start); /* Freeze the start or the end.*/
2025 
2026 #define FREEZE_EQ(a, startcase, endcase)		\
2027 	do {						\
2028 	    if (start) {				\
2029 		    tt_int_op((a), ==, (startcase));	\
2030 	    } else {					\
2031 		    tt_int_op((a), ==, (endcase));	\
2032 	    }						\
2033 	} while (0)
2034 
2035 
2036 	orig_length = evbuffer_get_length(buf);
2037 
2038 	/* These functions all manipulate the end of buf. */
2039 	r = evbuffer_add(buf, "abc", 0);
2040 	FREEZE_EQ(r, 0, -1);
2041 	r = evbuffer_reserve_space(buf, 10, v, 1);
2042 	FREEZE_EQ(r, 1, -1);
2043 	if (r == 1) {
2044 		memset(v[0].iov_base, 'X', 10);
2045 		v[0].iov_len = 10;
2046 	}
2047 	r = evbuffer_commit_space(buf, v, 1);
2048 	FREEZE_EQ(r, 0, -1);
2049 	r = evbuffer_add_reference(buf, string, 5, NULL, NULL);
2050 	FREEZE_EQ(r, 0, -1);
2051 	r = evbuffer_add_printf(buf, "Hello %s", "world");
2052 	FREEZE_EQ(r, 11, -1);
2053 	/* TODO: test add_buffer, add_file, read */
2054 
2055 	if (!start)
2056 		tt_int_op(orig_length, ==, evbuffer_get_length(buf));
2057 
2058 	orig_length = evbuffer_get_length(buf);
2059 
2060 	/* These functions all manipulate the start of buf. */
2061 	r = evbuffer_remove(buf, charbuf, 1);
2062 	FREEZE_EQ(r, -1, 1);
2063 	r = evbuffer_drain(buf, 3);
2064 	FREEZE_EQ(r, -1, 0);
2065 	r = evbuffer_prepend(buf, "dummy", 5);
2066 	FREEZE_EQ(r, -1, 0);
2067 	cp = evbuffer_readln(buf, NULL, EVBUFFER_EOL_LF);
2068 	FREEZE_EQ(cp==NULL, 1, 0);
2069 	if (cp)
2070 		free(cp);
2071 	/* TODO: Test remove_buffer, add_buffer, write, prepend_buffer */
2072 
2073 	if (start)
2074 		tt_int_op(orig_length, ==, evbuffer_get_length(buf));
2075 
2076 end:
2077 	if (buf)
2078 		evbuffer_free(buf);
2079 
2080 	if (tmp_buf)
2081 		evbuffer_free(tmp_buf);
2082 }
2083 
2084 static void
2085 test_evbuffer_add_iovec(void * ptr)
2086 {
2087 	struct evbuffer * buf = NULL;
2088 	struct evbuffer_iovec vec[4];
2089 	const char * data[] = {
2090 		"Guilt resembles a sword with two edges.",
2091 		"On the one hand, it cuts for Justice, imposing practical morality upon those who fear it.",
2092 		"Conscience does not always adhere to rational judgment.",
2093 		"Guilt is always a self-imposed burden, but it is not always rightly imposed."
2094 		/* -- R.A. Salvatore, _Sojurn_ */
2095 	};
2096 	size_t expected_length = 0;
2097 	size_t returned_length = 0;
2098 	int i;
2099 
2100 	buf = evbuffer_new();
2101 
2102 	tt_assert(buf);
2103 
2104 	for (i = 0; i < 4; i++) {
2105 		vec[i].iov_len  = strlen(data[i]);
2106 		vec[i].iov_base = (char*) data[i];
2107 		expected_length += vec[i].iov_len;
2108 	}
2109 
2110 	returned_length = evbuffer_add_iovec(buf, vec, 4);
2111 
2112 	tt_int_op(returned_length, ==, evbuffer_get_length(buf));
2113 	tt_int_op(evbuffer_get_length(buf), ==, expected_length);
2114 
2115 	for (i = 0; i < 4; i++) {
2116 		char charbuf[1024];
2117 
2118 		memset(charbuf, 0, 1024);
2119 		evbuffer_remove(buf, charbuf, strlen(data[i]));
2120 		tt_assert(strcmp(charbuf, data[i]) == 0);
2121 	}
2122 
2123 	tt_assert(evbuffer_get_length(buf) == 0);
2124 end:
2125 	if (buf) {
2126 		evbuffer_free(buf);
2127 	}
2128 }
2129 
2130 static void
2131 test_evbuffer_copyout(void *dummy)
2132 {
2133 	const char string[] =
2134 	    "Still they skirmish to and fro, men my messmates on the snow "
2135 	    "When we headed off the aurochs turn for turn; "
2136 	    "When the rich Allobrogenses never kept amanuenses, "
2137 	    "And our only plots were piled in lakes at Berne.";
2138 	/* -- Kipling, "In The Neolithic Age" */
2139 	char tmp[1024];
2140 	struct evbuffer_ptr ptr;
2141 	struct evbuffer *buf;
2142 
2143 	(void)dummy;
2144 
2145 	buf = evbuffer_new();
2146 	tt_assert(buf);
2147 
2148 	tt_int_op(strlen(string), ==, 206);
2149 
2150 	/* Ensure separate chains */
2151 	evbuffer_add_reference(buf, string, 80, no_cleanup, NULL);
2152 	evbuffer_add_reference(buf, string+80, 80, no_cleanup, NULL);
2153 	evbuffer_add(buf, string+160, strlen(string)-160);
2154 
2155 	tt_int_op(206, ==, evbuffer_get_length(buf));
2156 
2157 	/* First, let's test plain old copyout. */
2158 
2159 	/* Copy a little from the beginning. */
2160 	tt_int_op(10, ==, evbuffer_copyout(buf, tmp, 10));
2161 	tt_int_op(0, ==, memcmp(tmp, "Still they", 10));
2162 
2163 	/* Now copy more than a little from the beginning */
2164 	memset(tmp, 0, sizeof(tmp));
2165 	tt_int_op(100, ==, evbuffer_copyout(buf, tmp, 100));
2166 	tt_int_op(0, ==, memcmp(tmp, string, 100));
2167 
2168 	/* Copy too much; ensure truncation. */
2169 	memset(tmp, 0, sizeof(tmp));
2170 	tt_int_op(206, ==, evbuffer_copyout(buf, tmp, 230));
2171 	tt_int_op(0, ==, memcmp(tmp, string, 206));
2172 
2173 	/* That was supposed to be nondestructive, btw */
2174 	tt_int_op(206, ==, evbuffer_get_length(buf));
2175 
2176 	/* Now it's time to test copyout_from!  First, let's start in the
2177 	 * first chain. */
2178 	evbuffer_ptr_set(buf, &ptr, 15, EVBUFFER_PTR_SET);
2179 	memset(tmp, 0, sizeof(tmp));
2180 	tt_int_op(10, ==, evbuffer_copyout_from(buf, &ptr, tmp, 10));
2181 	tt_int_op(0, ==, memcmp(tmp, "mish to an", 10));
2182 
2183 	/* Right up to the end of the first chain */
2184 	memset(tmp, 0, sizeof(tmp));
2185 	tt_int_op(65, ==, evbuffer_copyout_from(buf, &ptr, tmp, 65));
2186 	tt_int_op(0, ==, memcmp(tmp, string+15, 65));
2187 
2188 	/* Span into the second chain */
2189 	memset(tmp, 0, sizeof(tmp));
2190 	tt_int_op(90, ==, evbuffer_copyout_from(buf, &ptr, tmp, 90));
2191 	tt_int_op(0, ==, memcmp(tmp, string+15, 90));
2192 
2193 	/* Span into the third chain */
2194 	memset(tmp, 0, sizeof(tmp));
2195 	tt_int_op(160, ==, evbuffer_copyout_from(buf, &ptr, tmp, 160));
2196 	tt_int_op(0, ==, memcmp(tmp, string+15, 160));
2197 
2198 	/* Overrun */
2199 	memset(tmp, 0, sizeof(tmp));
2200 	tt_int_op(206-15, ==, evbuffer_copyout_from(buf, &ptr, tmp, 999));
2201 	tt_int_op(0, ==, memcmp(tmp, string+15, 206-15));
2202 
2203 	/* That was supposed to be nondestructive, too */
2204 	tt_int_op(206, ==, evbuffer_get_length(buf));
2205 
2206 end:
2207 	if (buf)
2208 		evbuffer_free(buf);
2209 }
2210 
2211 static void *
2212 setup_passthrough(const struct testcase_t *testcase)
2213 {
2214 	return testcase->setup_data;
2215 }
2216 static int
2217 cleanup_passthrough(const struct testcase_t *testcase, void *ptr)
2218 {
2219 	(void) ptr;
2220 	return 1;
2221 }
2222 
2223 static const struct testcase_setup_t nil_setup = {
2224 	setup_passthrough,
2225 	cleanup_passthrough
2226 };
2227 
2228 struct testcase_t evbuffer_testcases[] = {
2229 	{ "evbuffer", test_evbuffer, 0, NULL, NULL },
2230 	{ "remove_buffer_with_empty", test_evbuffer_remove_buffer_with_empty, 0, NULL, NULL },
2231 	{ "reserve2", test_evbuffer_reserve2, 0, NULL, NULL },
2232 	{ "reserve_many", test_evbuffer_reserve_many, 0, NULL, NULL },
2233 	{ "reserve_many2", test_evbuffer_reserve_many, 0, &nil_setup, (void*)"add" },
2234 	{ "reserve_many3", test_evbuffer_reserve_many, 0, &nil_setup, (void*)"fill" },
2235 	{ "expand", test_evbuffer_expand, 0, NULL, NULL },
2236 	{ "reference", test_evbuffer_reference, 0, NULL, NULL },
2237 	{ "iterative", test_evbuffer_iterative, 0, NULL, NULL },
2238 	{ "readln", test_evbuffer_readln, TT_NO_LOGS, &basic_setup, NULL },
2239 	{ "search_eol", test_evbuffer_search_eol, 0, NULL, NULL },
2240 	{ "find", test_evbuffer_find, 0, NULL, NULL },
2241 	{ "ptr_set", test_evbuffer_ptr_set, 0, NULL, NULL },
2242 	{ "search", test_evbuffer_search, 0, NULL, NULL },
2243 	{ "callbacks", test_evbuffer_callbacks, 0, NULL, NULL },
2244 	{ "add_reference", test_evbuffer_add_reference, 0, NULL, NULL },
2245 	{ "multicast", test_evbuffer_multicast, 0, NULL, NULL },
2246 	{ "multicast_drain", test_evbuffer_multicast_drain, 0, NULL, NULL },
2247 	{ "prepend", test_evbuffer_prepend, TT_FORK, NULL, NULL },
2248 	{ "peek", test_evbuffer_peek, 0, NULL, NULL },
2249 	{ "peek_first_gt", test_evbuffer_peek_first_gt, 0, NULL, NULL },
2250 	{ "freeze_start", test_evbuffer_freeze, 0, &nil_setup, (void*)"start" },
2251 	{ "freeze_end", test_evbuffer_freeze, 0, &nil_setup, (void*)"end" },
2252 	{ "add_iovec", test_evbuffer_add_iovec, 0, NULL, NULL},
2253 	{ "copyout", test_evbuffer_copyout, 0, NULL, NULL},
2254 	{ "file_segment_add_cleanup_cb", test_evbuffer_file_segment_add_cleanup_cb, 0, NULL, NULL },
2255 
2256 #define ADDFILE_TEST(name, parameters)					\
2257 	{ name, test_evbuffer_add_file, TT_FORK|TT_NEED_BASE,		\
2258 	  &basic_setup, (void*)(parameters) }
2259 
2260 #define ADDFILE_TEST_GROUP(name, parameters)			\
2261 	ADDFILE_TEST(name "_sendfile", "sendfile " parameters), \
2262 	ADDFILE_TEST(name "_mmap", "mmap " parameters),		\
2263 	ADDFILE_TEST(name "_linear", "linear " parameters)
2264 
2265 	ADDFILE_TEST_GROUP("add_file", ""),
2266 	ADDFILE_TEST("add_file_nosegment", "default nosegment"),
2267 
2268 	ADDFILE_TEST_GROUP("add_big_file", "bigfile"),
2269 	ADDFILE_TEST("add_big_file_nosegment", "default nosegment bigfile"),
2270 
2271 	ADDFILE_TEST_GROUP("add_file_offset", "bigfile map_offset"),
2272 	ADDFILE_TEST("add_file_offset_nosegment",
2273 	    "default nosegment bigfile map_offset"),
2274 
2275 	ADDFILE_TEST_GROUP("add_file_offset2", "bigfile offset_in_segment"),
2276 
2277 	ADDFILE_TEST_GROUP("add_file_offset3",
2278 	    "bigfile offset_in_segment map_offset"),
2279 
2280 	END_OF_TESTCASES
2281 };
2282