1 /*- 2 * Copyright (c) 2005 Robert N. M. Watson 3 * All rights reserved. 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 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #include <sys/types.h> 28 #include <sys/event.h> 29 #include <sys/ioctl.h> 30 #include <sys/select.h> 31 #include <sys/stat.h> 32 #include <sys/time.h> 33 34 #include <err.h> 35 #include <errno.h> 36 #include <fcntl.h> 37 #include <limits.h> 38 #include <poll.h> 39 #include <signal.h> 40 #include <stdio.h> 41 #include <stdlib.h> 42 #include <string.h> 43 #include <unistd.h> 44 45 /* 46 * Regression test to exercise POSIX fifo I/O. 47 * 48 * We test a number of aspect of behavior, including: 49 * 50 * - If there's no data to read, then for blocking fifos, we block, and for 51 * non-blocking, we return EAGAIN. 52 * 53 * - If we write ten bytes, ten bytes can be read, and they're the same 54 * bytes, in the same order. 55 * 56 * - If we write two batches of five bytes, we can read the same ten bytes in 57 * one read of ten bytes. 58 * 59 * - If we write ten bytes, we can read the same ten bytes in two reads of 60 * five bytes each. 61 * 62 * - If we over-fill a buffer (by writing 512k, which we take to be a large 63 * number above default buffer sizes), we block if there is no reader. 64 * 65 * - That once 512k (ish) is read from the other end, the blocked writer 66 * wakes up. 67 * 68 * - When a fifo is empty, poll, select, kqueue, and fionread report it is 69 * writable but not readable. 70 * 71 * - When a fifo has data in it, poll, select, and kqueue report that it is 72 * writable. 73 * 74 * - XXX: blocked reader semantics? 75 * 76 * - XXX: event behavior on remote close? 77 * 78 * Although behavior of O_RDWR isn't defined for fifos by POSIX, we expect 79 * "reasonable" behavior, and run some additional tests relating to event 80 * management on O_RDWR fifo descriptors. 81 */ 82 83 #define KQUEUE_MAX_EVENT 8 84 85 /* 86 * All activity occurs within a temporary directory created early in the 87 * test. 88 */ 89 static char temp_dir[PATH_MAX]; 90 91 static void __unused 92 atexit_temp_dir(void) 93 { 94 95 rmdir(temp_dir); 96 } 97 98 static void 99 makefifo(const char *fifoname, const char *testname) 100 { 101 102 if (mkfifo(fifoname, 0700) < 0) 103 err(-1, "%s: makefifo: mkfifo: %s", testname, fifoname); 104 } 105 106 static void 107 cleanfifo2(const char *fifoname, int fd1, int fd2) 108 { 109 110 if (fd1 != -1) 111 close(fd1); 112 if (fd2 != -1) 113 close(fd2); 114 (void)unlink(fifoname); 115 } 116 117 static void 118 cleanfifo3(const char *fifoname, int fd1, int fd2, int fd3) 119 { 120 121 if (fd3 != -1) 122 close(fd3); 123 cleanfifo2(fifoname, fd1, fd2); 124 } 125 126 /* 127 * Open two different file descriptors for a fifo: one read, one write. Do 128 * so using non-blocking opens in order to avoid deadlocking the process. 129 */ 130 static int 131 openfifo(const char *fifoname, int *reader_fdp, int *writer_fdp) 132 { 133 int error, fd1, fd2; 134 135 fd1 = open(fifoname, O_RDONLY | O_NONBLOCK); 136 if (fd1 < 0) 137 return (-1); 138 fd2 = open(fifoname, O_WRONLY | O_NONBLOCK); 139 if (fd2 < 0) { 140 error = errno; 141 close(fd1); 142 errno = error; 143 return (-1); 144 } 145 *reader_fdp = fd1; 146 *writer_fdp = fd2; 147 148 return (0); 149 } 150 151 /* 152 * Open one file descriptor for the fifo, supporting both read and write. 153 */ 154 static int 155 openfifo_rw(const char *fifoname, int *fdp) 156 { 157 int fd; 158 159 fd = open(fifoname, O_RDWR); 160 if (fd < 0) 161 return (-1); 162 *fdp = fd; 163 164 return (0); 165 } 166 167 static int 168 set_nonblocking(int fd, const char *testname) 169 { 170 int flags; 171 172 flags = fcntl(fd, F_GETFL); 173 if (flags < 0) { 174 warn("%s: fcntl(fd, F_GETFL)", testname); 175 return(-1); 176 } 177 178 flags |= O_NONBLOCK; 179 180 if (fcntl(fd, F_SETFL, flags) < 0) { 181 warn("%s: fcntl(fd, 0x%x)", testname, flags); 182 return (-1); 183 } 184 185 return (0); 186 } 187 188 static int 189 set_blocking(int fd, const char *testname) 190 { 191 int flags; 192 193 flags = fcntl(fd, F_GETFL); 194 if (flags < 0) { 195 warn("%s: fcntl(fd, F_GETFL)", testname); 196 return(-1); 197 } 198 199 flags &= ~O_NONBLOCK; 200 201 if (fcntl(fd, F_SETFL, flags) < 0) { 202 warn("%s: fcntl(fd, 0x%x)", testname, flags); 203 return (-1); 204 } 205 206 return (0); 207 } 208 209 /* 210 * Drain a file descriptor (fifo) of any readable data. Note: resets the 211 * blocking state. 212 */ 213 static int 214 drain_fd(int fd, const char *testname) 215 { 216 ssize_t len; 217 u_char ch; 218 219 if (set_nonblocking(fd, testname) < 0) 220 return (-1); 221 222 while ((len = read(fd, &ch, sizeof(ch))) > 0); 223 if (len < 0) { 224 switch (errno) { 225 case EAGAIN: 226 return (0); 227 default: 228 warn("%s: drain_fd: read", testname); 229 return (-1); 230 } 231 } 232 warn("%s: drain_fd: read: returned 0 bytes", testname); 233 return (-1); 234 } 235 236 /* 237 * Simple I/O test: write ten integers, and make sure we get back the same 238 * integers in the same order. This assumes a minimum fifo buffer > 10 239 * bytes in order to not block and deadlock. 240 */ 241 static void 242 test_simpleio(void) 243 { 244 int i, reader_fd, writer_fd; 245 u_char buffer[10]; 246 ssize_t len; 247 248 makefifo("testfifo", __func__); 249 if (openfifo("testfifo", &reader_fd, &writer_fd) 250 < 0) { 251 warn("test_simpleio: openfifo: testfifo"); 252 cleanfifo2("testfifo", -1, -1); 253 exit(-1); 254 } 255 256 for (i = 0; i < 10; i++) 257 buffer[i] = i; 258 259 len = write(writer_fd, (char *)buffer, sizeof(buffer)); 260 if (len < 0) { 261 warn("test_simpleio: write"); 262 cleanfifo2("testfifo", reader_fd, writer_fd); 263 exit(-1); 264 } 265 if (len != sizeof(buffer)) { 266 warnx("test_simplio: tried %zu but wrote %zd", sizeof(buffer), 267 len); 268 cleanfifo2("testfifo", reader_fd, writer_fd); 269 exit(-1); 270 } 271 272 len = read(reader_fd, (char *)buffer, sizeof(buffer)); 273 if (len < 0) { 274 warn("test_simpleio: read"); 275 cleanfifo2("testfifo", reader_fd, writer_fd); 276 exit(-1); 277 } 278 if (len != sizeof(buffer)) { 279 warnx("test_simpleio: tried %zu but read %zd", sizeof(buffer), 280 len); 281 cleanfifo2("testfifo", reader_fd, writer_fd); 282 exit(-1); 283 } 284 for (i = 0; i < 10; i++) { 285 if (buffer[i] == i) 286 continue; 287 warnx("test_simpleio: write byte %d as 0x%02x, but read " 288 "0x%02x", i, i, buffer[i]); 289 cleanfifo2("testfifo", reader_fd, writer_fd); 290 exit(-1); 291 } 292 293 cleanfifo2("testfifo", reader_fd, writer_fd); 294 } 295 296 static volatile int alarm_fired; 297 /* 298 * Non-destructive SIGALRM handler. 299 */ 300 static void 301 sigalarm(int signum __unused) 302 { 303 304 alarm_fired = 1; 305 } 306 307 /* 308 * Wrapper function for write, which uses a timer to interrupt any blocking. 309 * Because we can't reliably detect EINTR for blocking I/O, we also track 310 * whether or not our timeout fired. 311 */ 312 static int __unused 313 timed_write(int fd, void *data, size_t len, ssize_t *written_lenp, 314 int timeout, int *timedoutp, const char *testname) 315 { 316 struct sigaction act, oact; 317 ssize_t written_len; 318 int error; 319 320 alarm_fired = 0; 321 bzero(&act, sizeof(oact)); 322 act.sa_handler = sigalarm; 323 if (sigaction(SIGALRM, &act, &oact) < 0) { 324 warn("%s: timed_write: sigaction", testname); 325 return (-1); 326 } 327 alarm(timeout); 328 written_len = write(fd, data, len); 329 error = errno; 330 alarm(0); 331 if (sigaction(SIGALRM, &oact, NULL) < 0) { 332 warn("%s: timed_write: sigaction", testname); 333 return (-1); 334 } 335 if (alarm_fired) 336 *timedoutp = 1; 337 else 338 *timedoutp = 0; 339 340 errno = error; 341 if (written_len < 0) 342 return (-1); 343 *written_lenp = written_len; 344 return (0); 345 } 346 347 /* 348 * Wrapper function for read, which uses a timer to interrupt any blocking. 349 * Because we can't reliably detect EINTR for blocking I/O, we also track 350 * whether or not our timeout fired. 351 */ 352 static int 353 timed_read(int fd, void *data, size_t len, ssize_t *read_lenp, 354 int timeout, int *timedoutp, const char *testname) 355 { 356 struct sigaction act, oact; 357 ssize_t read_len; 358 int error; 359 360 alarm_fired = 0; 361 bzero(&act, sizeof(oact)); 362 act.sa_handler = sigalarm; 363 if (sigaction(SIGALRM, &act, &oact) < 0) { 364 warn("%s: timed_write: sigaction", testname); 365 return (-1); 366 } 367 alarm(timeout); 368 read_len = read(fd, data, len); 369 error = errno; 370 alarm(0); 371 if (sigaction(SIGALRM, &oact, NULL) < 0) { 372 warn("%s: timed_write: sigaction", testname); 373 return (-1); 374 } 375 if (alarm_fired) 376 *timedoutp = 1; 377 else 378 *timedoutp = 0; 379 380 errno = error; 381 if (read_len < 0) 382 return (-1); 383 *read_lenp = read_len; 384 return (0); 385 } 386 387 /* 388 * This test operates on blocking and non-blocking fifo file descriptors, in 389 * order to determine whether they block at good moments or not. By good we 390 * mean: don't block for non-blocking sockets, and do block for blocking 391 * ones, assuming there isn't I/O buffer to satisfy the request. 392 * 393 * We use a timeout of 5 seconds, concluding that in 5 seconds either all I/O 394 * that can take place will, and that if we reach the end of the timeout, 395 * then blocking has occurred. 396 * 397 * We assume that the buffer size on a fifo is <512K, and as such, that 398 * writing that much data without an active reader will result in blocking. 399 */ 400 static void 401 test_blocking_read_empty(void) 402 { 403 int reader_fd, ret, timedout, writer_fd; 404 ssize_t len; 405 u_char ch; 406 407 makefifo("testfifo", __func__); 408 if (openfifo("testfifo", &reader_fd, &writer_fd) 409 < 0) { 410 warn("test_blocking_read_empty: openfifo: testfifo"); 411 cleanfifo2("testfifo", -1, -1); 412 exit(-1); 413 } 414 415 /* 416 * Read one byte from an empty blocking fifo, block as there is no 417 * data. 418 */ 419 if (set_blocking(reader_fd, __func__) < 0) { 420 cleanfifo2("testfifo", reader_fd, writer_fd); 421 exit(-1); 422 } 423 424 ret = timed_read(reader_fd, &ch, sizeof(ch), &len, 5, &timedout, 425 __func__); 426 if (ret != -1) { 427 warnx("test_blocking_read_empty: timed_read: returned " 428 "success"); 429 cleanfifo2("testfifo", reader_fd, writer_fd); 430 exit(-1); 431 } 432 if (errno != EINTR) { 433 warn("test_blocking_read_empty: timed_read"); 434 cleanfifo2("testfifo", reader_fd, writer_fd); 435 exit(-1); 436 } 437 438 /* 439 * Read one byte from an empty non-blocking fifo, return EAGAIN as 440 * there is no data. 441 */ 442 if (set_nonblocking(reader_fd, __func__) < 0) { 443 cleanfifo2("testfifo", reader_fd, writer_fd); 444 exit(-1); 445 } 446 447 ret = timed_read(reader_fd, &ch, sizeof(ch), &len, 5, &timedout, 448 __func__); 449 if (ret != -1) { 450 warnx("test_blocking_read_empty: timed_read: returned " 451 "success"); 452 cleanfifo2("testfifo", reader_fd, writer_fd); 453 exit(-1); 454 } 455 if (errno != EAGAIN) { 456 warn("test_blocking_read_empty: timed_read"); 457 cleanfifo2("testfifo", reader_fd, writer_fd); 458 exit(-1); 459 } 460 461 cleanfifo2("testfifo", reader_fd, writer_fd); 462 } 463 464 /* 465 * Write one byte to an empty fifo, then try to read one byte and make sure 466 * we don't block in either the write or the read. This tests both for 467 * improper blocking in the send and receive code. 468 */ 469 static void 470 test_blocking_one_byte(void) 471 { 472 int reader_fd, ret, timedout, writer_fd; 473 ssize_t len; 474 u_char ch; 475 476 makefifo("testfifo", __func__); 477 if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) { 478 warn("test_blocking: openfifo: testfifo"); 479 cleanfifo2("testfifo", -1, -1); 480 exit(-1); 481 } 482 483 if (set_blocking(writer_fd, __func__) < 0) { 484 cleanfifo2("testfifo", reader_fd, writer_fd); 485 exit(-1); 486 } 487 if (set_blocking(reader_fd, __func__) < 0) { 488 cleanfifo2("testfifo", reader_fd, writer_fd); 489 exit(-1); 490 } 491 492 ch = 0xfe; 493 ret = timed_write(writer_fd, &ch, sizeof(ch), &len, 5, &timedout, 494 __func__); 495 if (ret < 0) { 496 warn("test_blocking_one_byte: timed_write"); 497 cleanfifo2("testfifo", reader_fd, writer_fd); 498 exit(-1); 499 } 500 if (len != sizeof(ch)) { 501 warnx("test_blocking_one_byte: timed_write: tried to write " 502 "%zu, wrote %zd", sizeof(ch), len); 503 cleanfifo2("testfifo", reader_fd, writer_fd); 504 exit(-1); 505 } 506 507 ch = 0xab; 508 ret = timed_read(reader_fd, &ch, sizeof(ch), &len, 5, &timedout, 509 __func__); 510 if (ret < 0) { 511 warn("test_blocking_one_byte: timed_read"); 512 cleanfifo2("testfifo", reader_fd, writer_fd); 513 exit(-1); 514 } 515 if (len != sizeof(ch)) { 516 warnx("test_blocking_one_byte: timed_read: wanted %zu, " 517 "read %zd", sizeof(ch), len); 518 cleanfifo2("testfifo", reader_fd, writer_fd); 519 exit(-1); 520 } 521 if (ch != 0xfe) { 522 warnx("test_blocking_one_byte: timed_read: expected to read " 523 "0x%02x, read 0x%02x", 0xfe, ch); 524 cleanfifo2("testfifo", reader_fd, writer_fd); 525 exit(-1); 526 } 527 528 cleanfifo2("testfifo", reader_fd, writer_fd); 529 } 530 531 /* 532 * Write one byte to an empty fifo, then try to read one byte and make sure 533 * we don't get back EAGAIN. 534 */ 535 static void 536 test_nonblocking_one_byte(void) 537 { 538 int reader_fd, ret, timedout, writer_fd; 539 ssize_t len; 540 u_char ch; 541 542 makefifo("testfifo", __func__); 543 if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) { 544 warn("test_nonblocking: openfifo: testfifo"); 545 cleanfifo2("testfifo", -1, -1); 546 exit(-1); 547 } 548 549 if (set_nonblocking(reader_fd, __func__) < 0) { 550 cleanfifo2("testfifo", reader_fd, writer_fd); 551 exit(-1); 552 } 553 554 ch = 0xfe; 555 ret = timed_write(writer_fd, &ch, sizeof(ch), &len, 5, &timedout, 556 __func__); 557 if (ret < 0) { 558 warn("test_nonblocking_one_byte: timed_write"); 559 cleanfifo2("testfifo", reader_fd, writer_fd); 560 exit(-1); 561 } 562 if (len != sizeof(ch)) { 563 warnx("test_nonblocking_one_byte: timed_write: tried to write " 564 "%zu, wrote %zd", sizeof(ch), len); 565 cleanfifo2("testfifo", reader_fd, writer_fd); 566 exit(-1); 567 } 568 569 ch = 0xab; 570 ret = timed_read(reader_fd, &ch, sizeof(ch), &len, 5, &timedout, 571 __func__); 572 if (ret < 0) { 573 warn("test_nonblocking_one_byte: timed_read"); 574 cleanfifo2("testfifo", reader_fd, writer_fd); 575 exit(-1); 576 } 577 if (len != sizeof(ch)) { 578 warnx("test_nonblocking_one_byte: timed_read: wanted %zu, read " 579 "%zd", sizeof(ch), len); 580 cleanfifo2("testfifo", reader_fd, writer_fd); 581 exit(-1); 582 } 583 if (ch != 0xfe) { 584 warnx("test_nonblocking_one_byte: timed_read: expected to read " 585 "0x%02x, read 0x%02x", 0xfe, ch); 586 cleanfifo2("testfifo", reader_fd, writer_fd); 587 exit(-1); 588 } 589 590 cleanfifo2("testfifo", reader_fd, writer_fd); 591 } 592 593 /* 594 * First of two test cases involving a 512K buffer: write the buffer into a 595 * blocking file descriptor. We'd like to know it blocks, but the closest we 596 * can get is to see if SIGALRM fired during the I/O resulting in a partial 597 * write. 598 */ 599 static void 600 test_blocking_partial_write(void) 601 { 602 int reader_fd, ret, timedout, writer_fd; 603 u_char *buffer; 604 ssize_t len; 605 606 makefifo("testfifo", __func__); 607 if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) { 608 warn("test_blocking_partial_write: openfifo: testfifo"); 609 cleanfifo2("testfifo", -1, -1); 610 exit(-1); 611 } 612 613 if (set_blocking(writer_fd, __func__) < 0) { 614 cleanfifo2("testfifo", reader_fd, writer_fd); 615 exit(-1); 616 } 617 618 buffer = malloc(512*1024); 619 if (buffer == NULL) { 620 warn("test_blocking_partial_write: malloc"); 621 cleanfifo2("testfifo", reader_fd, writer_fd); 622 exit(-1); 623 } 624 bzero(buffer, 512*1024); 625 626 ret = timed_write(writer_fd, buffer, 512*1024, &len, 5, &timedout, 627 __func__); 628 if (ret < 0) { 629 warn("test_blocking_partial_write: timed_write"); 630 free(buffer); 631 cleanfifo2("testfifo", reader_fd, writer_fd); 632 exit(-1); 633 } 634 635 if (!timedout) { 636 warnx("test_blocking_partial_write: timed_write: blocking " 637 "socket didn't time out"); 638 free(buffer); 639 cleanfifo2("testfifo", reader_fd, writer_fd); 640 exit(-1); 641 } 642 643 free(buffer); 644 645 if (drain_fd(reader_fd, __func__) < 0) { 646 cleanfifo2("testfifo", reader_fd, writer_fd); 647 exit(-1); 648 } 649 650 cleanfifo2("testfifo", reader_fd, writer_fd); 651 } 652 653 /* 654 * Write a 512K buffer to an empty fifo using a non-blocking file descriptor, 655 * and make sure it doesn't block. 656 */ 657 static void 658 test_nonblocking_partial_write(void) 659 { 660 int reader_fd, ret, timedout, writer_fd; 661 u_char *buffer; 662 ssize_t len; 663 664 makefifo("testfifo", __func__); 665 if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) { 666 warn("test_blocking_partial_write: openfifo: testfifo"); 667 cleanfifo2("testfifo", -1, -1); 668 exit(-1); 669 } 670 671 if (set_nonblocking(writer_fd, __func__) < 0) { 672 cleanfifo2("testfifo", reader_fd, writer_fd); 673 exit(-1); 674 } 675 676 buffer = malloc(512*1024); 677 if (buffer == NULL) { 678 warn("test_blocking_partial_write: malloc"); 679 cleanfifo2("testfifo", reader_fd, writer_fd); 680 exit(-1); 681 } 682 bzero(buffer, 512*1024); 683 684 ret = timed_write(writer_fd, buffer, 512*1024, &len, 5, &timedout, 685 __func__); 686 if (ret < 0) { 687 warn("test_blocking_partial_write: timed_write"); 688 free(buffer); 689 cleanfifo2("testfifo", reader_fd, writer_fd); 690 exit(-1); 691 } 692 693 if (timedout) { 694 warnx("test_blocking_partial_write: timed_write: " 695 "non-blocking socket timed out"); 696 free(buffer); 697 cleanfifo2("testfifo", reader_fd, writer_fd); 698 exit(-1); 699 } 700 701 if (len == 0 || len >= 512*1024) { 702 warnx("test_blocking_partial_write: timed_write: requested " 703 "%d, sent %zd", 512*1024, len); 704 free(buffer); 705 cleanfifo2("testfifo", reader_fd, writer_fd); 706 exit(-1); 707 } 708 709 free(buffer); 710 711 if (drain_fd(reader_fd, __func__) < 0) { 712 cleanfifo2("testfifo", reader_fd, writer_fd); 713 exit(-1); 714 } 715 716 cleanfifo2("testfifo", reader_fd, writer_fd); 717 } 718 719 /* 720 * test_coalesce_big_read() verifies that data mingles in the fifo across 721 * message boundaries by performing two small writes, then a bigger read 722 * that should return data from both writes. 723 */ 724 static void 725 test_coalesce_big_read(void) 726 { 727 int i, reader_fd, writer_fd; 728 u_char buffer[10]; 729 ssize_t len; 730 731 makefifo("testfifo", __func__); 732 if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) { 733 warn("test_coalesce_big_read: openfifo: testfifo"); 734 cleanfifo2("testfifo", -1, -1); 735 exit(-1); 736 } 737 738 /* Write five, write five, read ten. */ 739 for (i = 0; i < 10; i++) 740 buffer[i] = i; 741 742 len = write(writer_fd, buffer, 5); 743 if (len < 0) { 744 warn("test_coalesce_big_read: write 5"); 745 cleanfifo2("testfifo", reader_fd, writer_fd); 746 exit(-1); 747 } 748 if (len != 5) { 749 warnx("test_coalesce_big_read: write 5 wrote %zd", len); 750 cleanfifo2("testfifo", reader_fd, writer_fd); 751 exit(-1); 752 } 753 754 len = write(writer_fd, buffer + 5, 5); 755 if (len < 0) { 756 warn("test_coalesce_big_read: write 5"); 757 cleanfifo2("testfifo", reader_fd, writer_fd); 758 exit(-1); 759 } 760 if (len != 5) { 761 warnx("test_coalesce_big_read: write 5 wrote %zd", len); 762 cleanfifo2("testfifo", reader_fd, writer_fd); 763 exit(-1); 764 } 765 766 len = read(reader_fd, buffer, 10); 767 if (len < 0) { 768 warn("test_coalesce_big_read: read 10"); 769 cleanfifo2("testfifo", reader_fd, writer_fd); 770 exit(-1); 771 } 772 if (len != 10) { 773 warnx("test_coalesce_big_read: read 10 read %zd", len); 774 cleanfifo2("testfifo", reader_fd, writer_fd); 775 exit(-1); 776 } 777 778 for (i = 0; i < 10; i++) { 779 if (buffer[i] == i) 780 continue; 781 warnx("test_coalesce_big_read: expected to read 0x%02x, " 782 "read 0x%02x", i, buffer[i]); 783 cleanfifo2("testfifo", reader_fd, writer_fd); 784 exit(-1); 785 } 786 787 cleanfifo2("testfifo", -1, -1); 788 } 789 790 /* 791 * test_coalesce_big_write() verifies that data mingles in the fifo across 792 * message boundaries by performing one big write, then two smaller reads 793 * that should return sequential elements of data from the write. 794 */ 795 static void 796 test_coalesce_big_write(void) 797 { 798 int i, reader_fd, writer_fd; 799 u_char buffer[10]; 800 ssize_t len; 801 802 makefifo("testfifo", __func__); 803 if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) { 804 warn("test_coalesce_big_write: openfifo: testfifo"); 805 cleanfifo2("testfifo", -1, -1); 806 exit(-1); 807 } 808 809 /* Write ten, read five, read five. */ 810 for (i = 0; i < 10; i++) 811 buffer[i] = i; 812 813 len = write(writer_fd, buffer, 10); 814 if (len < 0) { 815 warn("test_coalesce_big_write: write 10"); 816 cleanfifo2("testfifo", reader_fd, writer_fd); 817 exit(-1); 818 } 819 if (len != 10) { 820 warnx("test_coalesce_big_write: write 10 wrote %zd", len); 821 cleanfifo2("testfifo", reader_fd, writer_fd); 822 exit(-1); 823 } 824 825 len = read(reader_fd, buffer, 5); 826 if (len < 0) { 827 warn("test_coalesce_big_write: read 5"); 828 cleanfifo2("testfifo", reader_fd, writer_fd); 829 exit(-1); 830 } 831 if (len != 5) { 832 warnx("test_coalesce_big_write: read 5 read %zd", len); 833 cleanfifo2("testfifo", reader_fd, writer_fd); 834 exit(-1); 835 } 836 837 len = read(reader_fd, buffer + 5, 5); 838 if (len < 0) { 839 warn("test_coalesce_big_write: read 5"); 840 cleanfifo2("testfifo", reader_fd, writer_fd); 841 exit(-1); 842 } 843 if (len != 5) { 844 warnx("test_coalesce_big_write: read 5 read %zd", len); 845 cleanfifo2("testfifo", reader_fd, writer_fd); 846 exit(-1); 847 } 848 849 for (i = 0; i < 10; i++) { 850 if (buffer[i] == i) 851 continue; 852 warnx("test_coalesce_big_write: expected to read 0x%02x, " 853 "read 0x%02x", i, buffer[i]); 854 cleanfifo2("testfifo", reader_fd, writer_fd); 855 exit(-1); 856 } 857 858 cleanfifo2("testfifo", -1, -1); 859 } 860 861 static int 862 poll_status(int fd, int *readable, int *writable, int *exception, 863 const char *testname) 864 { 865 struct pollfd fds[1]; 866 867 fds[0].fd = fd; 868 fds[0].events = POLLIN | POLLOUT | POLLERR; 869 fds[0].revents = 0; 870 871 if (poll(fds, 1, 0) < 0) { 872 warn("%s: poll", testname); 873 return (-1); 874 } 875 *readable = (fds[0].revents & POLLIN) ? 1 : 0; 876 *writable = (fds[0].revents & POLLOUT) ? 1 : 0; 877 *exception = (fds[0].revents & POLLERR) ? 1 : 0; 878 return (0); 879 } 880 881 static int 882 select_status(int fd, int *readable, int *writable, int *exception, 883 const char *testname) 884 { 885 struct fd_set readfds, writefds, exceptfds; 886 struct timeval timeout; 887 888 FD_ZERO(&readfds); 889 FD_ZERO(&writefds); 890 FD_ZERO(&exceptfds); 891 FD_SET(fd, &readfds); 892 FD_SET(fd, &writefds); 893 FD_SET(fd, &exceptfds); 894 timeout.tv_sec = 0; 895 timeout.tv_usec = 0; 896 if (select(fd+1, &readfds, &writefds, &exceptfds, &timeout) < 0) { 897 warn("%s: select", testname); 898 return (-1); 899 } 900 *readable = FD_ISSET(fd, &readfds) ? 1 : 0; 901 *writable = FD_ISSET(fd, &writefds) ? 1 : 0; 902 *exception = FD_ISSET(fd, &exceptfds) ? 1 : 0; 903 return (0); 904 } 905 906 /* 907 * Given an existing kqueue, set up read and write event filters for the 908 * passed file descriptor. Typically called once for the read endpoint, and 909 * once for the write endpoint. 910 */ 911 static int 912 kqueue_setup(int kqueue_fd, int fd, const char *testname) 913 { 914 struct kevent kevent_changelist[2]; 915 struct kevent kevent_eventlist[KQUEUE_MAX_EVENT], *kp; 916 struct timespec timeout; 917 int i, ret; 918 919 timeout.tv_sec = 0; 920 timeout.tv_nsec = 0; 921 922 bzero(&kevent_changelist, sizeof(kevent_changelist)); 923 EV_SET(&kevent_changelist[0], fd, EVFILT_READ, EV_ADD, 0, 0, 0); 924 EV_SET(&kevent_changelist[1], fd, EVFILT_WRITE, EV_ADD, 0, 0, 0); 925 926 bzero(&kevent_eventlist, sizeof(kevent_eventlist)); 927 ret = kevent(kqueue_fd, kevent_changelist, 2, kevent_eventlist, 928 KQUEUE_MAX_EVENT, &timeout); 929 if (ret < 0) { 930 warn("%s:%s: kevent initial register", testname, __func__); 931 return (-1); 932 } 933 934 /* 935 * Verify that the events registered alright. 936 */ 937 for (i = 0; i < ret; i++) { 938 kp = &kevent_eventlist[i]; 939 if (kp->flags != EV_ERROR) 940 continue; 941 errno = kp->data; 942 warn("%s:%s: kevent register index %d", testname, __func__, 943 i); 944 return (-1); 945 } 946 947 return (0); 948 } 949 950 static int 951 kqueue_status(int kqueue_fd, int fd, int *readable, int *writable, 952 int *exception, const char *testname) 953 { 954 struct kevent kevent_eventlist[KQUEUE_MAX_EVENT], *kp; 955 struct timespec timeout; 956 int i, ret; 957 958 timeout.tv_sec = 0; 959 timeout.tv_nsec = 0; 960 961 ret = kevent(kqueue_fd, NULL, 0, kevent_eventlist, KQUEUE_MAX_EVENT, 962 &timeout); 963 if (ret < 0) { 964 warn("%s: %s: kevent", testname, __func__); 965 return (-1); 966 } 967 968 *readable = *writable = *exception = 0; 969 for (i = 0; i < ret; i++) { 970 kp = &kevent_eventlist[i]; 971 if (kp->ident != (u_int)fd) 972 continue; 973 if (kp->filter == EVFILT_READ) 974 *readable = 1; 975 if (kp->filter == EVFILT_WRITE) 976 *writable = 1; 977 } 978 979 return (0); 980 } 981 982 static int 983 fionread_status(int fd, int *readable, const char *testname) 984 { 985 int i; 986 987 if (ioctl(fd, FIONREAD, &i) < 0) { 988 warn("%s: ioctl(FIONREAD)", testname); 989 return (-1); 990 } 991 992 if (i > 0) 993 *readable = 1; 994 else 995 *readable = 0; 996 return (0); 997 } 998 999 #define READABLE 1 1000 #define WRITABLE 1 1001 #define EXCEPTION 1 1002 1003 #define NOT_READABLE 0 1004 #define NOT_WRITABLE 0 1005 #define NOT_EXCEPTION 0 1006 1007 static int 1008 assert_status(int fd, int kqueue_fd, int assert_readable, 1009 int assert_writable, int assert_exception, const char *testname, 1010 const char *conditionname, const char *fdname) 1011 { 1012 int readable, writable, exception; 1013 1014 if (poll_status(fd, &readable, &writable, &exception, testname) < 0) 1015 return (-1); 1016 1017 if (readable != assert_readable || writable != assert_writable || 1018 exception != assert_exception) { 1019 warnx("%s: %s polls r:%d, w:%d, e:%d on %s", testname, 1020 fdname, readable, writable, exception, conditionname); 1021 return (-1); 1022 } 1023 1024 if (select_status(fd, &readable, &writable, &exception, testname) < 0) 1025 return (-1); 1026 1027 if (readable != assert_readable || writable != assert_writable || 1028 exception != assert_exception) { 1029 warnx("%s: %s selects r:%d, w:%d, e:%d on %s", testname, 1030 fdname, readable, writable, exception, conditionname); 1031 return (-1); 1032 } 1033 1034 if (kqueue_status(kqueue_fd, fd, &readable, &writable, &exception, 1035 testname) < 0) 1036 return (-1); 1037 1038 if (readable != assert_readable || writable != assert_writable || 1039 exception != assert_exception) { 1040 warnx("%s: %s kevent r:%d, w:%d, e:%d on %s", testname, 1041 fdname, readable, writable, exception, conditionname); 1042 return (-1); 1043 } 1044 1045 if (fionread_status(fd, &readable, __func__) < 0) 1046 return (-1); 1047 1048 if (readable != assert_readable) { 1049 warnx("%s: %s fionread r:%d on %s", testname, fdname, 1050 readable, conditionname); 1051 return (-1); 1052 } 1053 1054 return (0); 1055 } 1056 1057 /* 1058 * test_events() uses poll(), select(), and kevent() to query the status of 1059 * fifo file descriptors and determine whether they match expected state 1060 * based on earlier semantic tests: specifically, whether or not poll/select/ 1061 * kevent will correctly inform on readable/writable state following I/O. 1062 * 1063 * It would be nice to also test status changes as a result of closing of one 1064 * or another fifo endpoint. 1065 */ 1066 static void 1067 test_events_outofbox(void) 1068 { 1069 int kqueue_fd, reader_fd, writer_fd; 1070 1071 makefifo("testfifo", __func__); 1072 if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) { 1073 warn("test_events_outofbox: openfifo: testfifo"); 1074 cleanfifo2("testfifo", -1, -1); 1075 exit(-1); 1076 } 1077 1078 kqueue_fd = kqueue(); 1079 if (kqueue_fd < 0) { 1080 warn("%s: kqueue", __func__); 1081 cleanfifo2("testfifo", reader_fd, writer_fd); 1082 exit(-1); 1083 } 1084 1085 if (kqueue_setup(kqueue_fd, reader_fd, __func__) < 0) { 1086 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd); 1087 exit(-1); 1088 } 1089 1090 if (kqueue_setup(kqueue_fd, writer_fd, __func__) < 0) { 1091 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd); 1092 exit(-1); 1093 } 1094 1095 /* 1096 * Make sure that fresh, out-of-the-box fifo file descriptors have 1097 * good initial states. The reader_fd should have no active state, 1098 * since it will not be readable (no data in pipe), writable (it's 1099 * a read-only descriptor), and there's no reason for error yet. 1100 */ 1101 if (assert_status(reader_fd, kqueue_fd, NOT_READABLE, NOT_WRITABLE, 1102 NOT_EXCEPTION, __func__, "create", "reader_fd") < 0) { 1103 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd); 1104 exit(-1); 1105 } 1106 1107 /* 1108 * Make sure that fresh, out-of-the-box fifo file descriptors have 1109 * good initial states. The writer_fd should be ready to write. 1110 */ 1111 if (assert_status(writer_fd, kqueue_fd, NOT_READABLE, WRITABLE, 1112 NOT_EXCEPTION, __func__, "create", "writer_fd") < 0) { 1113 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd); 1114 exit(-1); 1115 } 1116 1117 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd); 1118 } 1119 1120 static void 1121 test_events_write_read_byte(void) 1122 { 1123 int kqueue_fd, reader_fd, writer_fd; 1124 ssize_t len; 1125 u_char ch; 1126 1127 makefifo("testfifo", __func__); 1128 if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) { 1129 warn("test_events_write_read_byte: openfifo: testfifo"); 1130 cleanfifo2("testfifo", -1, -1); 1131 exit(-1); 1132 } 1133 1134 kqueue_fd = kqueue(); 1135 if (kqueue_fd < 0) { 1136 warn("%s: kqueue", __func__); 1137 cleanfifo2("testfifo", reader_fd, writer_fd); 1138 exit(-1); 1139 } 1140 1141 if (kqueue_setup(kqueue_fd, reader_fd, __func__) < 0) { 1142 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd); 1143 exit(-1); 1144 } 1145 1146 if (kqueue_setup(kqueue_fd, writer_fd, __func__) < 0) { 1147 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd); 1148 exit(-1); 1149 } 1150 1151 /* 1152 * Write a byte to the fifo, and make sure that the read end becomes 1153 * readable, and that the write end remains writable (small write). 1154 */ 1155 ch = 0x00; 1156 len = write(writer_fd, &ch, sizeof(ch)); 1157 if (len < 0) { 1158 warn("%s: write", __func__); 1159 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd); 1160 exit(-1); 1161 } 1162 1163 if (assert_status(reader_fd, kqueue_fd, READABLE, NOT_WRITABLE, 1164 NOT_EXCEPTION, __func__, "write", "reader_fd") < 0) { 1165 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd); 1166 exit(-1); 1167 } 1168 1169 /* 1170 * the writer_fd should remain writable. 1171 */ 1172 if (assert_status(writer_fd, kqueue_fd, NOT_READABLE, WRITABLE, 1173 NOT_EXCEPTION, __func__, "write", "writer_fd") < 0) { 1174 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd); 1175 exit(-1); 1176 } 1177 1178 /* 1179 * Read the byte from the reader_fd, and now confirm that the fifo 1180 * becomes unreadable. 1181 */ 1182 len = read(reader_fd, &ch, sizeof(ch)); 1183 if (len < 0) { 1184 warn("%s: read", __func__); 1185 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd); 1186 exit(-1); 1187 } 1188 1189 if (assert_status(reader_fd, kqueue_fd, NOT_READABLE, NOT_WRITABLE, 1190 NOT_EXCEPTION, __func__, "write+read", "reader_fd") < 0) { 1191 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd); 1192 exit(-1); 1193 } 1194 1195 /* 1196 * The writer_fd should remain writable. 1197 */ 1198 if (assert_status(writer_fd, kqueue_fd, NOT_READABLE, WRITABLE, 1199 NOT_EXCEPTION, __func__, "write+read", "writer_fd") < 0) { 1200 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd); 1201 exit(-1); 1202 } 1203 1204 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd); 1205 } 1206 1207 /* 1208 * Write a 512k buffer to the fifo in non-blocking mode, and make sure that 1209 * the write end becomes un-writable as a result of a partial write that 1210 * fills the fifo buffer. 1211 */ 1212 static void 1213 test_events_partial_write(void) 1214 { 1215 int kqueue_fd, reader_fd, writer_fd; 1216 u_char *buffer; 1217 ssize_t len; 1218 1219 makefifo("testfifo", __func__); 1220 if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) { 1221 warn("test_events_partial_write: openfifo: testfifo"); 1222 cleanfifo2("testfifo", -1, -1); 1223 exit(-1); 1224 } 1225 1226 kqueue_fd = kqueue(); 1227 if (kqueue_fd < 0) { 1228 warn("%s: kqueue", __func__); 1229 cleanfifo2("testfifo", reader_fd, writer_fd); 1230 exit(-1); 1231 } 1232 1233 if (kqueue_setup(kqueue_fd, reader_fd, __func__) < 0) { 1234 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd); 1235 exit(-1); 1236 } 1237 1238 if (kqueue_setup(kqueue_fd, writer_fd, __func__) < 0) { 1239 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd); 1240 exit(-1); 1241 } 1242 1243 if (set_nonblocking(writer_fd, "test_events") < 0) { 1244 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd); 1245 exit(-1); 1246 } 1247 1248 buffer = malloc(512*1024); 1249 if (buffer == NULL) { 1250 warn("test_events_partial_write: malloc"); 1251 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd); 1252 exit(-1); 1253 } 1254 bzero(buffer, 512*1024); 1255 1256 len = write(writer_fd, buffer, 512*1024); 1257 if (len < 0) { 1258 warn("test_events_partial_write: write"); 1259 free(buffer); 1260 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd); 1261 exit(-1); 1262 } 1263 1264 free(buffer); 1265 1266 if (assert_status(writer_fd, kqueue_fd, NOT_READABLE, NOT_WRITABLE, 1267 NOT_EXCEPTION, __func__, "big write", "writer_fd") < 0) { 1268 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd); 1269 exit(-1); 1270 } 1271 1272 if (drain_fd(reader_fd, "test_events") < 0) { 1273 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd); 1274 exit(-1); 1275 } 1276 1277 /* 1278 * Test that the writer_fd has been restored to writable state after 1279 * draining. 1280 */ 1281 if (assert_status(writer_fd, kqueue_fd, NOT_READABLE, WRITABLE, 1282 NOT_EXCEPTION, __func__, "big write + drain", "writer_fd") < 0) { 1283 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd); 1284 exit(-1); 1285 } 1286 1287 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd); 1288 } 1289 1290 /* 1291 * We don't comprehensively test O_RDWR file descriptors, but do run a couple 1292 * of event tests to make sure that the fifo implementation doesn't mixed up 1293 * status checks. In particular, at least one past FreeBSD bug exists in 1294 * which the FIONREAD test was performed on the wrong socket implementing the 1295 * fifo, resulting in the fifo never returning readable. 1296 */ 1297 static void 1298 test_events_rdwr(void) 1299 { 1300 int fd, kqueue_fd; 1301 ssize_t len; 1302 char ch; 1303 1304 makefifo("testfifo", __func__); 1305 if (openfifo_rw("testfifo", &fd) < 0) { 1306 warn("%s: openfifo_rw: testfifo", __func__); 1307 cleanfifo2("testfifo", -1, -1); 1308 exit(-1); 1309 } 1310 1311 kqueue_fd = kqueue(); 1312 if (kqueue_fd < 0) { 1313 warn("%s: kqueue", __func__); 1314 cleanfifo2("testifo", fd, -1); 1315 exit(-1); 1316 } 1317 1318 if (kqueue_setup(kqueue_fd, fd, __func__) < 0) { 1319 cleanfifo2("testfifo", fd, kqueue_fd); 1320 exit(-1); 1321 } 1322 1323 /* 1324 * On first creation, the O_RDWR descriptor should be writable but 1325 * not readable. 1326 */ 1327 if (assert_status(fd, kqueue_fd, NOT_READABLE, WRITABLE, 1328 NOT_EXCEPTION, __func__, "create", "fd") < 0) { 1329 cleanfifo2("testfifo", fd, kqueue_fd); 1330 exit(-1); 1331 } 1332 1333 /* 1334 * Write a byte, which should cause the file descriptor to become 1335 * readable and writable. 1336 */ 1337 ch = 0x00; 1338 len = write(fd, &ch, sizeof(ch)); 1339 if (len < 0) { 1340 warn("%s: write", __func__); 1341 cleanfifo2("testfifo", fd, kqueue_fd); 1342 exit(-1); 1343 } 1344 1345 if (assert_status(fd, kqueue_fd, READABLE, WRITABLE, NOT_EXCEPTION, 1346 __func__, "write", "fd") < 0) { 1347 cleanfifo2("testfifo", fd, kqueue_fd); 1348 exit(-1); 1349 } 1350 1351 /* 1352 * Read a byte, which should cause the file descriptor to return to 1353 * simply being writable. 1354 */ 1355 len = read(fd, &ch, sizeof(ch)); 1356 if (len < 0) { 1357 warn("%s: read", __func__); 1358 cleanfifo2("testfifo", fd, kqueue_fd); 1359 exit(-1); 1360 } 1361 1362 if (assert_status(fd, kqueue_fd, NOT_READABLE, WRITABLE, 1363 NOT_EXCEPTION, __func__, "write+read", "fd") < 0) { 1364 cleanfifo2("testfifo", fd, kqueue_fd); 1365 exit(-1); 1366 } 1367 1368 cleanfifo2("testfifo", fd, kqueue_fd); 1369 } 1370 1371 int 1372 main(void) 1373 { 1374 1375 strcpy(temp_dir, "fifo_io.XXXXXXXXXXX"); 1376 if (mkdtemp(temp_dir) == NULL) 1377 err(-1, "mkdtemp"); 1378 atexit(atexit_temp_dir); 1379 1380 if (chdir(temp_dir) < 0) 1381 err(-1, "chdir %s", temp_dir); 1382 1383 test_simpleio(); 1384 test_blocking_read_empty(); 1385 test_blocking_one_byte(); 1386 test_nonblocking_one_byte(); 1387 test_blocking_partial_write(); 1388 test_nonblocking_partial_write(); 1389 test_coalesce_big_read(); 1390 test_coalesce_big_write(); 1391 test_events_outofbox(); 1392 test_events_write_read_byte(); 1393 test_events_partial_write(); 1394 test_events_rdwr(); 1395 1396 return (0); 1397 } 1398