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