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