--- rinetd.c.orig Mon Apr 14 22:19:23 2003 +++ rinetd.c Tue Oct 4 07:25:42 2005 @@ -12,6 +12,7 @@ #include #include #include +#include #define INVALID_SOCKET (-1) #include #endif /* WIN32 */ @@ -94,6 +95,7 @@ #include "match.h" SOCKET *seFds = 0; +static int first_set = 0; /* In network order, for network purposes */ struct in_addr *seLocalAddrs = 0; unsigned short *seLocalPorts = 0; @@ -750,15 +752,82 @@ void openLocalFd(int se, int i); int getAddress(char *host, struct in_addr *iaddr); +inline void poll_init_fds(struct pollfd *pfds, int size) { + int i; + + memset(pfds, 0, sizeof(struct pollfd) * size); + first_set = 1; + for(i = 0; i < size; i++) + pfds[i].fd = -1; +} + +inline int poll_set_fd(struct pollfd *pfds, int size, int count, + int fd, short int ev) { +#ifdef _NEW_POLL_SET_FD + if(first_set) { + pfds[count].fd = fd; + pfds[count].events |= ev; + first_set = 0; + return 0; + } + if(pfds[count].fd != fd && !first_set) { + count++; + } + + pfds[count].fd = fd; + pfds[count].events |= ev; + + return count; +#else + int i; + + for(i = 0; i < size; i++) { + if(pfds[i].fd == -1) { + pfds[i].fd = fd; + pfds[i].events |= ev; + count++; + break; + } + if(pfds[i].fd == fd) { + pfds[i].events |= ev; + break; + } + } + + return count; +#endif +} + +int poll_fd_isset(struct pollfd *pfds, int nfds, int fd, short event) { + int i; + + for(i = 0; i < nfds; i++) { + if(pfds[i].fd == fd) + return pfds[i].revents & event; + } + + return 0; +} + void selectPass(void) { int i; - fd_set readfds, writefds; - FD_ZERO(&readfds); - FD_ZERO(&writefds); + int nfds = 0; + int total = 0; + static struct pollfd *pfds = NULL; + /* Server sockets */ + total = seTotal + (coTotal * 2); + + if(!pfds) { + pfds = malloc(sizeof(struct pollfd) * total); + } + + poll_init_fds(pfds, total); + for (i = 0; (i < seTotal); i++) { if (seFds[i] != INVALID_SOCKET) { - FD_SET(seFds[i], &readfds); + //FD_SET(seFds[i], &readfds) + nfds = poll_set_fd(pfds, total, nfds, seFds[i], POLLIN); } } /* Connection sockets */ @@ -768,35 +837,47 @@ } if (coClosing[i]) { if (!reClosed[i]) { - FD_SET(reFds[i], &writefds); - } - if (!loClosed[i]) { - FD_SET(loFds[i], &writefds); + //FD_SET(reFds[i], &writefds); + nfds = poll_set_fd(pfds, total, nfds, + reFds[i], POLLOUT); } } /* Get more input if we have room for it */ if ((!reClosed[i]) && (coInputRPos[i] < bufferSpace)) { - FD_SET(reFds[i], &readfds); + //FD_SET(reFds[i], &readfds); + nfds = poll_set_fd(pfds, total, nfds, reFds[i], POLLIN); } /* Send more output if we have any */ if ((!reClosed[i]) && (coOutputWPos[i] < coOutputRPos[i])) { - FD_SET(reFds[i], &writefds); + //FD_SET(reFds[i], &writefds); + nfds = poll_set_fd(pfds, total, nfds, reFds[i], POLLOUT); } + if (coClosing[i]) { + if (!loClosed[i]) { + //FD_SET(loFds[i], &writefds); + nfds = poll_set_fd(pfds, total, nfds, + loFds[i], POLLOUT); + } + } /* Accept more output from the local server if there's room */ if ((!loClosed[i]) && (coOutputRPos[i] < bufferSpace)) { - FD_SET(loFds[i], &readfds); + //FD_SET(loFds[i], &readfds); + nfds = poll_set_fd(pfds, total, nfds, loFds[i], POLLIN); } /* Send more input to the local server if we have any */ if ((!loClosed[i]) && (coInputWPos[i] < coInputRPos[i])) { - FD_SET(loFds[i], &writefds); + //FD_SET(loFds[i], &writefds); + nfds = poll_set_fd(pfds, total, nfds, loFds[i], POLLOUT); } } - select(maxfd + 1, &readfds, &writefds, 0, 0); + //select(maxfd + 1, &readfds, &writefds, 0, 0); + poll(pfds, nfds + 1, -1); for (i = 0; (i < seTotal); i++) { if (seFds[i] != -1) { - if (FD_ISSET(seFds[i], &readfds)) { + //if (FD_ISSET(seFds[i], &readfds)) { + if (poll_fd_isset(pfds, nfds, seFds[i], POLLIN)) { handleAccept(i); } } @@ -806,22 +887,26 @@ continue; } if (!reClosed[i]) { - if (FD_ISSET(reFds[i], &readfds)) { + //if (FD_ISSET(reFds[i], &readfds)) { + if (poll_fd_isset(pfds, nfds, reFds[i], POLLIN)) { handleRemoteRead(i); } } if (!reClosed[i]) { - if (FD_ISSET(reFds[i], &writefds)) { + //if (FD_ISSET(reFds[i], &writefds)) { + if (poll_fd_isset(pfds, nfds, reFds[i], POLLOUT)) { handleRemoteWrite(i); } } if (!loClosed[i]) { - if (FD_ISSET(loFds[i], &readfds)) { + //if (FD_ISSET(loFds[i], &readfds)) { + if (poll_fd_isset(pfds, nfds, loFds[i], POLLIN)) { handleLocalRead(i); } } if (!loClosed[i]) { - if (FD_ISSET(loFds[i], &writefds)) { + //if (FD_ISSET(loFds[i], &writefds)) { + if (poll_fd_isset(pfds, nfds, loFds[i], POLLOUT)) { handleLocalWrite(i); } }