xref: /openbsd/regress/sys/kern/pipe/pipe.c (revision 4b171f7d)
1 /*	$OpenBSD: pipe.c,v 1.5 2021/10/22 05:03:04 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
main(int argc,char * argv[])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 		{ "select-hup",				test_select_hup },
52 		{ "thundering-herd-read-signal",	test_thundering_herd_read_signal },
53 		{ "thundering-herd-read-wakeup",	test_thundering_herd_read_wakeup },
54 		{ "thundering-herd-write-signal",	test_thundering_herd_write_signal },
55 		{ "thundering-herd-write-wakeup",	test_thundering_herd_write_wakeup },
56 
57 		{ NULL, NULL },
58 	};
59 	int ch, i;
60 
61 	while ((ch = getopt(argc, argv, "iv")) != -1) {
62 		switch (ch) {
63 		case 'i':
64 			infinity = 1;
65 			break;
66 		case 'v':
67 			verbose = 1;
68 			break;
69 		default:
70 			usage();
71 		}
72 	}
73 	argc -= optind;
74 	argv += optind;
75 	if (argc != 1)
76 		usage();
77 
78 	if (signal(SIGPIPE, sighandler) == SIG_ERR)
79 		err(1, "signal");
80 
81 	for (i = 0; tests[i].t_name != NULL; i++) {
82 		if (strcmp(argv[0], tests[i].t_name))
83 			continue;
84 
85 		return tests[i].t_fn();
86 	}
87 	warnx("%s: no such test", argv[0]);
88 
89 	return 1;
90 }
91 
92 int
xwaitpid(pid_t pid)93 xwaitpid(pid_t pid)
94 {
95 	int status;
96 
97 	if (waitpid(pid, &status, 0) == -1)
98 		err(1, "waitpid");
99 	if (WIFEXITED(status))
100 		return WEXITSTATUS(status);
101 	if (WIFSIGNALED(status))
102 		return WTERMSIG(status);
103 	return 0;
104 }
105 
106 static void
sighandler(int signo)107 sighandler(int signo)
108 {
109 
110 	gotsigpipe = signo;
111 }
112 
113 static __dead void
usage(void)114 usage(void)
115 {
116 
117 	fprintf(stderr, "usage: pipe [-iv] test-case\n");
118 	exit(1);
119 }
120