summaryrefslogtreecommitdiff
path: root/main/strcompat.c
diff options
context:
space:
mode:
authorTilghman Lesher <tilghman@meg.abyt.es>2010-04-30 06:19:35 +0000
committerTilghman Lesher <tilghman@meg.abyt.es>2010-04-30 06:19:35 +0000
commit623ba816fa650234b416947d21c7418e435262ae (patch)
tree0542418b16e63298856156c912be948b30973373 /main/strcompat.c
parente940ef8c4cd522f26d7f496feb8028164e7f759f (diff)
Don't allow file descriptors to go above 64k, when we're closing them in a fork(2).
This saves time, when, even though the system allows the process limit to be that high, the practical limit is much lower. Also introduce an additional optimization, in the form of using the CLOEXEC flag to close descriptors at the right time. (closes issue #17223) Reported by: dbackeberg Patches: 20100423__issue17223.diff.txt uploaded by tilghman (license 14) Tested by: dbackeberg git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@260292 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main/strcompat.c')
-rw-r--r--main/strcompat.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/main/strcompat.c b/main/strcompat.c
index b1d8b0d1d..923e935f7 100644
--- a/main/strcompat.c
+++ b/main/strcompat.c
@@ -26,6 +26,8 @@
#include <sys/resource.h> /* for getrlimit(2) */
#include <sys/types.h> /* for opendir(3) */
#include <dirent.h> /* for opendir(3) */
+#include <unistd.h> /* for fcntl(2) */
+#include <fcntl.h> /* for fcntl(2) */
#ifndef HAVE_STRSEP
char *strsep(char **str, const char *delims)
@@ -420,14 +422,44 @@ void closefrom(int n)
continue;
}
if ((x = strtol(entry->d_name, &result, 10)) && x >= n) {
+#ifdef STRICT_COMPAT
close(x);
+#else
+ /* This isn't strictly compatible, but it's actually faster
+ * for our purposes to set the CLOEXEC flag than to close
+ * file descriptors.
+ */
+ long flags = fcntl(x, F_GETFD);
+ if (flags == -1 && errno == EBADF) {
+ continue;
+ }
+ fcntl(x, F_SETFD, flags | FD_CLOEXEC);
+#endif
}
}
closedir(dir);
} else {
getrlimit(RLIMIT_NOFILE, &rl);
+ if (rl.rlim_cur > 65535) {
+ /* A more reasonable value. Consider that the primary source of
+ * file descriptors in Asterisk are UDP sockets, of which we are
+ * limited to 65,535 per address. We additionally limit that down
+ * to about 10,000 sockets per protocol. While the kernel will
+ * allow us to set the fileno limit higher (up to 4.2 billion),
+ * there really is no practical reason for it to be that high.
+ */
+ rl.rlim_cur = 65535;
+ }
for (x = n; x < rl.rlim_cur; x++) {
+#ifdef STRICT_COMPAT
close(x);
+#else
+ long flags = fcntl(x, F_GETFD);
+ if (flags == -1 && errno == EBADF) {
+ continue;
+ }
+ fcntl(x, F_SETFD, flags | FD_CLOEXEC);
+#endif
}
}
}