Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: unlimited file descripters causes problems for zsh-4.0.2



On Oct 19,  5:56pm, Bart Schaefer wrote:
}
} } What I'm more concerned about is closeallelse() in exec.c, which is going
} } to make up to several billion close() calls
} 
} Here's a suggestion:  Once, at startup, we scan all the way to zopenmax()
} looking for open descriptors, and set a global to the largest number we
} find.

The following patch approximately implements the above.  It does not yet
change init.c to use a constant for fdtable_size, which is still needed
to prevent zsh from allocating huge amounts of memory if a descriptor
with a very large number is already open when the shell starts up.

I'm not able to test this on a machine that really implements a huge max.
number of file descriptors, so I won't commit it until someone else has
tried it.

Index: compat.c
===================================================================
RCS file: /extra/cvsroot/zsh/zsh-4.0/Src/compat.c,v
retrieving revision 1.2
diff -c -r1.2 compat.c
--- compat.c	2001/07/10 09:05:20	1.2
+++ compat.c	2001/10/21 19:00:17
@@ -198,12 +198,32 @@
 mod_export long
 zopenmax(void)
 {
-    long openmax = sysconf(_SC_OPEN_MAX);
+    static long openmax = 0;
 
-    if (openmax < 1)
-	return OPEN_MAX;
-    else
-	return openmax;
+    if (openmax < 1) {
+	if ((openmax = sysconf(_SC_OPEN_MAX)) < 1) {
+	    openmax = OPEN_MAX;
+	} else if (openmax > OPEN_MAX) {
+	    /* On some systems, "limit descriptors unlimited" or the  *
+	     * equivalent will set openmax to a huge number.  Unless  *
+	     * there actually is a file descriptor > OPEN_MAX already *
+	     * open, nothing in zsh requires the true maximum, and in *
+	     * fact it causes inefficiency elsewhere if we report it. *
+	     * So, report the maximum of OPEN_MAX or the largest open *
+	     * descriptor (is there a better way to find that?).      */
+	    long i, j = OPEN_MAX;
+	    for (i = j; i < openmax; i += (errno != EINTR)) {
+		errno = 0;
+		if (fcntl(i, F_GETFL, 0) < 0 &&
+		    (errno == EBADF || errno == EINTR))
+		    continue;
+		j = i;
+	    }
+	    openmax = j;
+	}
+    }
+
+    return (max_zsh_fd > openmax) ? max_zsh_fd : openmax;
 }
 #endif
 


-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com

Zsh: http://www.zsh.org | PHPerl Project: http://phperl.sourceforge.net   



Messages sorted by: Reverse Date, Date, Thread, Author