4 #include <sys/socket.h>
5 #include <sys/sysctl.h>
9 #include <netinet/in.h>
19 static void mainloop(int, const struct sockaddr_in *);
22 usage(const char *cmd)
24 fprintf(stderr, "%s -p port [-i n_instance] [-r]\n", cmd);
29 create_socket(const struct sockaddr_in *in, int reuseport)
33 serv_s = socket(AF_INET, SOCK_STREAM, 0);
35 fprintf(stderr, "socket failed: %d\n", errno);
41 if (setsockopt(serv_s, SOL_SOCKET, SO_REUSEADDR,
42 &on, sizeof(on)) < 0) {
43 fprintf(stderr, "setsockopt(REUSEADDR) failed: %d\n",
48 if (setsockopt(serv_s, SOL_SOCKET, SO_REUSEPORT,
49 &on, sizeof(on)) < 0) {
50 fprintf(stderr, "setsockopt(REUSEPORT) failed: %d\n",
57 if (ioctl(serv_s, FIONBIO, &on, sizeof(on)) < 0) {
58 fprintf(stderr, "ioctl(FIONBIO) failed: %d\n", errno);
62 if (bind(serv_s, (const struct sockaddr *)in, sizeof(*in)) < 0) {
63 fprintf(stderr, "bind failed: %d\n", errno);
67 if (listen(serv_s, -1) < 0) {
68 fprintf(stderr, "listen failed: %d\n", errno);
75 main(int argc, char *argv[])
77 struct sockaddr_in in;
78 int opt, ninst, serv_s, i, reuseport;
81 prm_len = sizeof(ninst);
82 if (sysctlbyname("hw.ncpu", &ninst, &prm_len, NULL, 0) != 0) {
83 fprintf(stderr, "sysctl hw.ncpu failed: %d\n", errno);
87 memset(&in, 0, sizeof(in));
88 in.sin_family = AF_INET;
89 in.sin_addr.s_addr = INADDR_ANY;
93 while ((opt = getopt(argc, argv, "p:i:r")) != -1) {
96 in.sin_port = htons(atoi(optarg));
100 ninst = atoi(optarg);
112 if (ninst < 1 || in.sin_port == 0)
117 serv_s = create_socket(&in, 0);
119 for (i = 1; i < ninst; ++i) {
124 mainloop(serv_s, &in);
126 } else if (pid < 0) {
127 fprintf(stderr, "fork failed: %d\n", errno);
131 mainloop(serv_s, &in);
136 mainloop(int serv_s, const struct sockaddr_in *in)
138 struct kevent change_evt0[EVENT_MAX];
142 serv_s = create_socket(in, 1);
146 fprintf(stderr, "kqueue failed: %d\n", errno);
150 EV_SET(&change_evt0[0], serv_s, EVFILT_READ, EV_ADD, 0, 0, NULL);
154 const struct kevent *change_evt = NULL;
155 struct kevent evt[EVENT_MAX];
159 change_evt = change_evt0;
161 nevt = kevent(kq, change_evt, nchange, evt, EVENT_MAX, NULL);
163 fprintf(stderr, "kevent failed: %d\n", errno);
168 for (i = 0; i < nevt; ++i) {
169 if (evt[i].ident == (u_int)serv_s) {
170 while (nchange < EVENT_MAX) {
173 s = accept(serv_s, NULL, NULL);
176 EV_SET(&change_evt0[nchange], s,
177 EVFILT_READ, EV_ADD, 0, 0, NULL);