xref: /freebsd/tests/sys/fifo/fifo_io.c (revision b3e7694832e81d7a904a10f525f8797b753bf0d3)
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
atexit_temp_dir(void)92  atexit_temp_dir(void)
93  {
94  
95  	rmdir(temp_dir);
96  }
97  
98  static void
makefifo(const char * fifoname,const char * testname)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
cleanfifo2(const char * fifoname,int fd1,int fd2)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
cleanfifo3(const char * fifoname,int fd1,int fd2,int fd3)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
openfifo(const char * fifoname,int * reader_fdp,int * writer_fdp)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
openfifo_rw(const char * fifoname,int * fdp)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
set_nonblocking(int fd,const char * testname)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
set_blocking(int fd,const char * testname)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
drain_fd(int fd,const char * testname)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
test_simpleio(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
sigalarm(int signum __unused)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
timed_write(int fd,void * data,size_t len,ssize_t * written_lenp,int timeout,int * timedoutp,const char * testname)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
timed_read(int fd,void * data,size_t len,ssize_t * read_lenp,int timeout,int * timedoutp,const char * testname)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
test_blocking_read_empty(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
test_blocking_one_byte(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
test_nonblocking_one_byte(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
test_blocking_partial_write(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
test_nonblocking_partial_write(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
test_coalesce_big_read(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
test_coalesce_big_write(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
poll_status(int fd,int * readable,int * writable,int * exception,const char * testname)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
select_status(int fd,int * readable,int * writable,int * exception,const char * testname)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
kqueue_setup(int kqueue_fd,int fd,const char * testname)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
kqueue_status(int kqueue_fd,int fd,int * readable,int * writable,int * exception,const char * testname)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
fionread_status(int fd,int * readable,const char * testname)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
assert_status(int fd,int kqueue_fd,int assert_readable,int assert_writable,int assert_exception,const char * testname,const char * conditionname,const char * fdname)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
test_events_outofbox(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
test_events_write_read_byte(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
test_events_partial_write(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
test_events_rdwr(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
main(void)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