1*73610d44SSepherosa Ziehau #include <sys/types.h>
2*73610d44SSepherosa Ziehau #include <sys/socket.h>
3*73610d44SSepherosa Ziehau #include <sys/time.h>
4*73610d44SSepherosa Ziehau 
5*73610d44SSepherosa Ziehau #include <arpa/inet.h>
6*73610d44SSepherosa Ziehau #include <netinet/in.h>
7*73610d44SSepherosa Ziehau 
8*73610d44SSepherosa Ziehau #include <err.h>
9*73610d44SSepherosa Ziehau #include <errno.h>
10*73610d44SSepherosa Ziehau #include <signal.h>
11*73610d44SSepherosa Ziehau #include <stdio.h>
12*73610d44SSepherosa Ziehau #include <stdlib.h>
13*73610d44SSepherosa Ziehau #include <string.h>
14*73610d44SSepherosa Ziehau #include <unistd.h>
15*73610d44SSepherosa Ziehau 
16*73610d44SSepherosa Ziehau #define READ_BLOCK_TIME		5	/* unit: sec */
17*73610d44SSepherosa Ziehau 
18*73610d44SSepherosa Ziehau static void
sig_alarm(int sig __unused)19*73610d44SSepherosa Ziehau sig_alarm(int sig __unused)
20*73610d44SSepherosa Ziehau {
21*73610d44SSepherosa Ziehau #define PANIC_STRING	"read blocks\n"
22*73610d44SSepherosa Ziehau 
23*73610d44SSepherosa Ziehau 	write(2, PANIC_STRING, strlen(PANIC_STRING));
24*73610d44SSepherosa Ziehau 	abort();
25*73610d44SSepherosa Ziehau }
26*73610d44SSepherosa Ziehau 
27*73610d44SSepherosa Ziehau static void
usage(const char * cmd)28*73610d44SSepherosa Ziehau usage(const char *cmd)
29*73610d44SSepherosa Ziehau {
30*73610d44SSepherosa Ziehau 	fprintf(stderr, "%s -p port\n", cmd);
31*73610d44SSepherosa Ziehau 	exit(1);
32*73610d44SSepherosa Ziehau }
33*73610d44SSepherosa Ziehau 
34*73610d44SSepherosa Ziehau int
main(int argc,char * argv[])35*73610d44SSepherosa Ziehau main(int argc, char *argv[])
36*73610d44SSepherosa Ziehau {
37*73610d44SSepherosa Ziehau 	struct sockaddr_in in;
38*73610d44SSepherosa Ziehau 	struct itimerval it;
39*73610d44SSepherosa Ziehau 	int s, n, error, port, opt;
40*73610d44SSepherosa Ziehau 	char buf;
41*73610d44SSepherosa Ziehau 
42*73610d44SSepherosa Ziehau 	port = 0;
43*73610d44SSepherosa Ziehau 	while ((opt = getopt(argc, argv, "p:")) != -1) {
44*73610d44SSepherosa Ziehau 		char *endptr;
45*73610d44SSepherosa Ziehau 
46*73610d44SSepherosa Ziehau 		switch (opt) {
47*73610d44SSepherosa Ziehau 		case 'p':
48*73610d44SSepherosa Ziehau 			port = strtol(optarg, &endptr, 0);
49*73610d44SSepherosa Ziehau 			if (*endptr != '\0')
50*73610d44SSepherosa Ziehau 				errx(1, "invalid -p argument");
51*73610d44SSepherosa Ziehau 			break;
52*73610d44SSepherosa Ziehau 
53*73610d44SSepherosa Ziehau 		default:
54*73610d44SSepherosa Ziehau 			usage(argv[0]);
55*73610d44SSepherosa Ziehau 		}
56*73610d44SSepherosa Ziehau 	}
57*73610d44SSepherosa Ziehau 	if (port <= 0)
58*73610d44SSepherosa Ziehau 		usage(argv[0]);
59*73610d44SSepherosa Ziehau 
60*73610d44SSepherosa Ziehau 	s = socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK, 0);
61*73610d44SSepherosa Ziehau 	if (s < 0)
62*73610d44SSepherosa Ziehau 		err(1, "socket failed");
63*73610d44SSepherosa Ziehau 
64*73610d44SSepherosa Ziehau 	memset(&in, 0, sizeof(in));
65*73610d44SSepherosa Ziehau 	in.sin_family = AF_INET;
66*73610d44SSepherosa Ziehau 	in.sin_port = htons(port);
67*73610d44SSepherosa Ziehau 	if (bind(s, (const struct sockaddr *)&in, sizeof(in)) < 0)
68*73610d44SSepherosa Ziehau 		err(1, "bind %d failed", port);
69*73610d44SSepherosa Ziehau 
70*73610d44SSepherosa Ziehau 	memset(&it, 0, sizeof(it));
71*73610d44SSepherosa Ziehau 	it.it_value.tv_sec = READ_BLOCK_TIME;
72*73610d44SSepherosa Ziehau 	if (signal(SIGALRM, sig_alarm) == SIG_ERR)
73*73610d44SSepherosa Ziehau 		err(1, "signal failed");
74*73610d44SSepherosa Ziehau 	if (setitimer(ITIMER_REAL, &it, NULL) < 0)
75*73610d44SSepherosa Ziehau 		err(1, "setitimer failed");
76*73610d44SSepherosa Ziehau 
77*73610d44SSepherosa Ziehau 	n = read(s, &buf, 1);
78*73610d44SSepherosa Ziehau 	if (n < 0) {
79*73610d44SSepherosa Ziehau 		error = errno;
80*73610d44SSepherosa Ziehau 		if (error != EAGAIN) {
81*73610d44SSepherosa Ziehau 			warnx("invalid errno %d", error);
82*73610d44SSepherosa Ziehau 			abort();
83*73610d44SSepherosa Ziehau 		}
84*73610d44SSepherosa Ziehau 	} else {
85*73610d44SSepherosa Ziehau 		warnx("read works");
86*73610d44SSepherosa Ziehau 		abort();
87*73610d44SSepherosa Ziehau 	}
88*73610d44SSepherosa Ziehau 
89*73610d44SSepherosa Ziehau 	fprintf(stderr, "passed\n");
90*73610d44SSepherosa Ziehau 	exit(0);
91*73610d44SSepherosa Ziehau }
92