summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2007-11-02 16:02:26 +0000
committerNick Mathewson <nickm@torproject.org>2007-11-02 16:02:26 +0000
commitdfc689bda232de67ff3ed20b145e12e57dd5dd31 (patch)
tree0110247f06634530a9368f97d3f9ca242f303b21
parente76581f97eb849a0e3de869828f4ff809d00e9ba (diff)
downloadtor-dfc689bda232de67ff3ed20b145e12e57dd5dd31.tar.gz
tor-dfc689bda232de67ff3ed20b145e12e57dd5dd31.zip
r14652@tombo: nickm | 2007-11-02 12:02:13 -0400
If setting our rlimit to rlim_max or cap fails, fall back to OPEN_FILES if defiled. This makes Tor run on OSX 10.5, while allowing OSX to mend its ways in the future. svn:r12341
-rw-r--r--ChangeLog5
-rw-r--r--configure.in2
-rw-r--r--src/common/compat.c33
3 files changed, 35 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index 7aedd17534..28432b5fb4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -77,7 +77,10 @@ Changes in version 0.2.0.10-alpha - 2007-1?-??
0.2.0.9-alpha.
- Minor bugfixes (portability):
- - Run correctly on platforms where rlim_t is larger than unsigned long.
+ - Run correctly on platforms where rlim_t is larger than unsigned
+ long.
+ - Run correctly on platforms where the real limit for number of
+ open files is OPEN_FILES, not rlim_max from getrlimit(RLIMIT_NOFILES)
Changes in version 0.2.0.9-alpha - 2007-10-24
diff --git a/configure.in b/configure.in
index 5ad8617ab3..b465ad5bef 100644
--- a/configure.in
+++ b/configure.in
@@ -251,7 +251,7 @@ AC_CHECK_HEADERS(netdb.h sys/ioctl.h sys/socket.h arpa/inet.h netinet/in.h pwd.h
dnl These headers are not essential
-AC_CHECK_HEADERS(stdint.h sys/types.h inttypes.h sys/param.h sys/wait.h limits.h sys/limits.h netinet/in.h arpa/inet.h machine/limits.h syslog.h sys/time.h sys/resource.h inttypes.h utime.h sys/utime.h sys/mman.h netintet/in.h netinet/in6.h malloc.h)
+AC_CHECK_HEADERS(stdint.h sys/types.h inttypes.h sys/param.h sys/wait.h limits.h sys/limits.h netinet/in.h arpa/inet.h machine/limits.h syslog.h sys/time.h sys/resource.h inttypes.h utime.h sys/utime.h sys/mman.h netintet/in.h netinet/in6.h malloc.h sys/syslimits.h)
AC_CHECK_HEADERS(net/if.h, net_if_found=1, net_if_found=0,
[#ifdef HAVE_SYS_TYPES_H
diff --git a/src/common/compat.c b/src/common/compat.c
index b46591701e..bc99a86d6e 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -94,6 +94,9 @@ const char compat_c_id[] =
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
+#ifdef HAVE_SYS_SYSLIMITS_H
+#include <sys/syslimits.h>
+#endif
#ifdef USE_BSOCKETS
#include <bsocket.h>
@@ -710,10 +713,34 @@ set_max_file_descriptors(unsigned long limit, unsigned long cap)
(unsigned long)rlim.rlim_cur, (unsigned long)most);
}
rlim.rlim_cur = most;
+
if (setrlimit(RLIMIT_NOFILE, &rlim) != 0) {
- log_warn(LD_CONFIG, "Could not set maximum number of file descriptors: %s",
- strerror(errno));
- return -1;
+ int bad = 1;
+#ifdef OPEN_MAX
+ if (errno == EINVAL && OPEN_MAX < rlim.rlim_cur) {
+ /* On some platforms, OPEN_MAX is the real limit, and getrlimit() is
+ * full of nasty lies. I'm looking at you, OSX 10.5.... */
+ rlim.rlim_cur = OPEN_MAX;
+ if (setrlimit(RLIMIT_NOFILE, &rlim) == 0) {
+ if (rlim.rlim_cur < limit) {
+ log_warn(LD_CONFIG, "We are limited to %lu file descriptors by "
+ "OPEN_MAX, and ConnLimit is %lu. Changing ConnLimit; sorry.",
+ (unsigned long)OPEN_MAX, limit);
+ } else {
+ log_info(LD_CONFIG, "Dropped connection limit to OPEN_MAX (%lu); "
+ "Apparently, %lu was too high and rlimit lied to us.",
+ (unsigned long)OPEN_MAX, (unsigned long)most);
+ }
+ most = rlim.rlim_cur;
+ bad = 0;
+ }
+ }
+#endif
+ if (bad) {
+ log_warn(LD_CONFIG, "Couldn't set maximum number of file descriptors: %s",
+ strerror(errno));
+ return -1;
+ }
}
/* leave some overhead for logs, etc, */
limit = most;