summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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