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