root/opal/mca/event/libevent2022/libevent/test/regress_buffer.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. _evbuffer_validate
  2. evbuffer_get_waste
  3. test_evbuffer
  4. no_cleanup
  5. test_evbuffer_remove_buffer_with_empty
  6. test_evbuffer_reserve2
  7. test_evbuffer_reserve_many
  8. test_evbuffer_expand
  9. reference_cb
  10. test_evbuffer_reference
  11. test_evbuffer_add_file
  12. failing_malloc
  13. test_evbuffer_readln
  14. test_evbuffer_search_eol
  15. test_evbuffer_iterative
  16. test_evbuffer_find
  17. test_evbuffer_ptr_set
  18. test_evbuffer_search
  19. log_change_callback
  20. self_draining_callback
  21. test_evbuffer_callbacks
  22. ref_done_cb
  23. test_evbuffer_add_reference
  24. test_evbuffer_prepend
  25. test_evbuffer_peek
  26. test_evbuffer_freeze
  27. setup_passthrough
  28. cleanup_passthrough

   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 
  28 #ifdef WIN32
  29 #include <winsock2.h>
  30 #include <windows.h>
  31 #endif
  32 
  33 #include "event2/event-config.h"
  34 
  35 #include <sys/types.h>
  36 #include <sys/stat.h>
  37 #ifdef _EVENT_HAVE_SYS_TIME_H
  38 #include <sys/time.h>
  39 #endif
  40 #include <sys/queue.h>
  41 #ifndef WIN32
  42 #include <sys/socket.h>
  43 #include <sys/wait.h>
  44 #include <signal.h>
  45 #include <unistd.h>
  46 #include <netdb.h>
  47 #endif
  48 #include <stdlib.h>
  49 #include <stdio.h>
  50 #include <string.h>
  51 #include <errno.h>
  52 #include <assert.h>
  53 
  54 #include "event2/event.h"
  55 #include "event2/buffer.h"
  56 #include "event2/buffer_compat.h"
  57 #include "event2/util.h"
  58 
  59 #include "evbuffer-internal.h"
  60 #include "log-internal.h"
  61 
  62 #include "regress.h"
  63 
  64 /* Validates that an evbuffer is good. Returns false if it isn't, true if it
  65  * is*/
  66 static int
  67 _evbuffer_validate(struct evbuffer *buf)
  68 {
  69         struct evbuffer_chain *chain;
  70         size_t sum = 0;
  71         int found_last_with_datap = 0;
  72 
  73         if (buf->first == NULL) {
  74                 tt_assert(buf->last == NULL);
  75                 tt_assert(buf->total_len == 0);
  76         }
  77 
  78         chain = buf->first;
  79 
  80         tt_assert(buf->last_with_datap);
  81         if (buf->last_with_datap == &buf->first)
  82                 found_last_with_datap = 1;
  83 
  84         while (chain != NULL) {
  85                 if (&chain->next == buf->last_with_datap)
  86                         found_last_with_datap = 1;
  87                 sum += chain->off;
  88                 if (chain->next == NULL) {
  89                         tt_assert(buf->last == chain);
  90                 }
  91                 tt_assert(chain->buffer_len >= chain->misalign + chain->off);
  92                 chain = chain->next;
  93         }
  94 
  95         if (buf->first)
  96                 tt_assert(*buf->last_with_datap);
  97 
  98         if (*buf->last_with_datap) {
  99                 chain = *buf->last_with_datap;
 100                 if (chain->off == 0 || buf->total_len == 0) {
 101                         tt_assert(chain->off == 0)
 102                         tt_assert(chain == buf->first);
 103                         tt_assert(buf->total_len == 0);
 104                 }
 105                 chain = chain->next;
 106                 while (chain != NULL) {
 107                         tt_assert(chain->off == 0);
 108                         chain = chain->next;
 109                 }
 110         } else {
 111                 tt_assert(buf->last_with_datap == &buf->first);
 112         }
 113         tt_assert(found_last_with_datap);
 114 
 115         tt_assert(sum == buf->total_len);
 116         return 1;
 117  end:
 118         return 0;
 119 }
 120 
 121 static void
 122 evbuffer_get_waste(struct evbuffer *buf, size_t *allocatedp, size_t *wastedp, size_t *usedp)
 123 {
 124         struct evbuffer_chain *chain;
 125         size_t a, w, u;
 126         int n = 0;
 127         u = a = w = 0;
 128 
 129         chain = buf->first;
 130         /* skip empty at start */
 131         while (chain && chain->off==0) {
 132                 ++n;
 133                 a += chain->buffer_len;
 134                 chain = chain->next;
 135         }
 136         /* first nonempty chain: stuff at the end only is wasted. */
 137         if (chain) {
 138                 ++n;
 139                 a += chain->buffer_len;
 140                 u += chain->off;
 141                 if (chain->next && chain->next->off)
 142                         w += (size_t)(chain->buffer_len - (chain->misalign + chain->off));
 143                 chain = chain->next;
 144         }
 145         /* subsequent nonempty chains */
 146         while (chain && chain->off) {
 147                 ++n;
 148                 a += chain->buffer_len;
 149                 w += (size_t)chain->misalign;
 150                 u += chain->off;
 151                 if (chain->next && chain->next->off)
 152                         w += (size_t) (chain->buffer_len - (chain->misalign + chain->off));
 153                 chain = chain->next;
 154         }
 155         /* subsequent empty chains */
 156         while (chain) {
 157                 ++n;
 158                 a += chain->buffer_len;
 159         }
 160         *allocatedp = a;
 161         *wastedp = w;
 162         *usedp = u;
 163 }
 164 
 165 #define evbuffer_validate(buf)                  \
 166         TT_STMT_BEGIN if (!_evbuffer_validate(buf)) TT_DIE(("Buffer format invalid")); TT_STMT_END
 167 
 168 static void
 169 test_evbuffer(void *ptr)
 170 {
 171         static char buffer[512], *tmp;
 172         struct evbuffer *evb = evbuffer_new();
 173         struct evbuffer *evb_two = evbuffer_new();
 174         size_t sz_tmp;
 175         int i;
 176 
 177         evbuffer_validate(evb);
 178         evbuffer_add_printf(evb, "%s/%d", "hello", 1);
 179         evbuffer_validate(evb);
 180 
 181         tt_assert(evbuffer_get_length(evb) == 7);
 182         tt_assert(!memcmp((char*)EVBUFFER_DATA(evb), "hello/1", 1));
 183 
 184         evbuffer_add_buffer(evb, evb_two);
 185         evbuffer_validate(evb);
 186 
 187         evbuffer_drain(evb, strlen("hello/"));
 188         evbuffer_validate(evb);
 189         tt_assert(evbuffer_get_length(evb) == 1);
 190         tt_assert(!memcmp((char*)EVBUFFER_DATA(evb), "1", 1));
 191 
 192         evbuffer_add_printf(evb_two, "%s", "/hello");
 193         evbuffer_validate(evb);
 194         evbuffer_add_buffer(evb, evb_two);
 195         evbuffer_validate(evb);
 196 
 197         tt_assert(evbuffer_get_length(evb_two) == 0);
 198         tt_assert(evbuffer_get_length(evb) == 7);
 199         tt_assert(!memcmp((char*)EVBUFFER_DATA(evb), "1/hello", 7) != 0);
 200 
 201         memset(buffer, 0, sizeof(buffer));
 202         evbuffer_add(evb, buffer, sizeof(buffer));
 203         evbuffer_validate(evb);
 204         tt_assert(evbuffer_get_length(evb) == 7 + 512);
 205 
 206         tmp = (char *)evbuffer_pullup(evb, 7 + 512);
 207         tt_assert(tmp);
 208         tt_assert(!strncmp(tmp, "1/hello", 7));
 209         tt_assert(!memcmp(tmp + 7, buffer, sizeof(buffer)));
 210         evbuffer_validate(evb);
 211 
 212         evbuffer_prepend(evb, "something", 9);
 213         evbuffer_validate(evb);
 214         evbuffer_prepend(evb, "else", 4);
 215         evbuffer_validate(evb);
 216 
 217         tmp = (char *)evbuffer_pullup(evb, 4 + 9 + 7);
 218         tt_assert(!strncmp(tmp, "elsesomething1/hello", 4 + 9 + 7));
 219         evbuffer_validate(evb);
 220 
 221         evbuffer_drain(evb, -1);
 222         evbuffer_validate(evb);
 223         evbuffer_drain(evb_two, -1);
 224         evbuffer_validate(evb);
 225 
 226         for (i = 0; i < 3; ++i) {
 227                 evbuffer_add(evb_two, buffer, sizeof(buffer));
 228                 evbuffer_validate(evb_two);
 229                 evbuffer_add_buffer(evb, evb_two);
 230                 evbuffer_validate(evb);
 231                 evbuffer_validate(evb_two);
 232         }
 233 
 234         tt_assert(evbuffer_get_length(evb_two) == 0);
 235         tt_assert(evbuffer_get_length(evb) == i * sizeof(buffer));
 236 
 237         /* test remove buffer */
 238         sz_tmp = (size_t)(sizeof(buffer)*2.5);
 239         evbuffer_remove_buffer(evb, evb_two, sz_tmp);
 240         tt_assert(evbuffer_get_length(evb_two) == sz_tmp);
 241         tt_assert(evbuffer_get_length(evb) == sizeof(buffer) / 2);
 242         evbuffer_validate(evb);
 243 
 244         if (memcmp(evbuffer_pullup(
 245                            evb, -1), buffer, sizeof(buffer) / 2) != 0 ||
 246             memcmp(evbuffer_pullup(
 247                            evb_two, -1), buffer, sizeof(buffer)) != 0)
 248                 tt_abort_msg("Pullup did not preserve content");
 249 
 250         evbuffer_validate(evb);
 251 
 252 
 253         /* testing one-vector reserve and commit */
 254         {
 255                 struct evbuffer_iovec v[1];
 256                 char *buf;
 257                 int i, j, r;
 258 
 259                 for (i = 0; i < 3; ++i) {
 260                         r = evbuffer_reserve_space(evb, 10000, v, 1);
 261                         tt_int_op(r, ==, 1);
 262                         tt_assert(v[0].iov_len >= 10000);
 263                         tt_assert(v[0].iov_base != NULL);
 264 
 265                         evbuffer_validate(evb);
 266                         buf = v[0].iov_base;
 267                         for (j = 0; j < 10000; ++j) {
 268                                 buf[j] = j;
 269                         }
 270                         evbuffer_validate(evb);
 271 
 272                         tt_int_op(evbuffer_commit_space(evb, v, 1), ==, 0);
 273                         evbuffer_validate(evb);
 274 
 275                         tt_assert(evbuffer_get_length(evb) >= 10000);
 276 
 277                         evbuffer_drain(evb, j * 5000);
 278                         evbuffer_validate(evb);
 279                 }
 280         }
 281 
 282  end:
 283         evbuffer_free(evb);
 284         evbuffer_free(evb_two);
 285 }
 286 
 287 static void
 288 no_cleanup(const void *data, size_t datalen, void *extra)
 289 {
 290 }
 291 
 292 static void
 293 test_evbuffer_remove_buffer_with_empty(void *ptr)
 294 {
 295     struct evbuffer *src = evbuffer_new();
 296     struct evbuffer *dst = evbuffer_new();
 297     char buf[2];
 298 
 299     evbuffer_validate(src);
 300     evbuffer_validate(dst);
 301 
 302     /* setup the buffers */
 303     /* we need more data in src than we will move later */
 304     evbuffer_add_reference(src, buf, sizeof(buf), no_cleanup, NULL);
 305     evbuffer_add_reference(src, buf, sizeof(buf), no_cleanup, NULL);
 306     /* we need one buffer in dst and one empty buffer at the end */
 307     evbuffer_add(dst, buf, sizeof(buf));
 308     evbuffer_add_reference(dst, buf, 0, no_cleanup, NULL);
 309 
 310     evbuffer_validate(src);
 311     evbuffer_validate(dst);
 312 
 313     /* move three bytes over */
 314     evbuffer_remove_buffer(src, dst, 3);
 315 
 316     evbuffer_validate(src);
 317     evbuffer_validate(dst);
 318 
 319 end:
 320     evbuffer_free(src);
 321     evbuffer_free(dst);
 322 }
 323 
 324 static void
 325 test_evbuffer_reserve2(void *ptr)
 326 {
 327         /* Test the two-vector cases of reserve/commit. */
 328         struct evbuffer *buf = evbuffer_new();
 329         int n, i;
 330         struct evbuffer_iovec v[2];
 331         size_t remaining;
 332         char *cp, *cp2;
 333 
 334         /* First chunk will necessarily be one chunk. Use 512 bytes of it.*/
 335         n = evbuffer_reserve_space(buf, 1024, v, 2);
 336         tt_int_op(n, ==, 1);
 337         tt_int_op(evbuffer_get_length(buf), ==, 0);
 338         tt_assert(v[0].iov_base != NULL);
 339         tt_int_op(v[0].iov_len, >=, 1024);
 340         memset(v[0].iov_base, 'X', 512);
 341         cp = v[0].iov_base;
 342         remaining = v[0].iov_len - 512;
 343         v[0].iov_len = 512;
 344         evbuffer_validate(buf);
 345         tt_int_op(0, ==, evbuffer_commit_space(buf, v, 1));
 346         tt_int_op(evbuffer_get_length(buf), ==, 512);
 347         evbuffer_validate(buf);
 348 
 349         /* Ask for another same-chunk request, in an existing chunk. Use 8
 350          * bytes of it. */
 351         n = evbuffer_reserve_space(buf, 32, v, 2);
 352         tt_int_op(n, ==, 1);
 353         tt_assert(cp + 512 == v[0].iov_base);
 354         tt_int_op(remaining, ==, v[0].iov_len);
 355         memset(v[0].iov_base, 'Y', 8);
 356         v[0].iov_len = 8;
 357         tt_int_op(0, ==, evbuffer_commit_space(buf, v, 1));
 358         tt_int_op(evbuffer_get_length(buf), ==, 520);
 359         remaining -= 8;
 360         evbuffer_validate(buf);
 361 
 362         /* Now ask for a request that will be split. Use only one byte of it,
 363            though. */
 364         n = evbuffer_reserve_space(buf, remaining+64, v, 2);
 365         tt_int_op(n, ==, 2);
 366         tt_assert(cp + 520 == v[0].iov_base);
 367         tt_int_op(remaining, ==, v[0].iov_len);
 368         tt_assert(v[1].iov_base);
 369         tt_assert(v[1].iov_len >= 64);
 370         cp2 = v[1].iov_base;
 371         memset(v[0].iov_base, 'Z', 1);
 372         v[0].iov_len = 1;
 373         tt_int_op(0, ==, evbuffer_commit_space(buf, v, 1));
 374         tt_int_op(evbuffer_get_length(buf), ==, 521);
 375         remaining -= 1;
 376         evbuffer_validate(buf);
 377 
 378         /* Now ask for a request that will be split. Use some of the first
 379          * part and some of the second. */
 380         n = evbuffer_reserve_space(buf, remaining+64, v, 2);
 381         evbuffer_validate(buf);
 382         tt_int_op(n, ==, 2);
 383         tt_assert(cp + 521 == v[0].iov_base);
 384         tt_int_op(remaining, ==, v[0].iov_len);
 385         tt_assert(v[1].iov_base == cp2);
 386         tt_assert(v[1].iov_len >= 64);
 387         memset(v[0].iov_base, 'W', 400);
 388         v[0].iov_len = 400;
 389         memset(v[1].iov_base, 'x', 60);
 390         v[1].iov_len = 60;
 391         tt_int_op(0, ==, evbuffer_commit_space(buf, v, 2));
 392         tt_int_op(evbuffer_get_length(buf), ==, 981);
 393         evbuffer_validate(buf);
 394 
 395         /* Now peek to make sure stuff got made how we like. */
 396         memset(v,0,sizeof(v));
 397         n = evbuffer_peek(buf, -1, NULL, v, 2);
 398         tt_int_op(n, ==, 2);
 399         tt_int_op(v[0].iov_len, ==, 921);
 400         tt_int_op(v[1].iov_len, ==, 60);
 401 
 402         cp = v[0].iov_base;
 403         for (i=0; i<512; ++i)
 404                 tt_int_op(cp[i], ==, 'X');
 405         for (i=512; i<520; ++i)
 406                 tt_int_op(cp[i], ==, 'Y');
 407         for (i=520; i<521; ++i)
 408                 tt_int_op(cp[i], ==, 'Z');
 409         for (i=521; i<921; ++i)
 410                 tt_int_op(cp[i], ==, 'W');
 411 
 412         cp = v[1].iov_base;
 413         for (i=0; i<60; ++i)
 414                 tt_int_op(cp[i], ==, 'x');
 415 
 416 end:
 417         evbuffer_free(buf);
 418 }
 419 
 420 static void
 421 test_evbuffer_reserve_many(void *ptr)
 422 {
 423         /* This is a glass-box test to handle expanding a buffer with more
 424          * chunks and reallocating chunks as needed */
 425         struct evbuffer *buf = evbuffer_new();
 426         struct evbuffer_iovec v[8];
 427         int n;
 428         size_t sz;
 429         int add_data = ptr && !strcmp(ptr, "add");
 430         int fill_first = ptr && !strcmp(ptr, "fill");
 431         char *cp1, *cp2;
 432 
 433         /* When reserving the the first chunk, we just allocate it */
 434         n = evbuffer_reserve_space(buf, 128, v, 2);
 435         evbuffer_validate(buf);
 436         tt_int_op(n, ==, 1);
 437         tt_assert(v[0].iov_len >= 128);
 438         sz = v[0].iov_len;
 439         cp1 = v[0].iov_base;
 440         if (add_data) {
 441                 *(char*)v[0].iov_base = 'X';
 442                 v[0].iov_len = 1;
 443                 n = evbuffer_commit_space(buf, v, 1);
 444                 tt_int_op(n, ==, 0);
 445         } else if (fill_first) {
 446                 memset(v[0].iov_base, 'X', v[0].iov_len);
 447                 n = evbuffer_commit_space(buf, v, 1);
 448                 tt_int_op(n, ==, 0);
 449                 n = evbuffer_reserve_space(buf, 128, v, 2);
 450                 tt_int_op(n, ==, 1);
 451                 sz = v[0].iov_len;
 452                 tt_assert(v[0].iov_base != cp1);
 453                 cp1 = v[0].iov_base;
 454         }
 455 
 456         /* Make another chunk get added. */
 457         n = evbuffer_reserve_space(buf, sz+128, v, 2);
 458         evbuffer_validate(buf);
 459         tt_int_op(n, ==, 2);
 460         sz = v[0].iov_len + v[1].iov_len;
 461         tt_int_op(sz, >=, v[0].iov_len+128);
 462         if (add_data) {
 463                 tt_assert(v[0].iov_base == cp1 + 1);
 464         } else {
 465                 tt_assert(v[0].iov_base == cp1);
 466         }
 467         cp1 = v[0].iov_base;
 468         cp2 = v[1].iov_base;
 469 
 470         /* And a third chunk. */
 471         n = evbuffer_reserve_space(buf, sz+128, v, 3);
 472         evbuffer_validate(buf);
 473         tt_int_op(n, ==, 3);
 474         tt_assert(cp1 == v[0].iov_base);
 475         tt_assert(cp2 == v[1].iov_base);
 476         sz = v[0].iov_len + v[1].iov_len + v[2].iov_len;
 477 
 478         /* Now force a reallocation by asking for more space in only 2
 479          * buffers. */
 480         n = evbuffer_reserve_space(buf, sz+128, v, 2);
 481         evbuffer_validate(buf);
 482         if (add_data) {
 483                 tt_int_op(n, ==, 2);
 484                 tt_assert(cp1 == v[0].iov_base);
 485         } else {
 486                 tt_int_op(n, ==, 1);
 487         }
 488 
 489 end:
 490         evbuffer_free(buf);
 491 }
 492 
 493 static void
 494 test_evbuffer_expand(void *ptr)
 495 {
 496         char data[4096];
 497         struct evbuffer *buf;
 498         size_t a,w,u;
 499         void *buffer;
 500 
 501         memset(data, 'X', sizeof(data));
 502 
 503         /* Make sure that expand() works on an empty buffer */
 504         buf = evbuffer_new();
 505         tt_int_op(evbuffer_expand(buf, 20000), ==, 0);
 506         evbuffer_validate(buf);
 507         a=w=u=0;
 508         evbuffer_get_waste(buf, &a,&w,&u);
 509         tt_assert(w == 0);
 510         tt_assert(u == 0);
 511         tt_assert(a >= 20000);
 512         tt_assert(buf->first);
 513         tt_assert(buf->first == buf->last);
 514         tt_assert(buf->first->off == 0);
 515         tt_assert(buf->first->buffer_len >= 20000);
 516 
 517         /* Make sure that expand() works as a no-op when there's enough
 518          * contiguous space already. */
 519         buffer = buf->first->buffer;
 520         evbuffer_add(buf, data, 1024);
 521         tt_int_op(evbuffer_expand(buf, 1024), ==, 0);
 522         tt_assert(buf->first->buffer == buffer);
 523         evbuffer_validate(buf);
 524         evbuffer_free(buf);
 525 
 526         /* Make sure that expand() can work by moving misaligned data
 527          * when it makes sense to do so. */
 528         buf = evbuffer_new();
 529         evbuffer_add(buf, data, 400);
 530         {
 531                 int n = (int)(buf->first->buffer_len - buf->first->off - 1);
 532                 tt_assert(n < (int)sizeof(data));
 533                 evbuffer_add(buf, data, n);
 534         }
 535         tt_assert(buf->first == buf->last);
 536         tt_assert(buf->first->off == buf->first->buffer_len - 1);
 537         evbuffer_drain(buf, buf->first->off - 1);
 538         tt_assert(1 == evbuffer_get_length(buf));
 539         tt_assert(buf->first->misalign > 0);
 540         tt_assert(buf->first->off == 1);
 541         buffer = buf->first->buffer;
 542         tt_assert(evbuffer_expand(buf, 40) == 0);
 543         tt_assert(buf->first == buf->last);
 544         tt_assert(buf->first->off == 1);
 545         tt_assert(buf->first->buffer == buffer);
 546         tt_assert(buf->first->misalign == 0);
 547         evbuffer_validate(buf);
 548         evbuffer_free(buf);
 549 
 550         /* add, expand, pull-up: This used to crash libevent. */
 551         buf = evbuffer_new();
 552 
 553         evbuffer_add(buf, data, sizeof(data));
 554         evbuffer_add(buf, data, sizeof(data));
 555         evbuffer_add(buf, data, sizeof(data));
 556 
 557         evbuffer_validate(buf);
 558         evbuffer_expand(buf, 1024);
 559         evbuffer_validate(buf);
 560         evbuffer_pullup(buf, -1);
 561         evbuffer_validate(buf);
 562 
 563 end:
 564         evbuffer_free(buf);
 565 }
 566 
 567 
 568 static int reference_cb_called;
 569 static void
 570 reference_cb(const void *data, size_t len, void *extra)
 571 {
 572         tt_str_op(data, ==, "this is what we add as read-only memory.");
 573         tt_int_op(len, ==, strlen(data));
 574         tt_want(extra == (void *)0xdeadaffe);
 575         ++reference_cb_called;
 576 end:
 577         ;
 578 }
 579 
 580 static void
 581 test_evbuffer_reference(void *ptr)
 582 {
 583         struct evbuffer *src = evbuffer_new();
 584         struct evbuffer *dst = evbuffer_new();
 585         struct evbuffer_iovec v[1];
 586         const char *data = "this is what we add as read-only memory.";
 587         reference_cb_called = 0;
 588 
 589         tt_assert(evbuffer_add_reference(src, data, strlen(data),
 590                  reference_cb, (void *)0xdeadaffe) != -1);
 591 
 592         evbuffer_reserve_space(dst, strlen(data), v, 1);
 593         tt_assert(evbuffer_remove(src, v[0].iov_base, 10) != -1);
 594 
 595         evbuffer_validate(src);
 596         evbuffer_validate(dst);
 597 
 598         /* make sure that we don't write data at the beginning */
 599         evbuffer_prepend(src, "aaaaa", 5);
 600         evbuffer_validate(src);
 601         evbuffer_drain(src, 5);
 602 
 603         tt_assert(evbuffer_remove(src, ((char*)(v[0].iov_base)) + 10,
 604                 strlen(data) - 10) != -1);
 605 
 606         v[0].iov_len = strlen(data);
 607 
 608         evbuffer_commit_space(dst, v, 1);
 609         evbuffer_validate(src);
 610         evbuffer_validate(dst);
 611 
 612         tt_int_op(reference_cb_called, ==, 1);
 613 
 614         tt_assert(!memcmp(evbuffer_pullup(dst, strlen(data)),
 615                           data, strlen(data)));
 616         evbuffer_validate(dst);
 617 
 618  end:
 619         evbuffer_free(dst);
 620         evbuffer_free(src);
 621 }
 622 
 623 int _evbuffer_testing_use_sendfile(void);
 624 int _evbuffer_testing_use_mmap(void);
 625 int _evbuffer_testing_use_linear_file_access(void);
 626 
 627 static void
 628 test_evbuffer_add_file(void *ptr)
 629 {
 630         const char *impl = ptr;
 631         struct evbuffer *src = evbuffer_new();
 632         const char *data = "this is what we add as file system data.";
 633         size_t datalen;
 634         const char *compare;
 635         int fd = -1;
 636         evutil_socket_t pair[2] = {-1, -1};
 637         int r=0, n_written=0;
 638 
 639         /* Add a test for a big file. XXXX */
 640 
 641         tt_assert(impl);
 642         if (!strcmp(impl, "sendfile")) {
 643                 if (!_evbuffer_testing_use_sendfile())
 644                         tt_skip();
 645                 TT_BLATHER(("Using sendfile-based implementaion"));
 646         } else if (!strcmp(impl, "mmap")) {
 647                 if (!_evbuffer_testing_use_mmap())
 648                         tt_skip();
 649                 TT_BLATHER(("Using mmap-based implementaion"));
 650         } else if (!strcmp(impl, "linear")) {
 651                 if (!_evbuffer_testing_use_linear_file_access())
 652                         tt_skip();
 653                 TT_BLATHER(("Using read-based implementaion"));
 654         } else {
 655                 TT_DIE(("Didn't recognize the implementation"));
 656         }
 657 
 658         /* Say that it drains to a fd so that we can use sendfile. */
 659         evbuffer_set_flags(src, EVBUFFER_FLAG_DRAINS_TO_FD);
 660 
 661 #if defined(_EVENT_HAVE_SENDFILE) && defined(__sun__) && defined(__svr4__)
 662         /* We need to use a pair of AF_INET sockets, since Solaris
 663            doesn't support sendfile() over AF_UNIX. */
 664         if (evutil_ersatz_socketpair(AF_INET, SOCK_STREAM, 0, pair) == -1)
 665                 tt_abort_msg("ersatz_socketpair failed");
 666 #else
 667         if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1)
 668                 tt_abort_msg("socketpair failed");
 669 #endif
 670 
 671         datalen = strlen(data);
 672         fd = regress_make_tmpfile(data, datalen);
 673 
 674         tt_assert(fd != -1);
 675 
 676         tt_assert(evbuffer_add_file(src, fd, 0, datalen) != -1);
 677 
 678         evbuffer_validate(src);
 679 
 680         while (evbuffer_get_length(src) &&
 681             (r = evbuffer_write(src, pair[0])) > 0) {
 682                 evbuffer_validate(src);
 683                 n_written += r;
 684         }
 685         tt_int_op(r, !=, -1);
 686         tt_int_op(n_written, ==, datalen);
 687 
 688         evbuffer_validate(src);
 689         tt_int_op(evbuffer_read(src, pair[1], (int)strlen(data)), ==, datalen);
 690         evbuffer_validate(src);
 691         compare = (char *)evbuffer_pullup(src, datalen);
 692         tt_assert(compare != NULL);
 693         if (memcmp(compare, data, datalen))
 694                 tt_abort_msg("Data from add_file differs.");
 695 
 696         evbuffer_validate(src);
 697  end:
 698         if (pair[0] >= 0)
 699                 evutil_closesocket(pair[0]);
 700         if (pair[1] >= 0)
 701                 evutil_closesocket(pair[1]);
 702         evbuffer_free(src);
 703 }
 704 
 705 #ifndef _EVENT_DISABLE_MM_REPLACEMENT
 706 static void *
 707 failing_malloc(size_t how_much)
 708 {
 709         errno = ENOMEM;
 710         return NULL;
 711 }
 712 #endif
 713 
 714 static void
 715 test_evbuffer_readln(void *ptr)
 716 {
 717         struct evbuffer *evb = evbuffer_new();
 718         struct evbuffer *evb_tmp = evbuffer_new();
 719         const char *s;
 720         char *cp = NULL;
 721         size_t sz;
 722 
 723 #define tt_line_eq(content)                                             \
 724         TT_STMT_BEGIN                                                   \
 725         if (!cp || sz != strlen(content) || strcmp(cp, content)) {      \
 726                 TT_DIE(("Wanted %s; got %s [%d]", content, cp, (int)sz)); \
 727         }                                                               \
 728         TT_STMT_END
 729 
 730         /* Test EOL_ANY. */
 731         s = "complex silly newline\r\n\n\r\n\n\rmore\0\n";
 732         evbuffer_add(evb, s, strlen(s)+2);
 733         evbuffer_validate(evb);
 734         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY);
 735         tt_line_eq("complex silly newline");
 736         free(cp);
 737         evbuffer_validate(evb);
 738         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY);
 739         if (!cp || sz != 5 || memcmp(cp, "more\0\0", 6))
 740                 tt_abort_msg("Not as expected");
 741         tt_uint_op(evbuffer_get_length(evb), ==, 0);
 742         evbuffer_validate(evb);
 743         s = "\nno newline";
 744         evbuffer_add(evb, s, strlen(s));
 745         free(cp);
 746         evbuffer_validate(evb);
 747         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY);
 748         tt_line_eq("");
 749         free(cp);
 750         evbuffer_validate(evb);
 751         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY);
 752         tt_assert(!cp);
 753         evbuffer_validate(evb);
 754         evbuffer_drain(evb, evbuffer_get_length(evb));
 755         tt_assert(evbuffer_get_length(evb) == 0);
 756         evbuffer_validate(evb);
 757 
 758         /* Test EOL_CRLF */
 759         s = "Line with\rin the middle\nLine with good crlf\r\n\nfinal\n";
 760         evbuffer_add(evb, s, strlen(s));
 761         evbuffer_validate(evb);
 762         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
 763         tt_line_eq("Line with\rin the middle");
 764         free(cp);
 765         evbuffer_validate(evb);
 766 
 767         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
 768         tt_line_eq("Line with good crlf");
 769         free(cp);
 770         evbuffer_validate(evb);
 771 
 772         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
 773         tt_line_eq("");
 774         free(cp);
 775         evbuffer_validate(evb);
 776 
 777         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
 778         tt_line_eq("final");
 779         s = "x";
 780         evbuffer_validate(evb);
 781         evbuffer_add(evb, s, 1);
 782         evbuffer_validate(evb);
 783         free(cp);
 784         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
 785         tt_assert(!cp);
 786         evbuffer_validate(evb);
 787 
 788         /* Test CRLF_STRICT */
 789         s = " and a bad crlf\nand a good one\r\n\r\nMore\r";
 790         evbuffer_add(evb, s, strlen(s));
 791         evbuffer_validate(evb);
 792         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
 793         tt_line_eq("x and a bad crlf\nand a good one");
 794         free(cp);
 795         evbuffer_validate(evb);
 796 
 797         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
 798         tt_line_eq("");
 799         free(cp);
 800         evbuffer_validate(evb);
 801 
 802         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
 803         tt_assert(!cp);
 804         evbuffer_validate(evb);
 805         evbuffer_add(evb, "\n", 1);
 806         evbuffer_validate(evb);
 807 
 808         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
 809         tt_line_eq("More");
 810         free(cp);
 811         tt_assert(evbuffer_get_length(evb) == 0);
 812         evbuffer_validate(evb);
 813 
 814         s = "An internal CR\r is not an eol\r\nNor is a lack of one";
 815         evbuffer_add(evb, s, strlen(s));
 816         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
 817         tt_line_eq("An internal CR\r is not an eol");
 818         free(cp);
 819         evbuffer_validate(evb);
 820 
 821         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
 822         tt_assert(!cp);
 823         evbuffer_validate(evb);
 824 
 825         evbuffer_add(evb, "\r\n", 2);
 826         evbuffer_validate(evb);
 827         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
 828         tt_line_eq("Nor is a lack of one");
 829         free(cp);
 830         tt_assert(evbuffer_get_length(evb) == 0);
 831         evbuffer_validate(evb);
 832 
 833         /* Test LF */
 834         s = "An\rand a nl\n\nText";
 835         evbuffer_add(evb, s, strlen(s));
 836         evbuffer_validate(evb);
 837 
 838         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
 839         tt_line_eq("An\rand a nl");
 840         free(cp);
 841         evbuffer_validate(evb);
 842 
 843         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
 844         tt_line_eq("");
 845         free(cp);
 846         evbuffer_validate(evb);
 847 
 848         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
 849         tt_assert(!cp);
 850         free(cp);
 851         evbuffer_add(evb, "\n", 1);
 852         evbuffer_validate(evb);
 853         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
 854         tt_line_eq("Text");
 855         free(cp);
 856         evbuffer_validate(evb);
 857 
 858         /* Test CRLF_STRICT - across boundaries*/
 859         s = " and a bad crlf\nand a good one\r";
 860         evbuffer_add(evb_tmp, s, strlen(s));
 861         evbuffer_validate(evb);
 862         evbuffer_add_buffer(evb, evb_tmp);
 863         evbuffer_validate(evb);
 864         s = "\n\r";
 865         evbuffer_add(evb_tmp, s, strlen(s));
 866         evbuffer_validate(evb);
 867         evbuffer_add_buffer(evb, evb_tmp);
 868         evbuffer_validate(evb);
 869         s = "\nMore\r";
 870         evbuffer_add(evb_tmp, s, strlen(s));
 871         evbuffer_validate(evb);
 872         evbuffer_add_buffer(evb, evb_tmp);
 873         evbuffer_validate(evb);
 874 
 875         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
 876         tt_line_eq(" and a bad crlf\nand a good one");
 877         free(cp);
 878         evbuffer_validate(evb);
 879 
 880         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
 881         tt_line_eq("");
 882         free(cp);
 883         evbuffer_validate(evb);
 884 
 885         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
 886         tt_assert(!cp);
 887         free(cp);
 888         evbuffer_validate(evb);
 889         evbuffer_add(evb, "\n", 1);
 890         evbuffer_validate(evb);
 891         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
 892         tt_line_eq("More");
 893         free(cp); cp = NULL;
 894         evbuffer_validate(evb);
 895         tt_assert(evbuffer_get_length(evb) == 0);
 896 
 897         /* Test memory problem*/
 898         s = "one line\ntwo line\nblue line";
 899         evbuffer_add(evb_tmp, s, strlen(s));
 900         evbuffer_validate(evb);
 901         evbuffer_add_buffer(evb, evb_tmp);
 902         evbuffer_validate(evb);
 903 
 904         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
 905         tt_line_eq("one line");
 906         free(cp); cp = NULL;
 907         evbuffer_validate(evb);
 908 
 909         /* the next call to readline should fail */
 910 #ifndef _EVENT_DISABLE_MM_REPLACEMENT
 911         event_set_mem_functions(failing_malloc, realloc, free);
 912         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
 913         tt_assert(cp == NULL);
 914         evbuffer_validate(evb);
 915 
 916         /* now we should get the next line back */
 917         event_set_mem_functions(malloc, realloc, free);
 918 #endif
 919         cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
 920         tt_line_eq("two line");
 921         free(cp); cp = NULL;
 922         evbuffer_validate(evb);
 923 
 924  end:
 925         evbuffer_free(evb);
 926         evbuffer_free(evb_tmp);
 927         if (cp) free(cp);
 928 }
 929 
 930 static void
 931 test_evbuffer_search_eol(void *ptr)
 932 {
 933         struct evbuffer *buf = evbuffer_new();
 934         struct evbuffer_ptr ptr1, ptr2;
 935         const char *s;
 936         size_t eol_len;
 937 
 938         s = "string! \r\n\r\nx\n";
 939         evbuffer_add(buf, s, strlen(s));
 940         eol_len = -1;
 941         ptr1 = evbuffer_search_eol(buf, NULL, &eol_len, EVBUFFER_EOL_CRLF);
 942         tt_int_op(ptr1.pos, ==, 8);
 943         tt_int_op(eol_len, ==, 2);
 944 
 945         eol_len = -1;
 946         ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_CRLF);
 947         tt_int_op(ptr2.pos, ==, 8);
 948         tt_int_op(eol_len, ==, 2);
 949 
 950         evbuffer_ptr_set(buf, &ptr1, 1, EVBUFFER_PTR_ADD);
 951         eol_len = -1;
 952         ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_CRLF);
 953         tt_int_op(ptr2.pos, ==, 9);
 954         tt_int_op(eol_len, ==, 1);
 955 
 956         eol_len = -1;
 957         ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_CRLF_STRICT);
 958         tt_int_op(ptr2.pos, ==, 10);
 959         tt_int_op(eol_len, ==, 2);
 960 
 961         eol_len = -1;
 962         ptr1 = evbuffer_search_eol(buf, NULL, &eol_len, EVBUFFER_EOL_LF);
 963         tt_int_op(ptr1.pos, ==, 9);
 964         tt_int_op(eol_len, ==, 1);
 965 
 966         eol_len = -1;
 967         ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_LF);
 968         tt_int_op(ptr2.pos, ==, 9);
 969         tt_int_op(eol_len, ==, 1);
 970 
 971         evbuffer_ptr_set(buf, &ptr1, 1, EVBUFFER_PTR_ADD);
 972         eol_len = -1;
 973         ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_LF);
 974         tt_int_op(ptr2.pos, ==, 11);
 975         tt_int_op(eol_len, ==, 1);
 976 
 977 end:
 978         evbuffer_free(buf);
 979 }
 980 
 981 static void
 982 test_evbuffer_iterative(void *ptr)
 983 {
 984         struct evbuffer *buf = evbuffer_new();
 985         const char *abc = "abcdefghijklmnopqrstvuwxyzabcdefghijklmnopqrstvuwxyzabcdefghijklmnopqrstvuwxyzabcdefghijklmnopqrstvuwxyz";
 986         unsigned i, j, sum, n;
 987 
 988         sum = 0;
 989         n = 0;
 990         for (i = 0; i < 1000; ++i) {
 991                 for (j = 1; j < strlen(abc); ++j) {
 992                         char format[32];
 993                         evutil_snprintf(format, sizeof(format), "%%%u.%us", j, j);
 994                         evbuffer_add_printf(buf, format, abc);
 995 
 996                         /* Only check for rep violations every so often.
 997                            Walking over the whole list of chains can get
 998                            pretty expensive as it gets long.
 999                          */
1000                         if ((n % 337) == 0)
1001                                 evbuffer_validate(buf);
1002 
1003                         sum += j;
1004                         n++;
1005                 }
1006         }
1007         evbuffer_validate(buf);
1008 
1009         tt_uint_op(sum, ==, evbuffer_get_length(buf));
1010 
1011         {
1012                 size_t a,w,u;
1013                 a=w=u=0;
1014                 evbuffer_get_waste(buf, &a, &w, &u);
1015                 if (0)
1016                         printf("Allocated: %u.\nWasted: %u.\nUsed: %u.",
1017                             (unsigned)a, (unsigned)w, (unsigned)u);
1018                 tt_assert( ((double)w)/a < .125);
1019         }
1020  end:
1021         evbuffer_free(buf);
1022 
1023 }
1024 
1025 static void
1026 test_evbuffer_find(void *ptr)
1027 {
1028         u_char* p;
1029         const char* test1 = "1234567890\r\n";
1030         const char* test2 = "1234567890\r";
1031 #define EVBUFFER_INITIAL_LENGTH 256
1032         char test3[EVBUFFER_INITIAL_LENGTH];
1033         unsigned int i;
1034         struct evbuffer * buf = evbuffer_new();
1035 
1036         tt_assert(buf);
1037 
1038         /* make sure evbuffer_find doesn't match past the end of the buffer */
1039         evbuffer_add(buf, (u_char*)test1, strlen(test1));
1040         evbuffer_validate(buf);
1041         evbuffer_drain(buf, strlen(test1));
1042         evbuffer_validate(buf);
1043         evbuffer_add(buf, (u_char*)test2, strlen(test2));
1044         evbuffer_validate(buf);
1045         p = evbuffer_find(buf, (u_char*)"\r\n", 2);
1046         tt_want(p == NULL);
1047 
1048         /*
1049          * drain the buffer and do another find; in r309 this would
1050          * read past the allocated buffer causing a valgrind error.
1051          */
1052         evbuffer_drain(buf, strlen(test2));
1053         evbuffer_validate(buf);
1054         for (i = 0; i < EVBUFFER_INITIAL_LENGTH; ++i)
1055                 test3[i] = 'a';
1056         test3[EVBUFFER_INITIAL_LENGTH - 1] = 'x';
1057         evbuffer_add(buf, (u_char *)test3, EVBUFFER_INITIAL_LENGTH);
1058         evbuffer_validate(buf);
1059         p = evbuffer_find(buf, (u_char *)"xy", 2);
1060         tt_want(p == NULL);
1061 
1062         /* simple test for match at end of allocated buffer */
1063         p = evbuffer_find(buf, (u_char *)"ax", 2);
1064         tt_assert(p != NULL);
1065         tt_want(strncmp((char*)p, "ax", 2) == 0);
1066 
1067 end:
1068         if (buf)
1069                 evbuffer_free(buf);
1070 }
1071 
1072 static void
1073 test_evbuffer_ptr_set(void *ptr)
1074 {
1075         struct evbuffer *buf = evbuffer_new();
1076         struct evbuffer_ptr pos;
1077         struct evbuffer_iovec v[1];
1078 
1079         tt_assert(buf);
1080 
1081         /* create some chains */
1082         evbuffer_reserve_space(buf, 5000, v, 1);
1083         v[0].iov_len = 5000;
1084         memset(v[0].iov_base, 1, v[0].iov_len);
1085         evbuffer_commit_space(buf, v, 1);
1086         evbuffer_validate(buf);
1087 
1088         evbuffer_reserve_space(buf, 4000, v, 1);
1089         v[0].iov_len = 4000;
1090         memset(v[0].iov_base, 2, v[0].iov_len);
1091         evbuffer_commit_space(buf, v, 1);
1092 
1093         evbuffer_reserve_space(buf, 3000, v, 1);
1094         v[0].iov_len = 3000;
1095         memset(v[0].iov_base, 3, v[0].iov_len);
1096         evbuffer_commit_space(buf, v, 1);
1097         evbuffer_validate(buf);
1098 
1099         tt_int_op(evbuffer_get_length(buf), ==, 12000);
1100 
1101         tt_assert(evbuffer_ptr_set(buf, &pos, 13000, EVBUFFER_PTR_SET) == -1);
1102         tt_assert(pos.pos == -1);
1103         tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
1104         tt_assert(pos.pos == 0);
1105         tt_assert(evbuffer_ptr_set(buf, &pos, 13000, EVBUFFER_PTR_ADD) == -1);
1106 
1107         tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
1108         tt_assert(pos.pos == 0);
1109         tt_assert(evbuffer_ptr_set(buf, &pos, 10000, EVBUFFER_PTR_ADD) == 0);
1110         tt_assert(pos.pos == 10000);
1111         tt_assert(evbuffer_ptr_set(buf, &pos, 1000, EVBUFFER_PTR_ADD) == 0);
1112         tt_assert(pos.pos == 11000);
1113         tt_assert(evbuffer_ptr_set(buf, &pos, 1000, EVBUFFER_PTR_ADD) == -1);
1114         tt_assert(pos.pos == -1);
1115 
1116 end:
1117         if (buf)
1118                 evbuffer_free(buf);
1119 }
1120 
1121 static void
1122 test_evbuffer_search(void *ptr)
1123 {
1124         struct evbuffer *buf = evbuffer_new();
1125         struct evbuffer *tmp = evbuffer_new();
1126         struct evbuffer_ptr pos, end;
1127 
1128         tt_assert(buf);
1129         tt_assert(tmp);
1130 
1131         /* set up our chains */
1132         evbuffer_add_printf(tmp, "hello");  /* 5 chars */
1133         evbuffer_add_buffer(buf, tmp);
1134         evbuffer_add_printf(tmp, "foo");    /* 3 chars */
1135         evbuffer_add_buffer(buf, tmp);
1136         evbuffer_add_printf(tmp, "cat");    /* 3 chars */
1137         evbuffer_add_buffer(buf, tmp);
1138         evbuffer_add_printf(tmp, "attack");
1139         evbuffer_add_buffer(buf, tmp);
1140 
1141         pos = evbuffer_search(buf, "attack", 6, NULL);
1142         tt_int_op(pos.pos, ==, 11);
1143         pos = evbuffer_search(buf, "attacker", 8, NULL);
1144         tt_int_op(pos.pos, ==, -1);
1145 
1146         /* test continuing search */
1147         pos = evbuffer_search(buf, "oc", 2, NULL);
1148         tt_int_op(pos.pos, ==, 7);
1149         pos = evbuffer_search(buf, "cat", 3, &pos);
1150         tt_int_op(pos.pos, ==, 8);
1151         pos = evbuffer_search(buf, "tacking", 7, &pos);
1152         tt_int_op(pos.pos, ==, -1);
1153 
1154         evbuffer_ptr_set(buf, &pos, 5, EVBUFFER_PTR_SET);
1155         pos = evbuffer_search(buf, "foo", 3, &pos);
1156         tt_int_op(pos.pos, ==, 5);
1157 
1158         evbuffer_ptr_set(buf, &pos, 2, EVBUFFER_PTR_ADD);
1159         pos = evbuffer_search(buf, "tat", 3, &pos);
1160         tt_int_op(pos.pos, ==, 10);
1161 
1162         /* test bounded search. */
1163         /* Set "end" to the first t in "attack". */
1164         evbuffer_ptr_set(buf, &end, 12, EVBUFFER_PTR_SET);
1165         pos = evbuffer_search_range(buf, "foo", 3, NULL, &end);
1166         tt_int_op(pos.pos, ==, 5);
1167         pos = evbuffer_search_range(buf, "foocata", 7, NULL, &end);
1168         tt_int_op(pos.pos, ==, 5);
1169         pos = evbuffer_search_range(buf, "foocatat", 8, NULL, &end);
1170         tt_int_op(pos.pos, ==, -1);
1171         pos = evbuffer_search_range(buf, "ack", 3, NULL, &end);
1172         tt_int_op(pos.pos, ==, -1);
1173 
1174 
1175 end:
1176         if (buf)
1177                 evbuffer_free(buf);
1178         if (tmp)
1179                 evbuffer_free(tmp);
1180 }
1181 
1182 static void
1183 log_change_callback(struct evbuffer *buffer,
1184     const struct evbuffer_cb_info *cbinfo,
1185     void *arg)
1186 {
1187 
1188         size_t old_len = cbinfo->orig_size;
1189         size_t new_len = old_len + cbinfo->n_added - cbinfo->n_deleted;
1190         struct evbuffer *out = arg;
1191         evbuffer_add_printf(out, "%lu->%lu; ", (unsigned long)old_len,
1192                             (unsigned long)new_len);
1193 }
1194 static void
1195 self_draining_callback(struct evbuffer *evbuffer, size_t old_len,
1196                 size_t new_len, void *arg)
1197 {
1198         if (new_len > old_len)
1199                 evbuffer_drain(evbuffer, new_len);
1200 }
1201 
1202 static void
1203 test_evbuffer_callbacks(void *ptr)
1204 {
1205         struct evbuffer *buf = evbuffer_new();
1206         struct evbuffer *buf_out1 = evbuffer_new();
1207         struct evbuffer *buf_out2 = evbuffer_new();
1208         struct evbuffer_cb_entry *cb1, *cb2;
1209 
1210         tt_assert(buf);
1211         tt_assert(buf_out1);
1212         tt_assert(buf_out2);
1213 
1214         cb1 = evbuffer_add_cb(buf, log_change_callback, buf_out1);
1215         cb2 = evbuffer_add_cb(buf, log_change_callback, buf_out2);
1216 
1217         /* Let's run through adding and deleting some stuff from the buffer
1218          * and turning the callbacks on and off and removing them.  The callback
1219          * adds a summary of length changes to buf_out1/buf_out2 when called. */
1220         /* size: 0-> 36. */
1221         evbuffer_add_printf(buf, "The %d magic words are spotty pudding", 2);
1222         evbuffer_validate(buf);
1223         evbuffer_cb_clear_flags(buf, cb2, EVBUFFER_CB_ENABLED);
1224         evbuffer_drain(buf, 10); /*36->26*/
1225         evbuffer_validate(buf);
1226         evbuffer_prepend(buf, "Hello", 5);/*26->31*/
1227         evbuffer_cb_set_flags(buf, cb2, EVBUFFER_CB_ENABLED);
1228         evbuffer_add_reference(buf, "Goodbye", 7, NULL, NULL); /*31->38*/
1229         evbuffer_remove_cb_entry(buf, cb1);
1230         evbuffer_validate(buf);
1231         evbuffer_drain(buf, evbuffer_get_length(buf)); /*38->0*/;
1232         tt_assert(-1 == evbuffer_remove_cb(buf, log_change_callback, NULL));
1233         evbuffer_add(buf, "X", 1); /* 0->1 */
1234         tt_assert(!evbuffer_remove_cb(buf, log_change_callback, buf_out2));
1235         evbuffer_validate(buf);
1236 
1237         tt_str_op(evbuffer_pullup(buf_out1, -1), ==,
1238                   "0->36; 36->26; 26->31; 31->38; ");
1239         tt_str_op(evbuffer_pullup(buf_out2, -1), ==,
1240                   "0->36; 31->38; 38->0; 0->1; ");
1241         evbuffer_drain(buf_out1, evbuffer_get_length(buf_out1));
1242         evbuffer_drain(buf_out2, evbuffer_get_length(buf_out2));
1243         /* Let's test the obsolete buffer_setcb function too. */
1244         cb1 = evbuffer_add_cb(buf, log_change_callback, buf_out1);
1245         tt_assert(cb1 != NULL);
1246         cb2 = evbuffer_add_cb(buf, log_change_callback, buf_out2);
1247         tt_assert(cb2 != NULL);
1248         evbuffer_setcb(buf, self_draining_callback, NULL);
1249         evbuffer_add_printf(buf, "This should get drained right away.");
1250         tt_uint_op(evbuffer_get_length(buf), ==, 0);
1251         tt_uint_op(evbuffer_get_length(buf_out1), ==, 0);
1252         tt_uint_op(evbuffer_get_length(buf_out2), ==, 0);
1253         evbuffer_setcb(buf, NULL, NULL);
1254         evbuffer_add_printf(buf, "This will not.");
1255         tt_str_op(evbuffer_pullup(buf, -1), ==, "This will not.");
1256         evbuffer_validate(buf);
1257         evbuffer_drain(buf, evbuffer_get_length(buf));
1258         evbuffer_validate(buf);
1259 #if 0
1260         /* Now let's try a suspended callback. */
1261         cb1 = evbuffer_add_cb(buf, log_change_callback, buf_out1);
1262         cb2 = evbuffer_add_cb(buf, log_change_callback, buf_out2);
1263         evbuffer_cb_suspend(buf,cb2);
1264         evbuffer_prepend(buf,"Hello world",11); /*0->11*/
1265         evbuffer_validate(buf);
1266         evbuffer_cb_suspend(buf,cb1);
1267         evbuffer_add(buf,"more",4); /* 11->15 */
1268         evbuffer_cb_unsuspend(buf,cb2);
1269         evbuffer_drain(buf, 4); /* 15->11 */
1270         evbuffer_cb_unsuspend(buf,cb1);
1271         evbuffer_drain(buf, evbuffer_get_length(buf)); /* 11->0 */
1272 
1273         tt_str_op(evbuffer_pullup(buf_out1, -1), ==,
1274                   "0->11; 11->11; 11->0; ");
1275         tt_str_op(evbuffer_pullup(buf_out2, -1), ==,
1276                   "0->15; 15->11; 11->0; ");
1277 #endif
1278 
1279  end:
1280         if (buf)
1281                 evbuffer_free(buf);
1282         if (buf_out1)
1283                 evbuffer_free(buf_out1);
1284         if (buf_out2)
1285                 evbuffer_free(buf_out2);
1286 }
1287 
1288 static int ref_done_cb_called_count = 0;
1289 static void *ref_done_cb_called_with = NULL;
1290 static const void *ref_done_cb_called_with_data = NULL;
1291 static size_t ref_done_cb_called_with_len = 0;
1292 static void ref_done_cb(const void *data, size_t len, void *info)
1293 {
1294         ++ref_done_cb_called_count;
1295         ref_done_cb_called_with = info;
1296         ref_done_cb_called_with_data = data;
1297         ref_done_cb_called_with_len = len;
1298 }
1299 
1300 static void
1301 test_evbuffer_add_reference(void *ptr)
1302 {
1303         const char chunk1[] = "If you have found the answer to such a problem";
1304         const char chunk2[] = "you ought to write it up for publication";
1305                           /* -- Knuth's "Notes on the Exercises" from TAOCP */
1306         char tmp[16];
1307         size_t len1 = strlen(chunk1), len2=strlen(chunk2);
1308 
1309         struct evbuffer *buf1 = NULL, *buf2 = NULL;
1310 
1311         buf1 = evbuffer_new();
1312         tt_assert(buf1);
1313 
1314         evbuffer_add_reference(buf1, chunk1, len1, ref_done_cb, (void*)111);
1315         evbuffer_add(buf1, ", ", 2);
1316         evbuffer_add_reference(buf1, chunk2, len2, ref_done_cb, (void*)222);
1317         tt_int_op(evbuffer_get_length(buf1), ==, len1+len2+2);
1318 
1319         /* Make sure we can drain a little from a reference. */
1320         tt_int_op(evbuffer_remove(buf1, tmp, 6), ==, 6);
1321         tt_int_op(memcmp(tmp, "If you", 6), ==, 0);
1322         tt_int_op(evbuffer_remove(buf1, tmp, 5), ==, 5);
1323         tt_int_op(memcmp(tmp, " have", 5), ==, 0);
1324 
1325         /* Make sure that prepending does not meddle with immutable data */
1326         tt_int_op(evbuffer_prepend(buf1, "I have ", 7), ==, 0);
1327         tt_int_op(memcmp(chunk1, "If you", 6), ==, 0);
1328         evbuffer_validate(buf1);
1329 
1330         /* Make sure that when the chunk is over, the callback is invoked. */
1331         evbuffer_drain(buf1, 7); /* Remove prepended stuff. */
1332         evbuffer_drain(buf1, len1-11-1); /* remove all but one byte of chunk1 */
1333         tt_int_op(ref_done_cb_called_count, ==, 0);
1334         evbuffer_remove(buf1, tmp, 1);
1335         tt_int_op(tmp[0], ==, 'm');
1336         tt_assert(ref_done_cb_called_with == (void*)111);
1337         tt_assert(ref_done_cb_called_with_data == chunk1);
1338         tt_assert(ref_done_cb_called_with_len == len1);
1339         tt_int_op(ref_done_cb_called_count, ==, 1);
1340         evbuffer_validate(buf1);
1341 
1342         /* Drain some of the remaining chunk, then add it to another buffer */
1343         evbuffer_drain(buf1, 6); /* Remove the ", you ". */
1344         buf2 = evbuffer_new();
1345         tt_assert(buf2);
1346         tt_int_op(ref_done_cb_called_count, ==, 1);
1347         evbuffer_add(buf2, "I ", 2);
1348 
1349         evbuffer_add_buffer(buf2, buf1);
1350         tt_int_op(ref_done_cb_called_count, ==, 1);
1351         evbuffer_remove(buf2, tmp, 16);
1352         tt_int_op(memcmp("I ought to write", tmp, 16), ==, 0);
1353         evbuffer_drain(buf2, evbuffer_get_length(buf2));
1354         tt_int_op(ref_done_cb_called_count, ==, 2);
1355         tt_assert(ref_done_cb_called_with == (void*)222);
1356         evbuffer_validate(buf2);
1357 
1358         /* Now add more stuff to buf1 and make sure that it gets removed on
1359          * free. */
1360         evbuffer_add(buf1, "You shake and shake the ", 24);
1361         evbuffer_add_reference(buf1, "ketchup bottle", 14, ref_done_cb,
1362             (void*)3333);
1363         evbuffer_add(buf1, ". Nothing comes and then a lot'll.", 42);
1364         evbuffer_free(buf1);
1365         buf1 = NULL;
1366         tt_int_op(ref_done_cb_called_count, ==, 3);
1367         tt_assert(ref_done_cb_called_with == (void*)3333);
1368 
1369 end:
1370         if (buf1)
1371                 evbuffer_free(buf1);
1372         if (buf2)
1373                 evbuffer_free(buf2);
1374 }
1375 
1376 /* Some cases that we didn't get in test_evbuffer() above, for more coverage. */
1377 static void
1378 test_evbuffer_prepend(void *ptr)
1379 {
1380         struct evbuffer *buf1 = NULL, *buf2 = NULL;
1381         char tmp[128];
1382         int n;
1383 
1384         buf1 = evbuffer_new();
1385         tt_assert(buf1);
1386 
1387         /* Case 0: The evbuffer is entirely empty. */
1388         evbuffer_prepend(buf1, "This string has 29 characters", 29);
1389         evbuffer_validate(buf1);
1390 
1391         /* Case 1: Prepend goes entirely in new chunk. */
1392         evbuffer_prepend(buf1, "Short.", 6);
1393         evbuffer_validate(buf1);
1394 
1395         /* Case 2: prepend goes entirely in first chunk. */
1396         evbuffer_drain(buf1, 6+11);
1397         evbuffer_prepend(buf1, "it", 2);
1398         evbuffer_validate(buf1);
1399         tt_assert(!memcmp(buf1->first->buffer+buf1->first->misalign,
1400                 "it has", 6));
1401 
1402         /* Case 3: prepend is split over multiple chunks. */
1403         evbuffer_prepend(buf1, "It is no longer true to say ", 28);
1404         evbuffer_validate(buf1);
1405         n = evbuffer_remove(buf1, tmp, sizeof(tmp)-1);
1406         tmp[n]='\0';
1407         tt_str_op(tmp,==,"It is no longer true to say it has 29 characters");
1408 
1409         buf2 = evbuffer_new();
1410         tt_assert(buf2);
1411 
1412         /* Case 4: prepend a buffer to an empty buffer. */
1413         n = 999;
1414         evbuffer_add_printf(buf1, "Here is string %d. ", n++);
1415         evbuffer_prepend_buffer(buf2, buf1);
1416         evbuffer_validate(buf2);
1417 
1418         /* Case 5: prepend a buffer to a nonempty buffer. */
1419         evbuffer_add_printf(buf1, "Here is string %d. ", n++);
1420         evbuffer_prepend_buffer(buf2, buf1);
1421         evbuffer_validate(buf2);
1422         evbuffer_validate(buf1);
1423         n = evbuffer_remove(buf2, tmp, sizeof(tmp)-1);
1424         tmp[n]='\0';
1425         tt_str_op(tmp,==,"Here is string 1000. Here is string 999. ");
1426 
1427 end:
1428         if (buf1)
1429                 evbuffer_free(buf1);
1430         if (buf2)
1431                 evbuffer_free(buf2);
1432 
1433 }
1434 
1435 static void
1436 test_evbuffer_peek(void *info)
1437 {
1438         struct evbuffer *buf = NULL, *tmp_buf = NULL;
1439         int i;
1440         struct evbuffer_iovec v[20];
1441         struct evbuffer_ptr ptr;
1442 
1443 #define tt_iov_eq(v, s)                                         \
1444         tt_int_op((v)->iov_len, ==, strlen(s));                 \
1445         tt_assert(!memcmp((v)->iov_base, (s), strlen(s)))
1446 
1447         /* Let's make a very fragmented buffer. */
1448         buf = evbuffer_new();
1449         tmp_buf = evbuffer_new();
1450         for (i = 0; i < 16; ++i) {
1451                 evbuffer_add_printf(tmp_buf, "Contents of chunk [%d]\n", i);
1452                 evbuffer_add_buffer(buf, tmp_buf);
1453         }
1454 
1455         /* How many chunks do we need for everything? */
1456         i = evbuffer_peek(buf, -1, NULL, NULL, 0);
1457         tt_int_op(i, ==, 16);
1458 
1459         /* Simple peek: get everything. */
1460         i = evbuffer_peek(buf, -1, NULL, v, 20);
1461         tt_int_op(i, ==, 16); /* we used only 16 chunks. */
1462         tt_iov_eq(&v[0], "Contents of chunk [0]\n");
1463         tt_iov_eq(&v[3], "Contents of chunk [3]\n");
1464         tt_iov_eq(&v[12], "Contents of chunk [12]\n");
1465         tt_iov_eq(&v[15], "Contents of chunk [15]\n");
1466 
1467         /* Just get one chunk worth. */
1468         memset(v, 0, sizeof(v));
1469         i = evbuffer_peek(buf, -1, NULL, v, 1);
1470         tt_int_op(i, ==, 1);
1471         tt_iov_eq(&v[0], "Contents of chunk [0]\n");
1472         tt_assert(v[1].iov_base == NULL);
1473 
1474         /* Suppose we want at least the first 40 bytes. */
1475         memset(v, 0, sizeof(v));
1476         i = evbuffer_peek(buf, 40, NULL, v, 16);
1477         tt_int_op(i, ==, 2);
1478         tt_iov_eq(&v[0], "Contents of chunk [0]\n");
1479         tt_iov_eq(&v[1], "Contents of chunk [1]\n");
1480         tt_assert(v[2].iov_base == NULL);
1481 
1482         /* How many chunks do we need for 100 bytes? */
1483         memset(v, 0, sizeof(v));
1484         i = evbuffer_peek(buf, 100, NULL, NULL, 0);
1485         tt_int_op(i, ==, 5);
1486         tt_assert(v[0].iov_base == NULL);
1487 
1488         /* Now we ask for more bytes than we provide chunks for */
1489         memset(v, 0, sizeof(v));
1490         i = evbuffer_peek(buf, 60, NULL, v, 1);
1491         tt_int_op(i, ==, 3);
1492         tt_iov_eq(&v[0], "Contents of chunk [0]\n");
1493         tt_assert(v[1].iov_base == NULL);
1494 
1495         /* Now we ask for more bytes than the buffer has. */
1496         memset(v, 0, sizeof(v));
1497         i = evbuffer_peek(buf, 65536, NULL, v, 20);
1498         tt_int_op(i, ==, 16); /* we used only 16 chunks. */
1499         tt_iov_eq(&v[0], "Contents of chunk [0]\n");
1500         tt_iov_eq(&v[3], "Contents of chunk [3]\n");
1501         tt_iov_eq(&v[12], "Contents of chunk [12]\n");
1502         tt_iov_eq(&v[15], "Contents of chunk [15]\n");
1503         tt_assert(v[16].iov_base == NULL);
1504 
1505         /* What happens if we try an empty buffer? */
1506         memset(v, 0, sizeof(v));
1507         i = evbuffer_peek(tmp_buf, -1, NULL, v, 20);
1508         tt_int_op(i, ==, 0);
1509         tt_assert(v[0].iov_base == NULL);
1510         memset(v, 0, sizeof(v));
1511         i = evbuffer_peek(tmp_buf, 50, NULL, v, 20);
1512         tt_int_op(i, ==, 0);
1513         tt_assert(v[0].iov_base == NULL);
1514 
1515         /* Okay, now time to have fun with pointers. */
1516         memset(v, 0, sizeof(v));
1517         evbuffer_ptr_set(buf, &ptr, 30, EVBUFFER_PTR_SET);
1518         i = evbuffer_peek(buf, 50, &ptr, v, 20);
1519         tt_int_op(i, ==, 3);
1520         tt_iov_eq(&v[0], " of chunk [1]\n");
1521         tt_iov_eq(&v[1], "Contents of chunk [2]\n");
1522         tt_iov_eq(&v[2], "Contents of chunk [3]\n"); /*more than we asked for*/
1523 
1524         /* advance to the start of another chain. */
1525         memset(v, 0, sizeof(v));
1526         evbuffer_ptr_set(buf, &ptr, 14, EVBUFFER_PTR_ADD);
1527         i = evbuffer_peek(buf, 44, &ptr, v, 20);
1528         tt_int_op(i, ==, 2);
1529         tt_iov_eq(&v[0], "Contents of chunk [2]\n");
1530         tt_iov_eq(&v[1], "Contents of chunk [3]\n"); /*more than we asked for*/
1531 
1532 end:
1533         if (buf)
1534                 evbuffer_free(buf);
1535         if (tmp_buf)
1536                 evbuffer_free(tmp_buf);
1537 }
1538 
1539 /* Check whether evbuffer freezing works right.  This is called twice,
1540    once with the argument "start" and once with the argument "end".
1541    When we test "start", we freeze the start of an evbuffer and make sure
1542    that modifying the start of the buffer doesn't work.  When we test
1543    "end", we freeze the end of an evbuffer and make sure that modifying
1544    the end of the buffer doesn't work.
1545  */
1546 static void
1547 test_evbuffer_freeze(void *ptr)
1548 {
1549         struct evbuffer *buf = NULL, *tmp_buf=NULL;
1550         const char string[] = /* Year's End, Richard Wilbur */
1551             "I've known the wind by water banks to shake\n"
1552             "The late leaves down, which frozen where they fell\n"
1553             "And held in ice as dancers in a spell\n"
1554             "Fluttered all winter long into a lake...";
1555         const int start = !strcmp(ptr, "start");
1556         char *cp;
1557         char charbuf[128];
1558         int r;
1559         size_t orig_length;
1560         struct evbuffer_iovec v[1];
1561 
1562         if (!start)
1563                 tt_str_op(ptr, ==, "end");
1564 
1565         buf = evbuffer_new();
1566         tmp_buf = evbuffer_new();
1567         tt_assert(tmp_buf);
1568 
1569         evbuffer_add(buf, string, strlen(string));
1570         evbuffer_freeze(buf, start); /* Freeze the start or the end.*/
1571 
1572 #define FREEZE_EQ(a, startcase, endcase)                \
1573         do {                                            \
1574             if (start) {                                \
1575                     tt_int_op((a), ==, (startcase));    \
1576             } else {                                    \
1577                     tt_int_op((a), ==, (endcase));      \
1578             }                                           \
1579         } while (0)
1580 
1581 
1582         orig_length = evbuffer_get_length(buf);
1583 
1584         /* These functions all manipulate the end of buf. */
1585         r = evbuffer_add(buf, "abc", 0);
1586         FREEZE_EQ(r, 0, -1);
1587         r = evbuffer_reserve_space(buf, 10, v, 1);
1588         FREEZE_EQ(r, 1, -1);
1589         if (r == 0) {
1590                 memset(v[0].iov_base, 'X', 10);
1591                 v[0].iov_len = 10;
1592         }
1593         r = evbuffer_commit_space(buf, v, 1);
1594         FREEZE_EQ(r, 0, -1);
1595         r = evbuffer_add_reference(buf, string, 5, NULL, NULL);
1596         FREEZE_EQ(r, 0, -1);
1597         r = evbuffer_add_printf(buf, "Hello %s", "world");
1598         FREEZE_EQ(r, 11, -1);
1599         /* TODO: test add_buffer, add_file, read */
1600 
1601         if (!start)
1602                 tt_int_op(orig_length, ==, evbuffer_get_length(buf));
1603 
1604         orig_length = evbuffer_get_length(buf);
1605 
1606         /* These functions all manipulate the start of buf. */
1607         r = evbuffer_remove(buf, charbuf, 1);
1608         FREEZE_EQ(r, -1, 1);
1609         r = evbuffer_drain(buf, 3);
1610         FREEZE_EQ(r, -1, 0);
1611         r = evbuffer_prepend(buf, "dummy", 5);
1612         FREEZE_EQ(r, -1, 0);
1613         cp = evbuffer_readln(buf, NULL, EVBUFFER_EOL_LF);
1614         FREEZE_EQ(cp==NULL, 1, 0);
1615         if (cp)
1616                 free(cp);
1617         /* TODO: Test remove_buffer, add_buffer, write, prepend_buffer */
1618 
1619         if (start)
1620                 tt_int_op(orig_length, ==, evbuffer_get_length(buf));
1621 
1622 end:
1623         if (buf)
1624                 evbuffer_free(buf);
1625 
1626         if (tmp_buf)
1627                 evbuffer_free(tmp_buf);
1628 }
1629 
1630 static void *
1631 setup_passthrough(const struct testcase_t *testcase)
1632 {
1633         return testcase->setup_data;
1634 }
1635 static int
1636 cleanup_passthrough(const struct testcase_t *testcase, void *ptr)
1637 {
1638         (void) ptr;
1639         return 1;
1640 }
1641 
1642 static const struct testcase_setup_t nil_setup = {
1643         setup_passthrough,
1644         cleanup_passthrough
1645 };
1646 
1647 struct testcase_t evbuffer_testcases[] = {
1648         { "evbuffer", test_evbuffer, 0, NULL, NULL },
1649         { "remove_buffer_with_empty", test_evbuffer_remove_buffer_with_empty, 0, NULL, NULL },
1650         { "reserve2", test_evbuffer_reserve2, 0, NULL, NULL },
1651         { "reserve_many", test_evbuffer_reserve_many, 0, NULL, NULL },
1652         { "reserve_many2", test_evbuffer_reserve_many, 0, &nil_setup, (void*)"add" },
1653         { "reserve_many3", test_evbuffer_reserve_many, 0, &nil_setup, (void*)"fill" },
1654         { "expand", test_evbuffer_expand, 0, NULL, NULL },
1655         { "reference", test_evbuffer_reference, 0, NULL, NULL },
1656         { "iterative", test_evbuffer_iterative, 0, NULL, NULL },
1657         { "readln", test_evbuffer_readln, TT_NO_LOGS, &basic_setup, NULL },
1658         { "search_eol", test_evbuffer_search_eol, 0, NULL, NULL },
1659         { "find", test_evbuffer_find, 0, NULL, NULL },
1660         { "ptr_set", test_evbuffer_ptr_set, 0, NULL, NULL },
1661         { "search", test_evbuffer_search, 0, NULL, NULL },
1662         { "callbacks", test_evbuffer_callbacks, 0, NULL, NULL },
1663         { "add_reference", test_evbuffer_add_reference, 0, NULL, NULL },
1664         { "prepend", test_evbuffer_prepend, TT_FORK, NULL, NULL },
1665         { "peek", test_evbuffer_peek, 0, NULL, NULL },
1666         { "freeze_start", test_evbuffer_freeze, 0, &nil_setup, (void*)"start" },
1667         { "freeze_end", test_evbuffer_freeze, 0, &nil_setup, (void*)"end" },
1668         /* TODO: need a temp file implementation for Windows */
1669         { "add_file_sendfile", test_evbuffer_add_file, TT_FORK, &nil_setup,
1670           (void*)"sendfile" },
1671         { "add_file_mmap", test_evbuffer_add_file, TT_FORK, &nil_setup,
1672           (void*)"mmap" },
1673         { "add_file_linear", test_evbuffer_add_file, TT_FORK, &nil_setup,
1674           (void*)"linear" },
1675 
1676         END_OF_TESTCASES
1677 };

/* [<][>][^][v][top][bottom][index][help] */