summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/compat.c66
-rw-r--r--src/common/compat.h2
2 files changed, 60 insertions, 8 deletions
diff --git a/src/common/compat.c b/src/common/compat.c
index 306081754e..76f9bcb97e 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -68,6 +68,9 @@
#ifdef HAVE_CRT_EXTERNS_H
#include <crt_externs.h>
#endif
+#ifdef HAVE_SYS_STATVFS_H
+#include <sys/statvfs.h>
+#endif
#ifdef _WIN32
#include <conio.h>
@@ -1600,15 +1603,23 @@ get_max_sockets(void)
* tell Tor it's allowed to use. */
#define ULIMIT_BUFFER 32 /* keep 32 extra fd's beyond ConnLimit_ */
-/** Learn the maximum allowed number of file descriptors, and tell the system
- * we want to use up to that number. (Some systems have a low soft limit, and
- * let us set it higher.)
+/** Learn the maximum allowed number of file descriptors, and tell the
+ * system we want to use up to that number. (Some systems have a low soft
+ * limit, and let us set it higher.) We compute this by finding the largest
+ * number that we can use.
+ *
+ * If the limit is below the reserved file descriptor value (ULIMIT_BUFFER),
+ * return -1 and <b>max_out</b> is untouched.
+ *
+ * If we can't find a number greater than or equal to <b>limit</b>, then we
+ * fail by returning -1 and <b>max_out</b> is untouched.
*
- * We compute this by finding the largest number that we can use.
- * If we can't find a number greater than or equal to <b>limit</b>,
- * then we fail: return -1.
+ * If we are unable to set the limit value because of setrlimit() failing,
+ * return -1 and <b>max_out</b> is set to the current maximum value returned
+ * by getrlimit().
*
- * Otherwise, return 0 and store the maximum we found inside <b>max_out</b>.*/
+ * Otherwise, return 0 and store the maximum we found inside <b>max_out</b>
+ * and set <b>max_sockets</b> with that value as well.*/
int
set_max_file_descriptors(rlim_t limit, int *max_out)
{
@@ -1665,7 +1676,7 @@ set_max_file_descriptors(rlim_t limit, int *max_out)
}
/* Set the current limit value so if the attempt to set the limit to the
* max fails at least we'll have a valid value of maximum sockets. */
- max_sockets = (int)rlim.rlim_cur - ULIMIT_BUFFER;
+ *max_out = max_sockets = (int)rlim.rlim_cur - ULIMIT_BUFFER;
rlim.rlim_cur = rlim.rlim_max;
if (setrlimit(RLIMIT_NOFILE, &rlim) != 0) {
@@ -3374,3 +3385,42 @@ tor_getpass(const char *prompt, char *output, size_t buflen)
#endif
}
+/** Return the amount of free disk space we have permission to use, in
+ * bytes. Return -1 if the amount of free space can't be determined. */
+int64_t
+tor_get_avail_disk_space(const char *path)
+{
+#ifdef HAVE_STATVFS
+ struct statvfs st;
+ int r;
+ memset(&st, 0, sizeof(st));
+
+ r = statvfs(path, &st);
+ if (r < 0)
+ return -1;
+
+ int64_t result = st.f_bavail;
+ if (st.f_frsize) {
+ result *= st.f_frsize;
+ } else if (st.f_bsize) {
+ result *= st.f_bsize;
+ } else {
+ return -1;
+ }
+
+ return result;
+#elif defined(_WIN32)
+ ULARGE_INTEGER freeBytesAvail;
+ BOOL ok;
+
+ ok = GetDiskFreeSpaceEx(path, &freeBytesAvail, NULL, NULL);
+ if (!ok) {
+ return -1;
+ }
+ return (int64_t)freeBytesAvail.QuadPart;
+#else
+ (void)path;
+ errno = ENOSYS;
+ return -1;
+#endif
+}
diff --git a/src/common/compat.h b/src/common/compat.h
index 3247a59878..d3b18eba92 100644
--- a/src/common/compat.h
+++ b/src/common/compat.h
@@ -405,6 +405,8 @@ int tor_fd_setpos(int fd, off_t pos);
int tor_fd_seekend(int fd);
int tor_ftruncate(int fd);
+int64_t tor_get_avail_disk_space(const char *path);
+
#ifdef _WIN32
#define PATH_SEPARATOR "\\"
#else