From 0dcd34090c532d748281281280140255a045f3e2 Mon Sep 17 00:00:00 2001 From: jkh Date: Sun, 9 Dec 2001 09:53:27 +0000 Subject: [PATCH] Don't assume that the number of fds to select on is known quantity (in this case 16). Use dynamic FD_SETs and calculated high-water marks throughout. There are also too many versions of telnet in the tree. Obtained from: OpenBSD and Apple's Radar database MFC after: 2 days git-svn-id: http://svn0.us-east.freebsd.org/base/head/contrib/telnet@87558 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- telnet/sys_bsd.c | 86 +++++++++++++++++++++++++++++++----------------- 1 file changed, 55 insertions(+), 31 deletions(-) diff --git a/telnet/sys_bsd.c b/telnet/sys_bsd.c index bcb302c..fca026d 100644 --- a/telnet/sys_bsd.c +++ b/telnet/sys_bsd.c @@ -32,6 +32,8 @@ */ #include +#include +#include __FBSDID("$FreeBSD$"); @@ -105,7 +107,8 @@ struct termio old_tc = { 0, 0, 0, 0, {}, 0, 0 }; # endif #endif /* USE_TERMIO */ -static fd_set ibits, obits, xbits; +static fd_set *ibitsp, *obitsp, *xbitsp; +int fdsn; #ifdef SIGINT static SIG_FUNC_RET intr(int); @@ -125,10 +128,6 @@ init_sys(void) { tout = fileno(stdout); tin = fileno(stdin); - FD_ZERO(&ibits); - FD_ZERO(&obits); - FD_ZERO(&xbits); - errno = 0; } @@ -924,24 +923,49 @@ process_rings(int netin, int netout, int netex, int ttyin, int ttyout, int poll) int c; int returnValue = 0; static struct timeval TimeValue = { 0, 0 }; + int maxfd = -1; + int tmp; - if (netout) { - FD_SET(net, &obits); + if ((netout || netin || netex) && net > maxfd) + maxfd = net; + + if (ttyout && tout > maxfd) + maxfd = tout; + if (ttyin && tin > maxfd) + maxfd = tin; + tmp = howmany(maxfd+1, NFDBITS) * sizeof(fd_mask); + if (tmp > fdsn) { + if (ibitsp) + free(ibitsp); + if (obitsp) + free(obitsp); + if (xbitsp) + free(xbitsp); + + fdsn = tmp; + if ((ibitsp = (fd_set *)malloc(fdsn)) == NULL) + err(1, "malloc"); + if ((obitsp = (fd_set *)malloc(fdsn)) == NULL) + err(1, "malloc"); + if ((xbitsp = (fd_set *)malloc(fdsn)) == NULL) + err(1, "malloc"); + memset(ibitsp, 0, fdsn); + memset(obitsp, 0, fdsn); + memset(xbitsp, 0, fdsn); } - if (ttyout) { - FD_SET(tout, &obits); - } - if (ttyin) { - FD_SET(tin, &ibits); - } - if (netin) { - FD_SET(net, &ibits); - } - if (netex) { - FD_SET(net, &xbits); - } - if ((c = select(16, &ibits, &obits, &xbits, - (poll == 0)? (struct timeval *)0 : &TimeValue)) < 0) { + + if (netout) + FD_SET(net, obitsp); + if (ttyout) + FD_SET(tout, obitsp); + if (ttyin) + FD_SET(tin, ibitsp); + if (netin) + FD_SET(net, ibitsp); + if (netex) + FD_SET(net, xbitsp); + if ((c = select(maxfd + 1, ibitsp, obitsp, xbitsp, + (poll == 0)? (struct timeval *)0 : &TimeValue)) < 0) { if (c == -1) { /* * we can get EINTR if we are in line mode, @@ -961,8 +985,8 @@ process_rings(int netin, int netout, int netex, int ttyin, int ttyout, int poll) /* * Any urgent data? */ - if (FD_ISSET(net, &xbits)) { - FD_CLR(net, &xbits); + if (FD_ISSET(net, xbitsp)) { + FD_CLR(net, xbitsp); SYNCHing = 1; (void) ttyflush(1); /* flush already enqueued data */ } @@ -970,10 +994,10 @@ process_rings(int netin, int netout, int netex, int ttyin, int ttyout, int poll) /* * Something to read from the network... */ - if (FD_ISSET(net, &ibits)) { + if (FD_ISSET(net, ibitsp)) { int canread; - FD_CLR(net, &ibits); + FD_CLR(net, ibitsp); canread = ring_empty_consecutive(&netiring); #if !defined(SO_OOBINLINE) /* @@ -1083,8 +1107,8 @@ process_rings(int netin, int netout, int netex, int ttyin, int ttyout, int poll) /* * Something to read from the tty... */ - if (FD_ISSET(tin, &ibits)) { - FD_CLR(tin, &ibits); + if (FD_ISSET(tin, ibitsp)) { + FD_CLR(tin, ibitsp); c = TerminalRead(ttyiring.supply, ring_empty_consecutive(&ttyiring)); if (c < 0 && errno == EIO) c = 0; @@ -1108,12 +1132,12 @@ process_rings(int netin, int netout, int netex, int ttyin, int ttyout, int poll) returnValue = 1; /* did something useful */ } - if (FD_ISSET(net, &obits)) { - FD_CLR(net, &obits); + if (FD_ISSET(net, obitsp)) { + FD_CLR(net, obitsp); returnValue |= netflush(); } - if (FD_ISSET(tout, &obits)) { - FD_CLR(tout, &obits); + if (FD_ISSET(tout, obitsp)) { + FD_CLR(tout, obitsp); returnValue |= (ttyflush(SYNCHing|flushout) > 0); }