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 */
89static char	temp_dir[PATH_MAX];
90
91static void __unused
92atexit_temp_dir(void)
93{
94
95	rmdir(temp_dir);
96}
97
98static void
99makefifo(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
106static void
107cleanfifo2(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
117static void
118cleanfifo3(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 */
130static int
131openfifo(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 */
154static int
155openfifo_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
167static int
168set_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
188static int
189set_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 */
213static int
214drain_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 */
241static void
242test_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
296static volatile int alarm_fired;
297/*
298 * Non-destructive SIGALRM handler.
299 */
300static void
301sigalarm(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 */
312static int __unused
313timed_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 */
352static int
353timed_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 */
400static void
401test_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 */
469static void
470test_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 */
535static void
536test_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 */
599static void
600test_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 */
657static void
658test_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 */
724static void
725test_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 */
795static void
796test_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
861static int
862poll_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
881static int
882select_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 */
911static int
912kqueue_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
950static int
951kqueue_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
982static int
983fionread_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
1007static int
1008assert_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 */
1066static void
1067test_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
1120static void
1121test_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 */
1212static void
1213test_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 */
1297static void
1298test_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
1371int
1372main(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