aboutsummaryrefslogtreecommitdiff
path: root/src/common/compat.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/compat.h')
-rw-r--r--src/common/compat.h199
1 files changed, 71 insertions, 128 deletions
diff --git a/src/common/compat.h b/src/common/compat.h
index 531e88f1bd..8cf84580c6 100644
--- a/src/common/compat.h
+++ b/src/common/compat.h
@@ -1,26 +1,18 @@
/* Copyright (c) 2003-2004, Roger Dingledine
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2013, The Tor Project, Inc. */
+ * Copyright (c) 2007-2016, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#ifndef TOR_COMPAT_H
#define TOR_COMPAT_H
#include "orconfig.h"
-#include "torint.h"
-#include "testsupport.h"
#ifdef _WIN32
-#ifndef _WIN32_WINNT
-#define _WIN32_WINNT 0x0501
-#endif
-#define WIN32_LEAN_AND_MEAN
-#if defined(_MSC_VER) && (_MSC_VER < 1300)
-#include <winsock.h>
-#else
#include <winsock2.h>
#include <ws2tcpip.h>
#endif
-#endif
+#include "torint.h"
+#include "testsupport.h"
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
@@ -36,9 +28,6 @@
#ifdef HAVE_STRING_H
#include <string.h>
#endif
-#if defined(HAVE_PTHREAD_H) && !defined(_WIN32)
-#include <pthread.h>
-#endif
#include <stdarg.h>
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
@@ -53,24 +42,18 @@
#include <netinet6/in6.h>
#endif
+#if defined(__has_feature)
+# if __has_feature(address_sanitizer)
+/* Some of the fancy glibc strcmp() macros include references to memory that
+ * clang rejects because it is off the end of a less-than-3. Clang hates this,
+ * even though those references never actually happen. */
+# undef strcmp
+# endif
+#endif
+
#include <stdio.h>
#include <errno.h>
-#if defined (WINCE)
-#include <fcntl.h>
-#include <io.h>
-#include <math.h>
-#include <projects.h>
-/* this is not exported as W .... */
-#define SHGetPathFromIDListW SHGetPathFromIDList
-/* wcecompat has vasprintf */
-#define HAVE_VASPRINTF
-/* no service here */
-#ifdef NT_SERVICE
-#undef NT_SERVICE
-#endif
-#endif // WINCE
-
#ifndef NULL_REP_IS_ZERO_BYTES
#error "It seems your platform does not represent NULL as zero. We can't cope."
#endif
@@ -101,20 +84,13 @@
/* inline is __inline on windows. */
#ifdef _WIN32
-#define INLINE __inline
-#else
-#define INLINE inline
+#define inline __inline
#endif
/* Try to get a reasonable __func__ substitute in place. */
#if defined(_MSC_VER)
-/* MSVC compilers before VC7 don't have __func__ at all; later ones call it
- * __FUNCTION__. */
-#if _MSC_VER < 1300
-#define __func__ "???"
-#else
+
#define __func__ __FUNCTION__
-#endif
#else
/* For platforms where autoconf works, make sure __func__ is defined
@@ -130,18 +106,8 @@
#endif /* ifndef MAVE_MACRO__func__ */
#endif /* if not windows */
-#if defined(_MSC_VER) && (_MSC_VER < 1300)
-/* MSVC versions before 7 apparently don't believe that you can cast uint64_t
- * to double and really mean it. */
-extern INLINE double U64_TO_DBL(uint64_t x) {
- int64_t i = (int64_t) x;
- return (i < 0) ? ((double) INT64_MAX) : (double) i;
-}
-#define DBL_TO_U64(x) ((uint64_t)(int64_t) (x))
-#else
#define U64_TO_DBL(x) ((double) (x))
#define DBL_TO_U64(x) ((uint64_t) (x))
-#endif
#ifdef ENUM_VALS_ARE_SIGNED
#define ENUM_BF(t) unsigned
@@ -159,6 +125,7 @@ extern INLINE double U64_TO_DBL(uint64_t x) {
#define ATTR_CONST __attribute__((const))
#define ATTR_MALLOC __attribute__((malloc))
#define ATTR_NORETURN __attribute__((noreturn))
+#define ATTR_WUR __attribute__((warn_unused_result))
/* Alas, nonnull is not at present a good idea for us. We'd like to get
* warnings when we pass NULL where we shouldn't (which nonnull does, albeit
* spottily), but we don't want to tell the compiler to make optimizations
@@ -194,6 +161,7 @@ extern INLINE double U64_TO_DBL(uint64_t x) {
#define ATTR_NORETURN
#define ATTR_NONNULL(x)
#define ATTR_UNUSED
+#define ATTR_WUR
#define PREDICT_LIKELY(exp) (exp)
#define PREDICT_UNLIKELY(exp) (exp)
#endif
@@ -218,6 +186,15 @@ extern INLINE double U64_TO_DBL(uint64_t x) {
#define STMT_END } while (0)
#endif
+/* Some tools (like coccinelle) don't like to see operators as macro
+ * arguments. */
+#define OP_LT <
+#define OP_GT >
+#define OP_GE >=
+#define OP_LE <=
+#define OP_EQ ==
+#define OP_NE !=
+
/* ===== String compatibility */
#ifdef _WIN32
/* Windows names string functions differently from most other platforms. */
@@ -320,7 +297,7 @@ const void *tor_memmem(const void *haystack, size_t hlen, const void *needle,
size_t nlen) ATTR_NONNULL((1,3));
static const void *tor_memstr(const void *haystack, size_t hlen,
const char *needle) ATTR_NONNULL((1,3));
-static INLINE const void *
+static inline const void *
tor_memstr(const void *haystack, size_t hlen, const char *needle)
{
return tor_memmem(haystack, hlen, needle, strlen(needle));
@@ -331,7 +308,7 @@ tor_memstr(const void *haystack, size_t hlen, const char *needle)
#define DECLARE_CTYPE_FN(name) \
static int TOR_##name(char c); \
extern const uint32_t TOR_##name##_TABLE[]; \
- static INLINE int TOR_##name(char c) { \
+ static inline int TOR_##name(char c) { \
uint8_t u = c; \
return !!(TOR_##name##_TABLE[(u >> 5) & 7] & (1u << (u & 31))); \
}
@@ -435,6 +412,9 @@ void tor_lockfile_unlock(tor_lockfile_t *lockfile);
off_t tor_fd_getpos(int fd);
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 "\\"
@@ -471,7 +451,8 @@ int tor_close_socket(tor_socket_t s);
tor_socket_t tor_open_socket_with_extensions(
int domain, int type, int protocol,
int cloexec, int nonblock);
-tor_socket_t tor_open_socket(int domain, int type, int protocol);
+MOCK_DECL(tor_socket_t,
+tor_open_socket,(int domain, int type, int protocol));
tor_socket_t tor_open_socket_nonblocking(int domain, int type, int protocol);
tor_socket_t tor_accept_socket(tor_socket_t sockfd, struct sockaddr *addr,
socklen_t *len);
@@ -482,8 +463,15 @@ tor_socket_t tor_accept_socket_with_extensions(tor_socket_t sockfd,
struct sockaddr *addr,
socklen_t *len,
int cloexec, int nonblock);
+MOCK_DECL(tor_socket_t,
+tor_connect_socket,(tor_socket_t socket,const struct sockaddr *address,
+ socklen_t address_len));
int get_n_open_sockets(void);
+MOCK_DECL(int,
+tor_getsockname,(tor_socket_t socket, struct sockaddr *address,
+ socklen_t *address_len));
+
#define tor_socket_send(s, buf, len, flags) send(s, buf, len, flags)
#define tor_socket_recv(s, buf, len, flags) recv(s, buf, len, flags)
@@ -549,10 +537,11 @@ struct sockaddr_in6 {
};
#endif
+MOCK_DECL(int,tor_gethostname,(char *name, size_t namelen));
int tor_inet_aton(const char *cp, struct in_addr *addr) ATTR_NONNULL((1,2));
const char *tor_inet_ntop(int af, const void *src, char *dst, size_t len);
int tor_inet_pton(int af, const char *src, void *dst);
-int tor_lookup_hostname(const char *name, uint32_t *addr) ATTR_NONNULL((1,2));
+MOCK_DECL(int,tor_lookup_hostname,(const char *name, uint32_t *addr));
int set_socket_nonblocking(tor_socket_t socket);
int tor_socketpair(int family, int type, int protocol, tor_socket_t fd[2]);
int network_init(void);
@@ -579,26 +568,30 @@ int network_init(void);
#define ERRNO_IS_ACCEPT_EAGAIN(e) ERRNO_IS_EAGAIN(e)
/** Return true if e is EMFILE or another error indicating that a call to
* accept() has failed because we're out of fds or something. */
-#define ERRNO_IS_ACCEPT_RESOURCE_LIMIT(e) \
+#define ERRNO_IS_RESOURCE_LIMIT(e) \
((e) == WSAEMFILE || (e) == WSAENOBUFS)
/** Return true if e is EADDRINUSE or the local equivalent. */
#define ERRNO_IS_EADDRINUSE(e) ((e) == WSAEADDRINUSE)
+/** Return true if e is EINTR or the local equivalent */
+#define ERRNO_IS_EINTR(e) ((e) == WSAEINTR || 0)
int tor_socket_errno(tor_socket_t sock);
const char *tor_socket_strerror(int e);
#else
#define SOCK_ERRNO(e) e
#if EAGAIN == EWOULDBLOCK
-#define ERRNO_IS_EAGAIN(e) ((e) == EAGAIN)
+/* || 0 is for -Wparentheses-equality (-Wall?) appeasement under clang */
+#define ERRNO_IS_EAGAIN(e) ((e) == EAGAIN || 0)
#else
#define ERRNO_IS_EAGAIN(e) ((e) == EAGAIN || (e) == EWOULDBLOCK)
#endif
-#define ERRNO_IS_EINPROGRESS(e) ((e) == EINPROGRESS)
-#define ERRNO_IS_CONN_EINPROGRESS(e) ((e) == EINPROGRESS)
+#define ERRNO_IS_EINTR(e) ((e) == EINTR || 0)
+#define ERRNO_IS_EINPROGRESS(e) ((e) == EINPROGRESS || 0)
+#define ERRNO_IS_CONN_EINPROGRESS(e) ((e) == EINPROGRESS || 0)
#define ERRNO_IS_ACCEPT_EAGAIN(e) \
(ERRNO_IS_EAGAIN(e) || (e) == ECONNABORTED)
-#define ERRNO_IS_ACCEPT_RESOURCE_LIMIT(e) \
+#define ERRNO_IS_RESOURCE_LIMIT(e) \
((e) == EMFILE || (e) == ENFILE || (e) == ENOBUFS || (e) == ENOMEM)
-#define ERRNO_IS_EADDRINUSE(e) ((e) == EADDRINUSE)
+#define ERRNO_IS_EADDRINUSE(e) (((e) == EADDRINUSE) || 0)
#define tor_socket_errno(sock) (errno)
#define tor_socket_strerror(e) strerror(e)
#endif
@@ -617,7 +610,7 @@ typedef enum {
} socks5_reply_status_t;
/* ===== OS compatibility */
-const char *get_uname(void);
+MOCK_DECL(const char *, get_uname, (void));
uint16_t get_uint16(const void *cp) ATTR_NONNULL((1));
uint32_t get_uint32(const void *cp) ATTR_NONNULL((1));
@@ -629,7 +622,7 @@ void set_uint64(void *cp, uint64_t v) ATTR_NONNULL((1));
/* These uint8 variants are defined to make the code more uniform. */
#define get_uint8(cp) (*(const uint8_t*)(cp))
static void set_uint8(void *cp, uint8_t v);
-static INLINE void
+static inline void
set_uint8(void *cp, uint8_t v)
{
*(uint8_t*)cp = v;
@@ -638,9 +631,21 @@ set_uint8(void *cp, uint8_t v)
#if !defined(HAVE_RLIM_T)
typedef unsigned long rlim_t;
#endif
+int get_max_sockets(void);
int set_max_file_descriptors(rlim_t limit, int *max);
int tor_disable_debugger_attach(void);
-int switch_id(const char *user);
+
+#if defined(HAVE_SYS_CAPABILITY_H) && defined(HAVE_CAP_SET_PROC)
+#define HAVE_LINUX_CAPABILITIES
+#endif
+
+int have_capability_support(void);
+
+/** Flag for switch_id; see switch_id() for documentation */
+#define SWITCH_ID_KEEP_BINDLOW (1<<0)
+/** Flag for switch_id; see switch_id() for documentation */
+#define SWITCH_ID_WARN_IF_NO_CAPS (1<<1)
+int switch_id(const char *user, unsigned flags);
#ifdef HAVE_PWD_H
char *get_user_homedir(const char *username);
#endif
@@ -657,77 +662,10 @@ char **get_environment(void);
int get_total_system_memory(size_t *mem_out);
-int spawn_func(void (*func)(void *), void *data);
-void spawn_exit(void) ATTR_NORETURN;
-
-#if defined(ENABLE_THREADS) && defined(_WIN32)
-#define USE_WIN32_THREADS
-#define TOR_IS_MULTITHREADED 1
-#elif (defined(ENABLE_THREADS) && defined(HAVE_PTHREAD_H) && \
- defined(HAVE_PTHREAD_CREATE))
-#define USE_PTHREADS
-#define TOR_IS_MULTITHREADED 1
-#else
-#undef TOR_IS_MULTITHREADED
-#endif
-
int compute_num_cpus(void);
-/* Because we use threads instead of processes on most platforms (Windows,
- * Linux, etc), we need locking for them. On platforms with poor thread
- * support or broken gethostbyname_r, these functions are no-ops. */
-
-/** A generic lock structure for multithreaded builds. */
-typedef struct tor_mutex_t {
-#if defined(USE_WIN32_THREADS)
- /** Windows-only: on windows, we implement locks with CRITICAL_SECTIONS. */
- CRITICAL_SECTION mutex;
-#elif defined(USE_PTHREADS)
- /** Pthreads-only: with pthreads, we implement locks with
- * pthread_mutex_t. */
- pthread_mutex_t mutex;
-#else
- /** No-threads only: Dummy variable so that tor_mutex_t takes up space. */
- int _unused;
-#endif
-} tor_mutex_t;
-
int tor_mlockall(void);
-#ifdef TOR_IS_MULTITHREADED
-tor_mutex_t *tor_mutex_new(void);
-void tor_mutex_init(tor_mutex_t *m);
-void tor_mutex_acquire(tor_mutex_t *m);
-void tor_mutex_release(tor_mutex_t *m);
-void tor_mutex_free(tor_mutex_t *m);
-void tor_mutex_uninit(tor_mutex_t *m);
-unsigned long tor_get_thread_id(void);
-void tor_threads_init(void);
-#else
-#define tor_mutex_new() ((tor_mutex_t*)tor_malloc(sizeof(int)))
-#define tor_mutex_init(m) STMT_NIL
-#define tor_mutex_acquire(m) STMT_VOID(m)
-#define tor_mutex_release(m) STMT_NIL
-#define tor_mutex_free(m) STMT_BEGIN tor_free(m); STMT_END
-#define tor_mutex_uninit(m) STMT_NIL
-#define tor_get_thread_id() (1UL)
-#define tor_threads_init() STMT_NIL
-#endif
-
-void set_main_thread(void);
-int in_main_thread(void);
-
-#ifdef TOR_IS_MULTITHREADED
-#if 0
-typedef struct tor_cond_t tor_cond_t;
-tor_cond_t *tor_cond_new(void);
-void tor_cond_free(tor_cond_t *cond);
-int tor_cond_wait(tor_cond_t *cond, tor_mutex_t *mutex);
-void tor_cond_signal_one(tor_cond_t *cond);
-void tor_cond_signal_all(tor_cond_t *cond);
-#endif
-#endif
-
/** Macros for MIN/MAX. Never use these when the arguments could have
* side-effects.
* {With GCC extensions we could probably define a safer MIN/MAX. But
@@ -773,5 +711,10 @@ STATIC int tor_ersatz_socketpair(int family, int type, int protocol,
#endif
#endif
+ssize_t tor_getpass(const char *prompt, char *output, size_t buflen);
+
+/* This needs some of the declarations above so we include it here. */
+#include "compat_threads.h"
+
#endif