summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbrian <brian@FreeBSD.org>2000-10-09 21:18:23 +0000
committerbrian <brian@FreeBSD.org>2000-10-09 21:18:23 +0000
commit38c4d01137dc7f3cd19b75f9b4513c9bab16388e (patch)
tree5fca605418aeeecc4aab375a4c4d001d27a1906d
parentecc37ebaa1badd59b516817d9bab52a82eaf84b8 (diff)
downloadFreeBSD-src-38c4d01137dc7f3cd19b75f9b4513c9bab16388e.zip
FreeBSD-src-38c4d01137dc7f3cd19b75f9b4513c9bab16388e.tar.gz
Create fd_sets big enough to handle getdtablesize() descriptors.
-rw-r--r--usr.sbin/ppp/defs.c12
-rw-r--r--usr.sbin/ppp/defs.h2
-rw-r--r--usr.sbin/ppp/ether.c16
-rw-r--r--usr.sbin/ppp/main.c76
4 files changed, 68 insertions, 38 deletions
diff --git a/usr.sbin/ppp/defs.c b/usr.sbin/ppp/defs.c
index c1b193d..3c72128 100644
--- a/usr.sbin/ppp/defs.c
+++ b/usr.sbin/ppp/defs.c
@@ -376,3 +376,15 @@ SetTitle(const char *title)
else
setproctitle("%s", title);
}
+
+fd_set *
+mkfdset()
+{
+ return (fd_set *)malloc(howmany(getdtablesize(), NFDBITS) * sizeof (fd_mask));
+}
+
+void
+zerofdset(fd_set *s)
+{
+ memset(s, '\0', howmany(getdtablesize(), NFDBITS) * sizeof (fd_mask));
+}
diff --git a/usr.sbin/ppp/defs.h b/usr.sbin/ppp/defs.h
index 8fe68b2..aee5d63 100644
--- a/usr.sbin/ppp/defs.h
+++ b/usr.sbin/ppp/defs.h
@@ -121,3 +121,5 @@ extern const char *NumStr(long, char *, size_t);
extern const char *HexStr(long, char *, size_t);
extern const char *ex_desc(int);
extern void SetTitle(const char *);
+extern fd_set *mkfdset(void);
+extern void zerofdset(fd_set *);
diff --git a/usr.sbin/ppp/ether.c b/usr.sbin/ppp/ether.c
index 7d80a69..c9906db 100644
--- a/usr.sbin/ppp/ether.c
+++ b/usr.sbin/ppp/ether.c
@@ -203,15 +203,23 @@ ether_MessageIn(struct etherdevice *dev)
char unknown[14];
const char *msg;
struct timeval t;
- fd_set r;
+ fd_set *r;
+ int ret;
if (dev->cs < 0)
return;
- FD_ZERO(&r);
- FD_SET(dev->cs, &r);
+ if ((r = mkfdset()) == NULL) {
+ log_Printf(LogERROR, "DoLoop: Cannot create fd_set\n");
+ return;
+ }
+ zerofdset(r);
+ FD_SET(dev->cs, r);
t.tv_sec = t.tv_usec = 0;
- if (select(dev->cs + 1, &r, NULL, NULL, &t) <= 0)
+ ret = select(dev->cs + 1, r, NULL, NULL, &t);
+ free(r);
+
+ if (ret <= 0)
return;
if (NgRecvMsg(dev->cs, rep, sizeof msgbuf, NULL) < 0)
diff --git a/usr.sbin/ppp/main.c b/usr.sbin/ppp/main.c
index bd875b3..731ef77 100644
--- a/usr.sbin/ppp/main.c
+++ b/usr.sbin/ppp/main.c
@@ -281,21 +281,11 @@ main(int argc, char **argv)
{
char *name;
const char *lastlabel;
- int nfds, label, arg;
+ int label, arg;
struct bundle *bundle;
struct prompt *prompt;
struct switches sw;
- nfds = getdtablesize();
- if (nfds >= FD_SETSIZE)
- /*
- * If we've got loads of file descriptors, make sure they're all
- * closed. If they aren't, we may end up with a seg fault when our
- * `fd_set's get too big when select()ing !
- */
- while (--nfds > 2)
- close(nfds);
-
name = strrchr(argv[0], '/');
log_Open(name ? name + 1 : argv[0]);
@@ -501,23 +491,41 @@ main(int argc, char **argv)
static void
DoLoop(struct bundle *bundle)
{
- fd_set rfds, wfds, efds;
+ fd_set *rfds, *wfds, *efds;
int i, nfds, nothing_done;
struct probe probe;
probe_Init(&probe);
+ if ((rfds = mkfdset()) == NULL) {
+ log_Printf(LogERROR, "DoLoop: Cannot create fd_set\n");
+ return;
+ }
+
+ if ((wfds = mkfdset()) == NULL) {
+ log_Printf(LogERROR, "DoLoop: Cannot create fd_set\n");
+ free(rfds);
+ return;
+ }
+
+ if ((efds = mkfdset()) == NULL) {
+ log_Printf(LogERROR, "DoLoop: Cannot create fd_set\n");
+ free(rfds);
+ free(wfds);
+ return;
+ }
+
for (; !bundle_IsDead(bundle); bundle_CleanDatalinks(bundle)) {
nfds = 0;
- FD_ZERO(&rfds);
- FD_ZERO(&wfds);
- FD_ZERO(&efds);
+ zerofdset(rfds);
+ zerofdset(wfds);
+ zerofdset(efds);
/* All our datalinks, the tun device and the MP socket */
- descriptor_UpdateSet(&bundle->desc, &rfds, &wfds, &efds, &nfds);
+ descriptor_UpdateSet(&bundle->desc, rfds, wfds, efds, &nfds);
/* All our prompts and the diagnostic socket */
- descriptor_UpdateSet(&server.desc, &rfds, NULL, NULL, &nfds);
+ descriptor_UpdateSet(&server.desc, rfds, NULL, NULL, &nfds);
bundle_CleanDatalinks(bundle);
if (bundle_IsDead(bundle))
@@ -535,7 +543,7 @@ DoLoop(struct bundle *bundle)
if (sig_Handle())
continue;
- i = select(nfds, &rfds, &wfds, &efds, NULL);
+ i = select(nfds, rfds, wfds, efds, NULL);
if (i < 0 && errno != EINTR) {
log_Printf(LogERROR, "DoLoop: select(): %s\n", strerror(errno));
@@ -543,29 +551,29 @@ DoLoop(struct bundle *bundle)
struct timeval t;
for (i = 0; i <= nfds; i++) {
- if (FD_ISSET(i, &rfds)) {
+ if (FD_ISSET(i, rfds)) {
log_Printf(LogTIMER, "Read set contains %d\n", i);
- FD_CLR(i, &rfds);
+ FD_CLR(i, rfds);
t.tv_sec = t.tv_usec = 0;
- if (select(nfds, &rfds, &wfds, &efds, &t) != -1) {
+ if (select(nfds, rfds, wfds, efds, &t) != -1) {
log_Printf(LogTIMER, "The culprit !\n");
break;
}
}
- if (FD_ISSET(i, &wfds)) {
+ if (FD_ISSET(i, wfds)) {
log_Printf(LogTIMER, "Write set contains %d\n", i);
- FD_CLR(i, &wfds);
+ FD_CLR(i, wfds);
t.tv_sec = t.tv_usec = 0;
- if (select(nfds, &rfds, &wfds, &efds, &t) != -1) {
+ if (select(nfds, rfds, wfds, efds, &t) != -1) {
log_Printf(LogTIMER, "The culprit !\n");
break;
}
}
- if (FD_ISSET(i, &efds)) {
+ if (FD_ISSET(i, efds)) {
log_Printf(LogTIMER, "Error set contains %d\n", i);
- FD_CLR(i, &efds);
+ FD_CLR(i, efds);
t.tv_sec = t.tv_usec = 0;
- if (select(nfds, &rfds, &wfds, &efds, &t) != -1) {
+ if (select(nfds, rfds, wfds, efds, &t) != -1) {
log_Printf(LogTIMER, "The culprit !\n");
break;
}
@@ -583,7 +591,7 @@ DoLoop(struct bundle *bundle)
continue;
for (i = 0; i <= nfds; i++)
- if (FD_ISSET(i, &efds)) {
+ if (FD_ISSET(i, efds)) {
log_Printf(LogPHASE, "Exception detected on descriptor %d\n", i);
/* We deal gracefully with link descriptor exceptions */
if (!bundle_Exception(bundle, i)) {
@@ -597,18 +605,18 @@ DoLoop(struct bundle *bundle)
nothing_done = 1;
- if (descriptor_IsSet(&server.desc, &rfds)) {
- descriptor_Read(&server.desc, bundle, &rfds);
+ if (descriptor_IsSet(&server.desc, rfds)) {
+ descriptor_Read(&server.desc, bundle, rfds);
nothing_done = 0;
}
- if (descriptor_IsSet(&bundle->desc, &rfds)) {
- descriptor_Read(&bundle->desc, bundle, &rfds);
+ if (descriptor_IsSet(&bundle->desc, rfds)) {
+ descriptor_Read(&bundle->desc, bundle, rfds);
nothing_done = 0;
}
- if (descriptor_IsSet(&bundle->desc, &wfds))
- if (!descriptor_Write(&bundle->desc, bundle, &wfds) && nothing_done) {
+ if (descriptor_IsSet(&bundle->desc, wfds))
+ if (!descriptor_Write(&bundle->desc, bundle, wfds) && nothing_done) {
/*
* This is disasterous. The OS has told us that something is
* writable, and all our write()s have failed. Rather than
OpenPOWER on IntegriCloud