+ FD_SET(s, &ibits);
+ /*
+ * If we need a dynamic update that was held off,
+ * needupdate will be set, and nextbcast is the time
+ * by which we want select to return. Compute time
+ * until dynamic update should be sent, and select only
+ * until then. If we have already passed nextbcast,
+ * just poll.
+ */
+ if (needupdate) {
+ waittime = nextbcast;
+ timevalsub(&waittime, &now);
+ if (waittime.tv_sec < 0) {
+ waittime.tv_sec = 0;
+ waittime.tv_usec = 0;
+ }
+ if (traceactions)
+ fprintf(ftrace,
+ "select until dynamic update %d/%d sec/usec\n",
+ waittime.tv_sec, waittime.tv_usec);
+ tvp = &waittime;
+ } else
+ tvp = (struct timeval *)NULL;
+ n = select(nfd, &ibits, 0, 0, tvp);
+ if (n <= 0) {
+ /*
+ * Need delayed dynamic update if select returned
+ * nothing and we timed out. Otherwise, ignore
+ * errors (e.g. EINTR).
+ */
+ if (n < 0) {
+ if (errno == EINTR)
+ continue;
+ syslog(LOG_ERR, "select: %m");
+ }
+ omask = sigblock(sigmask(SIGALRM));
+ if (n == 0 && needupdate) {
+ if (traceactions)
+ fprintf(ftrace,
+ "send delayed dynamic update\n");
+ (void) gettimeofday(&now,
+ (struct timezone *)NULL);
+ toall(supply, RTS_CHANGED,
+ (struct interface *)NULL);
+ lastbcast = now;
+ needupdate = 0;
+ nextbcast.tv_sec = 0;
+ }
+ sigsetmask(omask);