diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/compat.c | 66 | ||||
-rw-r--r-- | src/common/compat.h | 2 |
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 |