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