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 <stdlib.h>
#include <err.h>
__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);
}