-/* getdtablesize() function for platforms that don't have it.
- Copyright (C) 2008-2011 Free Software Foundation, Inc.
+/* getdtablesize() function: Return maximum possible file descriptor value + 1.
+ Copyright (C) 2008-2018 Free Software Foundation, Inc.
Written by Bruno Haible <bruno@clisp.org>, 2008.
This program is free software: you can redistribute it and/or modify
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
#include <config.h>
#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
-#include <stdio.h>
+# include <stdio.h>
-/* Cache for the previous getdtablesize () result. */
+# if HAVE_MSVC_INVALID_PARAMETER_HANDLER
+# include "msvc-inval.h"
+# endif
+
+# if HAVE_MSVC_INVALID_PARAMETER_HANDLER
+static int
+_setmaxstdio_nothrow (int newmax)
+{
+ int result;
+
+ TRY_MSVC_INVAL
+ {
+ result = _setmaxstdio (newmax);
+ }
+ CATCH_MSVC_INVAL
+ {
+ result = -1;
+ }
+ DONE_MSVC_INVAL;
+
+ return result;
+}
+# else
+# define _setmaxstdio_nothrow _setmaxstdio
+# endif
+
+/* Cache for the previous getdtablesize () result. Safe to cache because
+ Windows also lacks setrlimit. */
static int dtablesize;
int
freed when we call _setmaxstdio with the original value. */
int orig_max_stdio = _getmaxstdio ();
unsigned int bound;
- for (bound = 0x10000; _setmaxstdio (bound) < 0; bound = bound / 2)
+ for (bound = 0x10000; _setmaxstdio_nothrow (bound) < 0; bound = bound / 2)
;
- _setmaxstdio (orig_max_stdio);
+ _setmaxstdio_nothrow (orig_max_stdio);
dtablesize = bound;
}
return dtablesize;
}
+#else
+
+# include <limits.h>
+# include <sys/resource.h>
+
+# ifndef RLIM_SAVED_CUR
+# define RLIM_SAVED_CUR RLIM_INFINITY
+# endif
+# ifndef RLIM_SAVED_MAX
+# define RLIM_SAVED_MAX RLIM_INFINITY
+# endif
+
+# ifdef __CYGWIN__
+ /* Cygwin 1.7.25 auto-increases the RLIMIT_NOFILE soft limit until it
+ hits the compile-time constant hard limit of 3200. We might as
+ well just report the hard limit. */
+# define rlim_cur rlim_max
+# endif
+
+int
+getdtablesize (void)
+{
+ struct rlimit lim;
+
+ if (getrlimit (RLIMIT_NOFILE, &lim) == 0
+ && 0 <= lim.rlim_cur && lim.rlim_cur <= INT_MAX
+ && lim.rlim_cur != RLIM_INFINITY
+ && lim.rlim_cur != RLIM_SAVED_CUR
+ && lim.rlim_cur != RLIM_SAVED_MAX)
+ return lim.rlim_cur;
+
+ return INT_MAX;
+}
+
#endif