diff options
author | Werner Koch <[email protected]> | 2016-01-15 14:17:26 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2016-01-15 14:17:26 +0000 |
commit | 7101fcbb662220326f2fc786219c1853f27a5298 (patch) | |
tree | 9b71a0a7fee2500ecc26f62eba888dfe9c9526d1 /src/system-posix.c | |
parent | Post release updates. (diff) | |
download | libassuan-7101fcbb662220326f2fc786219c1853f27a5298.tar.gz libassuan-7101fcbb662220326f2fc786219c1853f27a5298.zip |
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 <[email protected]>
Diffstat (limited to 'src/system-posix.c')
-rw-r--r-- | src/system-posix.c | 73 |
1 files changed, 64 insertions, 9 deletions
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 <stdlib.h> #include <errno.h> +#ifdef HAVE_STDINT_H +# include <stdint.h> +#endif /* Solaris 8 needs sys/types.h before time.h. */ #include <sys/types.h> #include <time.h> #include <fcntl.h> #include <sys/wait.h> +#ifdef HAVE_GETRLIMIT +# include <sys/time.h> +# include <sys/resource.h> +#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) |