From 7101fcbb662220326f2fc786219c1853f27a5298 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 15 Jan 2016 15:17:26 +0100 Subject: Improve getting of max. number of open fds. * configure.ac (AC_CHECK_FUNCS): Add getrlimit. * src/assuan-pipe-connect.c (MAX_OPEN_FDS): Remove non-used macro. * src/system.c (MAX_OPEN_FDS): Remove non-used macro. * src/system-posix.c: Include stdint.h, sys/time.h, sys/resource.h. (MAX_OPEN_FDS): Remove non-used macro. (get_max_fds): New. Taken from gnupg/common/exechelp-posix.c. (__assuan_spawn): Use it here. -- This is related to GnuPG-bug-id: 2071 Changing of get_max_fds from LPGLv3+ to LGPLv2+ approved by me as sole author or that code. Signed-off-by: Werner Koch --- src/system-posix.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 64 insertions(+), 9 deletions(-) (limited to 'src/system-posix.c') diff --git a/src/system-posix.c b/src/system-posix.c index 5bdc676..8ca27e6 100644 --- a/src/system-posix.c +++ b/src/system-posix.c @@ -24,21 +24,23 @@ #include #include +#ifdef HAVE_STDINT_H +# include +#endif /* Solaris 8 needs sys/types.h before time.h. */ #include #include #include #include +#ifdef HAVE_GETRLIMIT +# include +# include +#endif /*HAVE_GETRLIMIT*/ + #include "assuan-defs.h" #include "debug.h" -#ifdef _POSIX_OPEN_MAX -#define MAX_OPEN_FDS _POSIX_OPEN_MAX -#else -#define MAX_OPEN_FDS 20 -#endif - @@ -168,6 +170,61 @@ writen (int fd, const char *buffer, size_t length) } +/* Return the maximum number of currently allowed open file + * descriptors. */ +static int +get_max_fds (void) +{ + int max_fds = -1; + +#ifdef HAVE_GETRLIMIT + struct rlimit rl; + +# ifdef RLIMIT_NOFILE + if (!getrlimit (RLIMIT_NOFILE, &rl)) + max_fds = rl.rlim_max; +# endif + +# ifdef RLIMIT_OFILE + if (max_fds == -1 && !getrlimit (RLIMIT_OFILE, &rl)) + max_fds = rl.rlim_max; + +# endif +#endif /*HAVE_GETRLIMIT*/ + +#ifdef _SC_OPEN_MAX + if (max_fds == -1) + { + long int scres = sysconf (_SC_OPEN_MAX); + if (scres >= 0) + max_fds = scres; + } +#endif + +#ifdef _POSIX_OPEN_MAX + if (max_fds == -1) + max_fds = _POSIX_OPEN_MAX; +#endif + +#ifdef OPEN_MAX + if (max_fds == -1) + max_fds = OPEN_MAX; +#endif + + if (max_fds == -1) + max_fds = 256; /* Arbitrary limit. */ + + /* AIX returns INT32_MAX instead of a proper value. We assume that + this is always an error and use a more reasonable limit. */ +#ifdef INT32_MAX + if (max_fds == INT32_MAX) + max_fds = 256; +#endif + + return max_fds; +} + + int __assuan_spawn (assuan_context_t ctx, pid_t *r_pid, const char *name, const char **argv, @@ -246,9 +303,7 @@ __assuan_spawn (assuan_context_t ctx, pid_t *r_pid, const char *name, /* Close all files which will not be duped and are not in the fd_child_list. */ - n = sysconf (_SC_OPEN_MAX); - if (n < 0) - n = MAX_OPEN_FDS; + n = get_max_fds (); for (i = 0; i < n; i++) { if (i == STDIN_FILENO || i == STDOUT_FILENO || i == STDERR_FILENO) -- cgit v1.2.3