diff options
author | Eric S. Raymond <esr@thyrsus.com> | 1996-10-19 19:03:31 +0000 |
---|---|---|
committer | Eric S. Raymond <esr@thyrsus.com> | 1996-10-19 19:03:31 +0000 |
commit | 07513709eed70fe7fcf7361eaf17640ed74683bf (patch) | |
tree | ab22ca5334e422d176327e5162c7390dc3c369aa /fetchmail.c | |
parent | 5bd3f8287149511024b95c01fb4212e60ec6fe13 (diff) | |
download | fetchmail-07513709eed70fe7fcf7361eaf17640ed74683bf.tar.gz fetchmail-07513709eed70fe7fcf7361eaf17640ed74683bf.tar.bz2 fetchmail-07513709eed70fe7fcf7361eaf17640ed74683bf.zip |
Avoid the socket-exhaustion bug.
svn path=/trunk/; revision=354
Diffstat (limited to 'fetchmail.c')
-rw-r--r-- | fetchmail.c | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/fetchmail.c b/fetchmail.c index 5c1023e7..3e5a991d 100644 --- a/fetchmail.c +++ b/fetchmail.c @@ -29,6 +29,8 @@ #include "fetchmail.h" #include "getopt.h" +#define DROPDEAD 6 /* maximum bad socjet opens */ + #ifdef HAVE_PROTOTYPES /* prototypes for internal functions */ static int dump_options (struct hostrec *queryctl); @@ -62,7 +64,7 @@ main (argc,argv) int argc; char **argv; { - int mboxfd, st, bkgd; + int mboxfd, st, bkgd, lossage; struct hostrec def_opts; int parsestatus, implicitmode; char *servername, *user, *home, *tmpdir, tmpbuf[BUFSIZ]; @@ -394,12 +396,38 @@ char **argv; * Query all hosts. If there's only one, the error return will * reflect the status of that transaction. */ + lossage = 0; do { for (hostp = hostlist; hostp; hostp = hostp->next) { if (hostp->active && !(implicitmode && hostp->skip)) { popstatus = query_host(hostp); + + /* + * Under Linux, if fetchmail is run in daemon mode + * with the network inaccessible, each poll leaves a + * socket allocated but in CLOSE state (this is + * visible in netstat(1)'s output). For some reason, + * these sockets aren't garbage-collected until + * fetchmail exits. When whatever kernel table is + * involved fills up, fetchmail can no longer run even + * if the network is up. This does not appear to be a + * socket leak in fetchmail. To avoid this + * problem, fetchmail commits seppuku after five + * unsuccessful socket opens. + */ + if (popstatus == PS_SOCKET) + lossage++; + else + lossage = 0; + if (lossage >= DROPDEAD) + { + fputs("fetchmail: exiting, network appears to be down\n", + stderr); + termhook(0); + } + if (!check_only) update_uid_lists(hostp); } |