diff options
Diffstat (limited to 'src/common/compat.c')
-rw-r--r-- | src/common/compat.c | 103 |
1 files changed, 88 insertions, 15 deletions
diff --git a/src/common/compat.c b/src/common/compat.c index d7ce89479a..c97a4545c9 100644 --- a/src/common/compat.c +++ b/src/common/compat.c @@ -137,8 +137,13 @@ tor_open_cloexec(const char *path, int flags, unsigned mode) fd = open(path, flags, mode); #ifdef FD_CLOEXEC - if (fd >= 0) - fcntl(fd, F_SETFD, FD_CLOEXEC); + if (fd >= 0) { + if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) { + log_warn(LD_FS,"Couldn't set FD_CLOEXEC: %s", strerror(errno)); + close(fd); + return -1; + } + } #endif return fd; } @@ -150,8 +155,13 @@ tor_fopen_cloexec(const char *path, const char *mode) { FILE *result = fopen(path, mode); #ifdef FD_CLOEXEC - if (result != NULL) - fcntl(fileno(result), F_SETFD, FD_CLOEXEC); + if (result != NULL) { + if (fcntl(fileno(result), F_SETFD, FD_CLOEXEC) == -1) { + log_warn(LD_FS,"Couldn't set FD_CLOEXEC: %s", strerror(errno)); + fclose(result); + return NULL; + } + } #endif return result; } @@ -1024,7 +1034,15 @@ tor_open_socket(int domain, int type, int protocol) return s; #if defined(FD_CLOEXEC) - fcntl(s, F_SETFD, FD_CLOEXEC); + if (fcntl(s, F_SETFD, FD_CLOEXEC) == -1) { + log_warn(LD_FS,"Couldn't set FD_CLOEXEC: %s", strerror(errno)); +#if defined(_WIN32) + closesocket(s); +#else + close(s); +#endif + return -1; + } #endif goto socket_ok; /* So that socket_ok will not be unused. */ @@ -1059,7 +1077,11 @@ tor_accept_socket(tor_socket_t sockfd, struct sockaddr *addr, socklen_t *len) return s; #if defined(FD_CLOEXEC) - fcntl(s, F_SETFD, FD_CLOEXEC); + if (fcntl(s, F_SETFD, FD_CLOEXEC) == -1) { + log_warn(LD_NET, "Couldn't set FD_CLOEXEC: %s", strerror(errno)); + close(s); + return TOR_INVALID_SOCKET; + } #endif goto socket_ok; /* So that socket_ok will not be unused. */ @@ -1083,17 +1105,31 @@ get_n_open_sockets(void) return n; } -/** Turn <b>socket</b> into a nonblocking socket. +/** Turn <b>socket</b> into a nonblocking socket. Return 0 on success, -1 + * on failure. */ -void +int set_socket_nonblocking(tor_socket_t socket) { #if defined(_WIN32) unsigned long nonblocking = 1; ioctlsocket(socket, FIONBIO, (unsigned long*) &nonblocking); #else - fcntl(socket, F_SETFL, O_NONBLOCK); + int flags; + + flags = fcntl(socket, F_GETFL, 0); + if (flags == -1) { + log_warn(LD_NET, "Couldn't get file status flags: %s", strerror(errno)); + return -1; + } + flags |= O_NONBLOCK; + if (fcntl(socket, F_SETFL, flags) == -1) { + log_warn(LD_NET, "Couldn't set file status flags: %s", strerror(errno)); + return -1; + } #endif + + return 0; } /** @@ -1136,10 +1172,22 @@ tor_socketpair(int family, int type, int protocol, tor_socket_t fd[2]) return -errno; #if defined(FD_CLOEXEC) - if (SOCKET_OK(fd[0])) - fcntl(fd[0], F_SETFD, FD_CLOEXEC); - if (SOCKET_OK(fd[1])) - fcntl(fd[1], F_SETFD, FD_CLOEXEC); + if (SOCKET_OK(fd[0])) { + r = fcntl(fd[0], F_SETFD, FD_CLOEXEC); + if (r == -1) { + close(fd[0]); + close(fd[1]); + return -errno; + } + } + if (SOCKET_OK(fd[1])) { + r = fcntl(fd[1], F_SETFD, FD_CLOEXEC); + if (r == -1) { + close(fd[0]); + close(fd[1]); + return -errno; + } + } #endif goto sockets_ok; /* So that sockets_ok will not be unused. */ @@ -2265,8 +2313,33 @@ compute_num_cpus_impl(void) return (int)info.dwNumberOfProcessors; else return -1; -#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_CONF) - long cpus = sysconf(_SC_NPROCESSORS_CONF); +#elif defined(HAVE_SYSCONF) +#ifdef _SC_NPROCESSORS_CONF + long cpus_conf = sysconf(_SC_NPROCESSORS_CONF); +#else + long cpus_conf = -1; +#endif +#ifdef _SC_NPROCESSORS_ONLN + long cpus_onln = sysconf(_SC_NPROCESSORS_ONLN); +#else + long cpus_onln = -1; +#endif + long cpus = -1; + + if (cpus_conf > 0 && cpus_onln < 0) { + cpus = cpus_conf; + } else if (cpus_onln > 0 && cpus_conf < 0) { + cpus = cpus_onln; + } else if (cpus_onln > 0 && cpus_conf > 0) { + if (cpus_onln < cpus_conf) { + log_notice(LD_GENERAL, "I think we have %ld CPUS, but only %ld of them " + "are available. Telling Tor to only use %ld. You can over" + "ride this with the NumCPUs option", + cpus_conf, cpus_onln, cpus_onln); + } + cpus = cpus_onln; + } + if (cpus >= 1 && cpus < INT_MAX) return (int)cpus; else |