netrate/accept_connect: Switch to err(3)
[dragonfly.git] / tools / tools / netrate / accept_connect / connect_client / connect_client.c
1 #include <sys/types.h>
2 #include <sys/mman.h>
3 #include <sys/socket.h>
4 #include <sys/sysctl.h>
5 #include <sys/time.h>
6 #include <sys/wait.h>
7
8 #include <arpa/inet.h>
9 #include <netinet/in.h>
10
11 #include <err.h>
12 #include <signal.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <unistd.h>
17
18 static void     mainloop(const struct sockaddr_in *, long, u_long *);
19
20 static int      global_stopped;
21
22 static void
23 usage(const char *cmd)
24 {
25         fprintf(stderr, "%s -4 inet4 -p port "
26             "[-i n_instance] [-l duration]\n", cmd);
27         exit(1);
28 }
29
30 int
31 main(int argc, char *argv[])
32 {
33         struct sockaddr_in in;
34         int opt, ninst, i;
35         long dur;
36         u_long *result, sum;
37         size_t prm_len;
38
39         prm_len = sizeof(ninst);
40         if (sysctlbyname("hw.ncpu", &ninst, &prm_len, NULL, 0) != 0)
41                 err(2, "sysctl hw.ncpu failed");
42
43         memset(&in, 0, sizeof(in));
44         in.sin_family = AF_INET;
45
46         dur = 10;
47
48         while ((opt = getopt(argc, argv, "4:p:i:l:")) != -1) {
49                 switch (opt) {
50                 case '4':
51                         if (inet_pton(AF_INET, optarg, &in.sin_addr) <= 0) {
52                                 fprintf(stderr, "invalid inet address %s\n",
53                                     optarg);
54                                 usage(argv[0]);
55                         }
56                         break;
57
58                 case 'p':
59                         in.sin_port = htons(atoi(optarg));
60                         break;
61
62                 case 'i':
63                         ninst = atoi(optarg);
64                         break;
65
66                 case 'l':
67                         dur = strtol(optarg, NULL, 10);
68                         break;
69
70                 default:
71                         usage(argv[0]);
72                 }
73         }
74
75         if (ninst < 1 || dur < 1 ||
76             in.sin_port == 0 || in.sin_addr.s_addr == INADDR_ANY)
77                 usage(argv[0]);
78
79         result = mmap(NULL, ninst * sizeof(u_long), PROT_READ | PROT_WRITE,
80             MAP_ANON | MAP_SHARED, -1, 0);
81         if (result == MAP_FAILED)
82                 err(1, "mmap failed");
83         memset(result, 0, ninst * sizeof(u_long));
84
85         for (i = 0; i < ninst; ++i) {
86                 pid_t pid;
87
88                 pid = fork();
89                 if (pid == 0) {
90                         mainloop(&in, dur, &result[i]);
91                         exit(0);
92                 } else if (pid < 0) {
93                         err(1, "fork failed");
94                 }
95         }
96
97         for (i = 0; i < ninst; ++i) {
98                 pid_t pid;
99
100                 pid = waitpid(-1, NULL, 0);
101                 if (pid < 0)
102                         err(1, "waitpid failed");
103         }
104
105         sum = 0;
106         for (i = 0; i < ninst; ++i)
107                 sum += result[i];
108         printf("%.2f\n", (double)sum / (double)dur);
109
110         exit(0);
111 }
112
113 static void
114 signal_handler(int signum __unused)
115 {
116         global_stopped = 1;
117 }
118
119 static void
120 mainloop(const struct sockaddr_in *in, long dur, u_long *res)
121 {
122         struct itimerval it;
123         u_long count = 0;
124
125         if (signal(SIGALRM, signal_handler) == SIG_ERR)
126                 err(1, "signal failed");
127
128         it.it_interval.tv_sec = 0;
129         it.it_interval.tv_usec = 0;
130         it.it_value.tv_sec = dur;
131         it.it_value.tv_usec = 0;
132
133         if (setitimer(ITIMER_REAL, &it, NULL) < 0)
134                 err(1, "setitimer failed");
135
136         while (!global_stopped) {
137                 int s;
138
139                 s = socket(AF_INET, SOCK_STREAM, 0);
140                 if (s < 0)
141                         continue;
142
143                 if (connect(s,
144                     (const struct sockaddr *)in, sizeof(*in)) == 0)
145                         ++count;
146                 close(s);
147         }
148         *res = count;
149 }