void engine_del_fd(long fd) { long arrayidx = (long) get_fd_internal(fd); /* If it's at the end of the array, just chop it off */ if(arrayidx == last_pfd) { fdfprintf(stderr, "Removing %d[%d] from end of pollfds\n", last_pfd, fd); last_pfd--; return; } /* Otherwise, move the last array member to where the old one was */ fdfprintf(stderr, "Moving pfd %d[%d] to vacated spot %d[%d] -- now %d[%d]\n", last_pfd, poll_fds[last_pfd].fd, arrayidx, fd, last_pfd, fd); memcpy(&poll_fds[arrayidx], &poll_fds[last_pfd], sizeof(struct pollfd)); last_pfd--; set_fd_internal(poll_fds[arrayidx].fd, (void *) arrayidx); }
void add_fd(int fd, int type, void *value) { fdfprintf(stderr, "add_fd: %d %d %x\n", fd, type, (int) value); fd_range_assert(fd); fd_notused_assert(fd); fd_list[fd].type = type; fd_list[fd].value = value; fd_list[fd].flags = 0; engine_add_fd(fd); }
void del_fd(int fd) { fdfprintf(stderr, "del_fd: %d\n", fd); fd_range_assert(fd); fd_used_assert(fd); engine_del_fd(fd); fd_list[fd].type = FDT_NONE; fd_list[fd].value = NULL; fd_list[fd].internal = NULL; }
void unset_fd_flags(int fd, unsigned int flags) { unsigned int oldflags; fd_range_assert(fd); fd_used_assert(fd); oldflags = fd_list[fd].flags; fd_list[fd].flags &= ~(flags); fdfprintf(stderr, "unset_fd_flags: %d %x [%x -> %x]\n", fd, flags, oldflags, fd_list[fd].flags); if(oldflags != fd_list[fd].flags) engine_change_fd_state(fd, fd_list[fd].flags); }
int engine_read_message(time_t delay) { fd_set read_set, write_set; struct timeval wt; int nfds, length, i; unsigned int fdflags; int fdtype; void *fdvalue; aClient *cptr; aListener *lptr; engine_get_fdsets(&read_set, &write_set); wt.tv_sec = delay; wt.tv_usec = 0; nfds = select(MAXCONNECTIONS, &read_set, &write_set, NULL, &wt); if (nfds == -1) { if(((errno == EINTR) || (errno == EAGAIN))) return -1; report_error("select %s:%s", &me); sleep(5); return -1; } else if (nfds == 0) return 0; if(delay) NOW = timeofday = time(NULL); for (i = 0; i < MAXCONNECTIONS; i++) { get_fd_info(i, &fdtype, &fdflags, &fdvalue); cptr = NULL; length = -1; if (nfds) { int rr = FD_ISSET(i, &read_set); int rw = FD_ISSET(i, &write_set); if(rr || rw) nfds--; else continue; fdfprintf(stderr, "fd %d: %s%s\n", i, rr ? "read " : "", rw ? "write" : ""); switch(fdtype) { case FDT_NONE: break; case FDT_AUTH: cptr = (aClient *) fdvalue; if (rr) read_authports(cptr); if (rw && cptr->authfd >= 0) send_authports(cptr); check_client_fd(cptr); break; case FDT_LISTENER: lptr = (aListener *) fdvalue; if(rr) accept_connection(lptr); break; case FDT_RESOLVER: do_dns_async(); break; case FDT_CLIENT: cptr = (aClient *) fdvalue; readwrite_client(cptr, rr, rw); break; case FDT_CALLBACKP: { struct fd_callbackp *fdcb = (struct fd_callbackp *) fdvalue; fdcb->rdf = rr; fdcb->wrf = rw; (*fdcb->callback)(fdcb); } break; default: abort(); /* unknown client type? bail! */ } } else break; /* no more fds? break out of the loop */ } /* end of for() loop for testing selected sockets */ return 0; }
int engine_read_message(time_t delay) { static struct pollfd poll_fdarray[MAXCONNECTIONS]; struct pollfd *pfd; long nfds, nbr_pfds; int length, i; unsigned int fdflags; int fdtype; void *fdvalue; aClient *cptr; aListener *lptr; engine_get_pollfds(&pfd, &nbr_pfds); memcpy(poll_fdarray, pfd, sizeof(struct pollfd) * nbr_pfds); nfds = poll(poll_fdarray, nbr_pfds, delay * 1000); if (nfds == -1) { if(((errno == EINTR) || (errno == EAGAIN))) return -1; report_error("poll %s:%s", &me); sleep(5); return -1; } if(delay) NOW = timeofday = time(NULL); for (pfd = poll_fdarray, i = 0; nfds && (i < nbr_pfds); i++, pfd++) { get_fd_info(pfd->fd, &fdtype, &fdflags, &fdvalue); cptr = NULL; length = -1; if (nfds && pfd->revents) { int rr = pfd->revents & (POLLIN|POLLHUP|POLLERR); int rw = pfd->revents & (POLLOUT); fdfprintf(stderr, "fd %d: %s%s\n", pfd->fd, rr ? "read " : "", rw ? "write" : ""); nfds--; switch(fdtype) { case FDT_NONE: break; case FDT_AUTH: cptr = (aClient *) fdvalue; if (rr) read_authports(cptr); if (rw && cptr->authfd >= 0) send_authports(cptr); check_client_fd(cptr); break; case FDT_LISTENER: lptr = (aListener *) fdvalue; if(rr) accept_connection(lptr); break; case FDT_RESOLVER: do_dns_async(); break; case FDT_CLIENT: cptr = (aClient *) fdvalue; readwrite_client(cptr, rr, rw); break; case FDT_CALLBACKP: { struct fd_callbackp *fdcb = (struct fd_callbackp *) fdvalue; fdcb->rdf = rr; fdcb->wrf = rw; (*fdcb->callback)(fdcb); } break; default: abort(); /* unknown client type? bail! */ } } } /* end of for() loop for testing polled sockets */ return 0; }