summaryrefslogtreecommitdiffstats
path: root/contrib
diff options
context:
space:
mode:
authorjkh <jkh@FreeBSD.org>2001-12-09 09:53:27 +0000
committerjkh <jkh@FreeBSD.org>2001-12-09 09:53:27 +0000
commitfcc97a61adfa5dac1098e5ae102eacff890bba85 (patch)
tree639c66425712a98332c5503ac4d1cc26aebe1577 /contrib
parent3824d202d7975b7fa60b86b36924f7a0d3617da8 (diff)
downloadFreeBSD-src-fcc97a61adfa5dac1098e5ae102eacff890bba85.zip
FreeBSD-src-fcc97a61adfa5dac1098e5ae102eacff890bba85.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. There are also too many versions of telnet in the tree. Obtained from: OpenBSD and Apple's Radar database MFC after: 2 days
Diffstat (limited to 'contrib')
-rw-r--r--contrib/telnet/telnet/sys_bsd.c88
1 files changed, 56 insertions, 32 deletions
diff --git a/contrib/telnet/telnet/sys_bsd.c b/contrib/telnet/telnet/sys_bsd.c
index bcb302c..fca026d 100644
--- a/contrib/telnet/telnet/sys_bsd.c
+++ b/contrib/telnet/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);
}
OpenPOWER on IntegriCloud