xref: /openbsd/regress/sys/kern/pipe/pipe.c (revision 3cab2bb3)
1 /*	$OpenBSD: pipe.c,v 1.4 2020/06/29 18:25:37 anton Exp $	*/
2 
3 /*
4  * Copyright (c) 2019 Anton Lindqvist <anton@openbsd.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/wait.h>
20 
21 #include <err.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <unistd.h>
26 
27 #include "pipe.h"
28 
29 static void sighandler(int);
30 static __dead void usage(void);
31 
32 sig_atomic_t gotsigpipe = 0;
33 int infinity = 0;
34 int verbose = 0;
35 
36 int
37 main(int argc, char *argv[])
38 {
39 	struct {
40 		const char *t_name;
41 		int (*t_fn)(void);
42 	} tests[] = {
43 		{ "close-race",				test_close_race },
44 		{ "kqueue-read",			test_kqueue_read },
45 		{ "kqueue-read-eof",			test_kqueue_read_eof },
46 		{ "kqueue-write",			test_kqueue_write },
47 		{ "kqueue-write-eof",			test_kqueue_write_eof },
48 		{ "ping-pong",				test_ping_pong },
49 		{ "run-down-write-big",			test_run_down_write_big },
50 		{ "run-down-write-small",		test_run_down_write_small },
51 		{ "thundering-herd-read-signal",	test_thundering_herd_read_signal },
52 		{ "thundering-herd-read-wakeup",	test_thundering_herd_read_wakeup },
53 		{ "thundering-herd-write-signal",	test_thundering_herd_write_signal },
54 		{ "thundering-herd-write-wakeup",	test_thundering_herd_write_wakeup },
55 
56 		{ NULL, NULL },
57 	};
58 	int ch, i;
59 
60 	while ((ch = getopt(argc, argv, "iv")) != -1) {
61 		switch (ch) {
62 		case 'i':
63 			infinity = 1;
64 			break;
65 		case 'v':
66 			verbose = 1;
67 			break;
68 		default:
69 			usage();
70 		}
71 	}
72 	argc -= optind;
73 	argv += optind;
74 	if (argc != 1)
75 		usage();
76 
77 	if (signal(SIGPIPE, sighandler) == SIG_ERR)
78 		err(1, "signal");
79 
80 	for (i = 0; tests[i].t_name != NULL; i++) {
81 		if (strcmp(argv[0], tests[i].t_name))
82 			continue;
83 
84 		return tests[i].t_fn();
85 	}
86 	warnx("%s: no such test", argv[0]);
87 
88 	return 1;
89 }
90 
91 int
92 xwaitpid(pid_t pid)
93 {
94 	int status;
95 
96 	if (waitpid(pid, &status, 0) == -1)
97 		err(1, "waitpid");
98 	if (WIFEXITED(status))
99 		return WEXITSTATUS(status);
100 	if (WIFSIGNALED(status))
101 		return WTERMSIG(status);
102 	return 0;
103 }
104 
105 static void
106 sighandler(int signo)
107 {
108 
109 	gotsigpipe = signo;
110 }
111 
112 static __dead void
113 usage(void)
114 {
115 
116 	fprintf(stderr, "usage: pipe [-iv] test-case\n");
117 	exit(1);
118 }
119