2 #include <sys/socket.h>
8 #include <netinet/in.h>
18 #define WRITE_WAIT_TIME 8 /* unit: sec */
19 #define READ_WAIT_MIN 6 /* unit: sec */
22 usage(const char *cmd)
24 fprintf(stderr, "%s -p port\n", cmd);
29 connect_client(int port, int ctrl_s)
31 struct sockaddr_in in;
34 s = socket(AF_INET, SOCK_STREAM, 0);
36 err(1, "client socket failed");
38 memset(&in, 0, sizeof(in));
39 in.sin_family = AF_INET;
40 in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
41 in.sin_port = htons(port);
42 if (connect(s, (const struct sockaddr *)&in, sizeof(in)) < 0)
43 err(1, "connect failed");
45 /* Make sure server side compltes the 3-way handshake */
49 write(ctrl_s, &dummy, sizeof(dummy));
51 sleep(WRITE_WAIT_TIME);
52 write(s, &dummy, sizeof(dummy));
59 main(int argc, char *argv[])
61 struct sockaddr_in in;
62 int serv_s, s, ctrl_s[2];
63 int opt, port, dummy, n, status, panic, ex;
64 struct timespec stime, etime;
71 while ((opt = getopt(argc, argv, "p:")) != -1) {
76 port = strtol(optarg, &endptr, 0);
78 errx(1, "invalid -p");
88 if (socketpair(AF_UNIX, SOCK_DGRAM, 0, ctrl_s) < 0)
89 err(1, "socketpair failed");
91 serv_s = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
93 err(1, "socket failed");
95 memset(&in, 0, sizeof(in));
96 in.sin_family = AF_INET;
97 in.sin_port = htons(port);
98 if (bind(serv_s, (const struct sockaddr *)&in, sizeof(in)) < 0)
99 err(1, "bind failed");
101 if (listen(serv_s, 0) < 0)
102 err(1, "listen failed");
106 err(1, "fork failed");
107 } else if (pid == 0) {
109 connect_client(port, ctrl_s[1]);
113 /* Wait for the connect */
114 read(ctrl_s[0], &dummy, sizeof(dummy));
116 s = accept4(serv_s, NULL, NULL, 0);
118 warn("accept4 failed");
123 clock_gettime(CLOCK_MONOTONIC, &stime);
124 n = read(s, &dummy, sizeof(dummy));
128 } else if (n != sizeof(dummy)) {
129 warnx("read size mismatch");
132 clock_gettime(CLOCK_MONOTONIC, &etime);
134 if (etime.tv_sec - stime.tv_sec < READ_WAIT_MIN) {
135 warnx("invalid wait time %ld", etime.tv_sec - stime.tv_sec);
141 fprintf(stderr, "passed\n");
144 waitpid(pid, &status, 0);