diff options
author | jkh <jkh@FreeBSD.org> | 2001-12-08 21:51:34 +0000 |
---|---|---|
committer | jkh <jkh@FreeBSD.org> | 2001-12-08 21:51:34 +0000 |
commit | 8496a60c31fd9e35c200728a2c8ba1f2879cadd9 (patch) | |
tree | 8cc7f399e630f5ed88500f492aaf7bef53490da5 /usr.bin/telnet/sys_bsd.c | |
parent | d43f78304005450d8f53ea339e79d9ea90fc4c87 (diff) | |
download | FreeBSD-src-8496a60c31fd9e35c200728a2c8ba1f2879cadd9.zip FreeBSD-src-8496a60c31fd9e35c200728a2c8ba1f2879cadd9.tar.gz |
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.
Obtained from: OpenBSD and Apple's Radar database
MFC after: 2 days
Diffstat (limited to 'usr.bin/telnet/sys_bsd.c')
-rw-r--r-- | usr.bin/telnet/sys_bsd.c | 88 |
1 files changed, 56 insertions, 32 deletions
diff --git a/usr.bin/telnet/sys_bsd.c b/usr.bin/telnet/sys_bsd.c index bcb302c..fca026d 100644 --- a/usr.bin/telnet/sys_bsd.c +++ b/usr.bin/telnet/sys_bsd.c @@ -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 }; - - if (netout) { - FD_SET(net, &obits); - } - if (ttyout) { - FD_SET(tout, &obits); - } - if (ttyin) { - FD_SET(tin, &ibits); - } - if (netin) { - FD_SET(net, &ibits); - } - if (netex) { - FD_SET(net, &xbits); + int maxfd = -1; + int tmp; + + 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 ((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); } |