void ROKEN_LIB_FUNCTION mini_inetd_addrinfo (struct addrinfo *ai) { int ret; struct addrinfo *a; int n, nalloc, i; int *fds; fd_set orig_read_set, read_set; int max_fd = -1; for (nalloc = 0, a = ai; a != NULL; a = a->ai_next) ++nalloc; fds = malloc (nalloc * sizeof(*fds)); if (fds == NULL) errx (1, "mini_inetd: out of memory"); FD_ZERO(&orig_read_set); for (i = 0, a = ai; a != NULL; a = a->ai_next) { fds[i] = socket (a->ai_family, a->ai_socktype, a->ai_protocol); if (fds[i] < 0) { warn ("socket af = %d", a->ai_family); continue; } socket_set_reuseaddr (fds[i], 1); if (bind (fds[i], a->ai_addr, a->ai_addrlen) < 0) { warn ("bind af = %d", a->ai_family); close(fds[i]); continue; } if (listen (fds[i], SOMAXCONN) < 0) { warn ("listen af = %d", a->ai_family); close(fds[i]); continue; } if (fds[i] >= FD_SETSIZE) errx (1, "fd too large"); FD_SET(fds[i], &orig_read_set); max_fd = max(max_fd, fds[i]); ++i; } if (i == 0) errx (1, "no sockets"); n = i; do { read_set = orig_read_set; ret = select (max_fd + 1, &read_set, NULL, NULL, NULL); if (ret < 0 && errno != EINTR) err (1, "select"); } while (ret <= 0); for (i = 0; i < n; ++i) if (FD_ISSET (fds[i], &read_set)) { accept_it (fds[i]); return; } abort (); }
void mini_inetd_addrinfo (struct addrinfo *ai) { struct addrinfo *a; int n, nalloc, i, ret; int *fds; int on=1; #ifdef HAVE_POLL struct pollfd *set; #else fd_set orig_read_set, read_set; int max_fd = -1; #endif for (nalloc = 0, a = ai; a != NULL; a = a->ai_next) ++nalloc; fds = (int*)malloc (nalloc * sizeof(*fds)); #ifdef HAVE_POLL set = malloc (nalloc * sizeof(*set)); #else FD_ZERO(&orig_read_set); #endif for (i = 0, a = ai; a != NULL; a = a->ai_next) { fds[i] = socket (a->ai_family, a->ai_socktype, a->ai_protocol); if (fds[i] < 0) { continue; } (void) setsockopt(fds[i], SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)); if (bind (fds[i], a->ai_addr, a->ai_addrlen) < 0) { close(fds[i]); continue; } if (listen (fds[i], SOMAXCONN) < 0) { close(fds[i]); continue; } #ifdef HAVE_POLL set[i].fd = fds[i]; set[i].events = POLLIN; #else FD_SET(fds[i], &orig_read_set); max_fd = MAX(max_fd, fds[i]); #endif ++i; } n = i; do { #ifdef HAVE_POLL ret = poll (set, nalloc, INFTIM); #else read_set = orig_read_set; ret = select (max_fd + 1, &read_set, NULL, NULL, NULL); #endif } while (ret <= 0); for (i = 0; i < n; ++i) #ifdef HAVE_POLL if (set[i].revents & POLLIN) #else if (FD_ISSET (fds[i], &read_set)) #endif { accept_it (fds[0]); free (fds); #ifdef HAVE_POLL free (set); #endif return; } abort (); }