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
This commit is contained in:
jkh 2001-12-09 09:53:27 +00:00
parent c166211dae
commit 0dcd34090c

View File

@ -32,6 +32,8 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
#include <stdlib.h>
#include <err.h>
__FBSDID("$FreeBSD$"); __FBSDID("$FreeBSD$");
@ -105,7 +107,8 @@ struct termio old_tc = { 0, 0, 0, 0, {}, 0, 0 };
# endif # endif
#endif /* USE_TERMIO */ #endif /* USE_TERMIO */
static fd_set ibits, obits, xbits; static fd_set *ibitsp, *obitsp, *xbitsp;
int fdsn;
#ifdef SIGINT #ifdef SIGINT
static SIG_FUNC_RET intr(int); static SIG_FUNC_RET intr(int);
@ -125,10 +128,6 @@ init_sys(void)
{ {
tout = fileno(stdout); tout = fileno(stdout);
tin = fileno(stdin); tin = fileno(stdin);
FD_ZERO(&ibits);
FD_ZERO(&obits);
FD_ZERO(&xbits);
errno = 0; errno = 0;
} }
@ -924,24 +923,49 @@ process_rings(int netin, int netout, int netex, int ttyin, int ttyout, int poll)
int c; int c;
int returnValue = 0; int returnValue = 0;
static struct timeval TimeValue = { 0, 0 }; static struct timeval TimeValue = { 0, 0 };
int maxfd = -1;
int tmp;
if (netout) { if ((netout || netin || netex) && net > maxfd)
FD_SET(net, &obits); 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 (netout)
} FD_SET(net, obitsp);
if (ttyin) { if (ttyout)
FD_SET(tin, &ibits); FD_SET(tout, obitsp);
} if (ttyin)
if (netin) { FD_SET(tin, ibitsp);
FD_SET(net, &ibits); if (netin)
} FD_SET(net, ibitsp);
if (netex) { if (netex)
FD_SET(net, &xbits); FD_SET(net, xbitsp);
} if ((c = select(maxfd + 1, ibitsp, obitsp, xbitsp,
if ((c = select(16, &ibits, &obits, &xbits, (poll == 0)? (struct timeval *)0 : &TimeValue)) < 0) {
(poll == 0)? (struct timeval *)0 : &TimeValue)) < 0) {
if (c == -1) { if (c == -1) {
/* /*
* we can get EINTR if we are in line mode, * 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? * Any urgent data?
*/ */
if (FD_ISSET(net, &xbits)) { if (FD_ISSET(net, xbitsp)) {
FD_CLR(net, &xbits); FD_CLR(net, xbitsp);
SYNCHing = 1; SYNCHing = 1;
(void) ttyflush(1); /* flush already enqueued data */ (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... * Something to read from the network...
*/ */
if (FD_ISSET(net, &ibits)) { if (FD_ISSET(net, ibitsp)) {
int canread; int canread;
FD_CLR(net, &ibits); FD_CLR(net, ibitsp);
canread = ring_empty_consecutive(&netiring); canread = ring_empty_consecutive(&netiring);
#if !defined(SO_OOBINLINE) #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... * Something to read from the tty...
*/ */
if (FD_ISSET(tin, &ibits)) { if (FD_ISSET(tin, ibitsp)) {
FD_CLR(tin, &ibits); FD_CLR(tin, ibitsp);
c = TerminalRead(ttyiring.supply, ring_empty_consecutive(&ttyiring)); c = TerminalRead(ttyiring.supply, ring_empty_consecutive(&ttyiring));
if (c < 0 && errno == EIO) if (c < 0 && errno == EIO)
c = 0; 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 */ returnValue = 1; /* did something useful */
} }
if (FD_ISSET(net, &obits)) { if (FD_ISSET(net, obitsp)) {
FD_CLR(net, &obits); FD_CLR(net, obitsp);
returnValue |= netflush(); returnValue |= netflush();
} }
if (FD_ISSET(tout, &obits)) { if (FD_ISSET(tout, obitsp)) {
FD_CLR(tout, &obits); FD_CLR(tout, obitsp);
returnValue |= (ttyflush(SYNCHing|flushout) > 0); returnValue |= (ttyflush(SYNCHing|flushout) > 0);
} }