This source file includes following definitions.
- _evbuffer_validate
- evbuffer_get_waste
- test_evbuffer
- no_cleanup
- test_evbuffer_remove_buffer_with_empty
- test_evbuffer_reserve2
- test_evbuffer_reserve_many
- test_evbuffer_expand
- reference_cb
- test_evbuffer_reference
- test_evbuffer_add_file
- failing_malloc
- test_evbuffer_readln
- test_evbuffer_search_eol
- test_evbuffer_iterative
- test_evbuffer_find
- test_evbuffer_ptr_set
- test_evbuffer_search
- log_change_callback
- self_draining_callback
- test_evbuffer_callbacks
- ref_done_cb
- test_evbuffer_add_reference
- test_evbuffer_prepend
- test_evbuffer_peek
- test_evbuffer_freeze
- setup_passthrough
- cleanup_passthrough
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 
  20 
  21 
  22 
  23 
  24 
  25 
  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 
  65 
  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         
 131         while (chain && chain->off==0) {
 132                 ++n;
 133                 a += chain->buffer_len;
 134                 chain = chain->next;
 135         }
 136         
 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         
 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         
 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         
 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         
 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     
 303     
 304     evbuffer_add_reference(src, buf, sizeof(buf), no_cleanup, NULL);
 305     evbuffer_add_reference(src, buf, sizeof(buf), no_cleanup, NULL);
 306     
 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     
 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         
 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         
 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         
 350 
 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         
 363 
 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         
 379 
 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         
 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         
 424 
 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         
 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         
 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         
 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         
 479 
 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         
 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         
 518 
 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         
 527 
 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         
 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         
 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         
 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         
 659         evbuffer_set_flags(src, EVBUFFER_FLAG_DRAINS_TO_FD);
 660 
 661 #if defined(_EVENT_HAVE_SENDFILE) && defined(__sun__) && defined(__svr4__)
 662         
 663 
 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         
 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         
 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         
 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         
 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         
 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         
 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         
 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         
 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                         
 997 
 998 
 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         
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 
1050 
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         
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         
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         
1132         evbuffer_add_printf(tmp, "hello");  
1133         evbuffer_add_buffer(buf, tmp);
1134         evbuffer_add_printf(tmp, "foo");    
1135         evbuffer_add_buffer(buf, tmp);
1136         evbuffer_add_printf(tmp, "cat");    
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         
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         
1163         
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         
1218 
1219 
1220         
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); 
1225         evbuffer_validate(buf);
1226         evbuffer_prepend(buf, "Hello", 5);
1227         evbuffer_cb_set_flags(buf, cb2, EVBUFFER_CB_ENABLED);
1228         evbuffer_add_reference(buf, "Goodbye", 7, NULL, NULL); 
1229         evbuffer_remove_cb_entry(buf, cb1);
1230         evbuffer_validate(buf);
1231         evbuffer_drain(buf, evbuffer_get_length(buf)); ;
1232         tt_assert(-1 == evbuffer_remove_cb(buf, log_change_callback, NULL));
1233         evbuffer_add(buf, "X", 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         
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         
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); 
1265         evbuffer_validate(buf);
1266         evbuffer_cb_suspend(buf,cb1);
1267         evbuffer_add(buf,"more",4); 
1268         evbuffer_cb_unsuspend(buf,cb2);
1269         evbuffer_drain(buf, 4); 
1270         evbuffer_cb_unsuspend(buf,cb1);
1271         evbuffer_drain(buf, evbuffer_get_length(buf)); 
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                           
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         
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         
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         
1331         evbuffer_drain(buf1, 7); 
1332         evbuffer_drain(buf1, len1-11-1); 
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         
1343         evbuffer_drain(buf1, 6); 
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         
1359 
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 
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         
1388         evbuffer_prepend(buf1, "This string has 29 characters", 29);
1389         evbuffer_validate(buf1);
1390 
1391         
1392         evbuffer_prepend(buf1, "Short.", 6);
1393         evbuffer_validate(buf1);
1394 
1395         
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         
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         
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         
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         
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         
1456         i = evbuffer_peek(buf, -1, NULL, NULL, 0);
1457         tt_int_op(i, ==, 16);
1458 
1459         
1460         i = evbuffer_peek(buf, -1, NULL, v, 20);
1461         tt_int_op(i, ==, 16); 
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         
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         
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         
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         
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         
1496         memset(v, 0, sizeof(v));
1497         i = evbuffer_peek(buf, 65536, NULL, v, 20);
1498         tt_int_op(i, ==, 16); 
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         
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         
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"); 
1523 
1524         
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"); 
1531 
1532 end:
1533         if (buf)
1534                 evbuffer_free(buf);
1535         if (tmp_buf)
1536                 evbuffer_free(tmp_buf);
1537 }
1538 
1539 
1540 
1541 
1542 
1543 
1544 
1545 
1546 static void
1547 test_evbuffer_freeze(void *ptr)
1548 {
1549         struct evbuffer *buf = NULL, *tmp_buf=NULL;
1550         const char string[] = 
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); 
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         
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         
1600 
1601         if (!start)
1602                 tt_int_op(orig_length, ==, evbuffer_get_length(buf));
1603 
1604         orig_length = evbuffer_get_length(buf);
1605 
1606         
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         
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         
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 };