about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBart Schaefer <barts@users.sourceforge.net>2001-11-03 23:39:11 +0000
committerBart Schaefer <barts@users.sourceforge.net>2001-11-03 23:39:11 +0000
commitc43a6be917e0eafbaac49971b97408d366c5a5a4 (patch)
treeed5e8ead0a5e7bf96c12d7591490f669c24d34d8
parentd98a67c56990a81bc8a913612b8a2ae496000836 (diff)
downloadzsh-c43a6be917e0eafbaac49971b97408d366c5a5a4.tar.gz
zsh-c43a6be917e0eafbaac49971b97408d366c5a5a4.tar.xz
zsh-c43a6be917e0eafbaac49971b97408d366c5a5a4.zip
16094: zopenmax() need only return the highest-numbered open descriptor
-rw-r--r--Src/compat.c30
1 files changed, 25 insertions, 5 deletions
diff --git a/Src/compat.c b/Src/compat.c
index 86611a727..126d4bd4a 100644
--- a/Src/compat.c
+++ b/Src/compat.c
@@ -198,12 +198,32 @@ zpathmax(char *dir)
 mod_export long
 zopenmax(void)
 {
-    long openmax = sysconf(_SC_OPEN_MAX);
+    static long openmax = 0;
+
+    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;
+	}
+    }
 
-    if (openmax < 1)
-	return OPEN_MAX;
-    else
-	return openmax;
+    return (max_zsh_fd > openmax) ? max_zsh_fd : openmax;
 }
 #endif