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 | |
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]>
-rw-r--r-- | configure.ac | 3 | ||||
-rw-r--r-- | src/assuan-pipe-connect.c | 7 | ||||
-rw-r--r-- | src/system-posix.c | 73 | ||||
-rw-r--r-- | src/system.c | 26 |
4 files changed, 76 insertions, 33 deletions
diff --git a/configure.ac b/configure.ac index cd1a80d..755a55c 100644 --- a/configure.ac +++ b/configure.ac @@ -360,7 +360,8 @@ AM_PATH_GPG_ERROR(1.17,, AC_MSG_ERROR([libgpg-error was not found])) # # Checks for library functions. # -AC_CHECK_FUNCS([flockfile funlockfile inet_pton stat getaddrinfo]) +AC_CHECK_FUNCS([flockfile funlockfile inet_pton stat getaddrinfo \ + getrlimit ]) # On some systems (e.g. Solaris) nanosleep requires linking to librl. # Given that we use nanosleep only as an optimization over a select diff --git a/src/assuan-pipe-connect.c b/src/assuan-pipe-connect.c index edc8dbb..e5d2a38 100644 --- a/src/assuan-pipe-connect.c +++ b/src/assuan-pipe-connect.c @@ -65,13 +65,6 @@ #endif -#ifdef _POSIX_OPEN_MAX -#define MAX_OPEN_FDS _POSIX_OPEN_MAX -#else -#define MAX_OPEN_FDS 20 -#endif - - /* This should be called to make sure that SIGPIPE gets ignored. */ static void fix_signals (void) 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) diff --git a/src/system.c b/src/system.c index 1fca056..ddb99fb 100644 --- a/src/system.c +++ b/src/system.c @@ -36,12 +36,6 @@ #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 - #define DEBUG_SYSIO 0 @@ -66,11 +60,11 @@ _assuan_calloc (assuan_context_t ctx, size_t cnt, size_t elsize) { void *ptr; size_t nbytes; - + nbytes = cnt * elsize; /* Check for overflow. */ - if (elsize && nbytes / elsize != cnt) + if (elsize && nbytes / elsize != cnt) { gpg_err_set_errno (ENOMEM); return NULL; @@ -111,7 +105,7 @@ _assuan_system_hooks_copy (assuan_system_hooks_t dst, /* Reset the defaults. */ if (dst != &_assuan_system_hooks) memcpy (dst, &_assuan_system_hooks, sizeof (*dst)); - + dst->version = ASSUAN_SYSTEM_HOOKS_VERSION; if (src->version >= 1) { @@ -164,7 +158,7 @@ _assuan_pipe (assuan_context_t ctx, assuan_fd_t fd[2], int inherit_idx) if (err) return TRACE_SYSRES (err); - return TRACE_SUC2 ("read=0x%x, write=0x%x", fd[0], fd[1]); + return TRACE_SUC2 ("read=0x%x, write=0x%x", fd[0], fd[1]); } @@ -257,7 +251,7 @@ _assuan_recvmsg (assuan_context_t ctx, assuan_fd_t fd, assuan_msghdr_t msg, cmptr->cmsg_len - (((char *)data) - ((char *)cmptr)), cmptr->cmsg_level, cmptr->cmsg_type, *(int *)data); } - } + } return TRACE_SYSRES (res); #else return (ctx->system.recvmsg) (ctx, fd, msg, flags); @@ -280,7 +274,7 @@ _assuan_sendmsg (assuan_context_t ctx, assuan_fd_t fd, assuan_msghdr_t msg, TRACE_LOG2 ("msg->iov[0] = { iov_base=%p, iov_len=%i }", msg->msg_iov[0].iov_base, msg->msg_iov[0].iov_len); TRACE_LOGBUF (msg->msg_iov[0].iov_base, msg->msg_iov[0].iov_len); - + cmptr = CMSG_FIRSTHDR (msg); if (cmptr) { @@ -358,7 +352,7 @@ _assuan_spawn (assuan_context_t ctx, pid_t *r_pid, const char *name, /* FIXME: Add some sort of waitpid function that covers GPGME and gpg-agent's use of assuan. */ -pid_t +pid_t _assuan_waitpid (assuan_context_t ctx, pid_t pid, int action, int *status, int options) { @@ -384,7 +378,7 @@ _assuan_socketpair (assuan_context_t ctx, int namespace, int style, TRACE_BEG4 (ctx, ASSUAN_LOG_SYSIO, "_assuan_socketpair", ctx, "namespace=%i,style=%i,protocol=%i,filedes=%p", namespace, style, protocol, filedes); - + res = (ctx->system.socketpair) (ctx, namespace, style, protocol, filedes); if (res == 0) TRACE_LOG2 ("filedes = { 0x%x, 0x%x }", filedes[0], filedes[1]); @@ -401,7 +395,7 @@ _assuan_socket (assuan_context_t ctx, int namespace, int style, int protocol) TRACE_BEG3 (ctx, ASSUAN_LOG_SYSIO, "_assuan_socket", ctx, "namespace=%i,style=%i,protocol=%i", namespace, style, protocol); - + res = (ctx->system.socket) (ctx, namespace, style, protocol); return TRACE_SYSRES (res); } @@ -413,7 +407,7 @@ _assuan_connect (assuan_context_t ctx, int sock, struct sockaddr *addr, socklen_ int res; TRACE_BEG3 (ctx, ASSUAN_LOG_SYSIO, "_assuan_connect", ctx, "socket=%i,addr=%p,length=%i", sock, addr, length); - + res = (ctx->system.connect) (ctx, sock, addr, length); return TRACE_SYSRES (res); } |