diff options
Diffstat (limited to 'src/common/compat.h')
-rw-r--r-- | src/common/compat.h | 132 |
1 files changed, 115 insertions, 17 deletions
diff --git a/src/common/compat.h b/src/common/compat.h index c7ed32b0d8..af795ffba9 100644 --- a/src/common/compat.h +++ b/src/common/compat.h @@ -51,6 +51,22 @@ #include <netinet6/in6.h> #endif +#if defined (WINCE) +#include <fcntl.h> +#include <io.h> +#include <math.h> +#include <projects.h> +#define snprintf _snprintf +/* 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 @@ -177,8 +193,8 @@ extern INLINE double U64_TO_DBL(uint64_t x) { /* ===== String compatibility */ #ifdef MS_WINDOWS /* Windows names string functions differently from most other platforms. */ -#define strncasecmp strnicmp -#define strcasecmp stricmp +#define strncasecmp _strnicmp +#define strcasecmp _stricmp #endif #ifndef HAVE_STRLCAT size_t strlcat(char *dst, const char *src, size_t siz) ATTR_NONNULL((1,2)); @@ -196,18 +212,26 @@ size_t strlcpy(char *dst, const char *src, size_t siz) ATTR_NONNULL((1,2)); #define U64_SCANF_ARG(a) (a) /** Expands to a literal uint64_t-typed constant for the value <b>n</b>. */ #define U64_LITERAL(n) (n ## ui64) +#define I64_PRINTF_ARG(a) (a) +#define I64_SCANF_ARG(a) (a) +#define I64_LITERAL(n) (n ## i64) #else #define U64_PRINTF_ARG(a) ((long long unsigned int)(a)) #define U64_SCANF_ARG(a) ((long long unsigned int*)(a)) #define U64_LITERAL(n) (n ## llu) +#define I64_PRINTF_ARG(a) ((long long signed int)(a)) +#define I64_SCANF_ARG(a) ((long long signed int*)(a)) +#define I64_LITERAL(n) (n ## ll) #endif #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__) /** The formatting string used to put a uint64_t value in a printf() or * scanf() function. See also U64_PRINTF_ARG and U64_SCANF_ARG. */ #define U64_FORMAT "%I64u" +#define I64_FORMAT "%I64d" #else #define U64_FORMAT "%llu" +#define I64_FORMAT "%lld" #endif /** Represents an mmaped file. Allocated via tor_mmap_file; freed with @@ -235,6 +259,10 @@ int tor_snprintf(char *str, size_t size, const char *format, ...) int tor_vsnprintf(char *str, size_t size, const char *format, va_list args) ATTR_NONNULL((1,3)); +int tor_asprintf(char **strp, const char *fmt, ...) + CHECK_PRINTF(2,3); +int tor_vasprintf(char **strp, const char *fmt, va_list args); + const void *tor_memmem(const void *haystack, size_t hlen, const void *needle, size_t nlen) ATTR_PURE ATTR_NONNULL((1,3)); static const void *tor_memstr(const void *haystack, size_t hlen, @@ -267,6 +295,13 @@ extern const char TOR_TOLOWER_TABLE[]; #define TOR_TOLOWER(c) (TOR_TOLOWER_TABLE[(uint8_t)c]) #define TOR_TOUPPER(c) (TOR_TOUPPER_TABLE[(uint8_t)c]) +char *tor_strtok_r_impl(char *str, const char *sep, char **lasts); +#ifdef HAVE_STRTOK_R +#define tor_strtok_r(str, sep, lasts) strtok_r(str, sep, lasts) +#else +#define tor_strtok_r(str, sep, lasts) tor_strtok_r_impl(str, sep, lasts) +#endif + #ifdef MS_WINDOWS #define _SHORT_FILE_ (tor_fix_source_file(__FILE__)) const char *tor_fix_source_file(const char *fname); @@ -277,6 +312,7 @@ const char *tor_fix_source_file(const char *fname); /* ===== Time compatibility */ #if !defined(HAVE_GETTIMEOFDAY) && !defined(HAVE_STRUCT_TIMEVAL_TV_SEC) +/** Implementation of timeval for platforms that don't have it. */ struct timeval { time_t tv_sec; unsigned int tv_usec; @@ -285,16 +321,49 @@ struct timeval { void tor_gettimeofday(struct timeval *timeval); -#ifdef HAVE_LOCALTIME_R -#define tor_localtime_r localtime_r -#else struct tm *tor_localtime_r(const time_t *timep, struct tm *result); -#endif - -#ifdef HAVE_GMTIME_R -#define tor_gmtime_r gmtime_r -#else struct tm *tor_gmtime_r(const time_t *timep, struct tm *result); + +#ifndef timeradd +/** Replacement for timeradd on platforms that do not have it: sets tvout to + * the sum of tv1 and tv2. */ +#define timeradd(tv1,tv2,tvout) \ + do { \ + (tvout)->tv_sec = (tv1)->tv_sec + (tv2)->tv_sec; \ + (tvout)->tv_usec = (tv2)->tv_usec + (tv2)->tv_usec; \ + if ((tvout)->tv_usec >= 1000000) { \ + (tvout)->tv_usec -= 1000000; \ + (tvout)->tv_sec++; \ + } \ + } while (0) +#endif + +#ifndef timersub +/** Replacement for timersub on platforms that do not have it: sets tvout to + * tv1 minus tv2. */ +#define timersub(tv1,tv2,tvout) \ + do { \ + (tvout)->tv_sec = (tv1)->tv_sec - (tv2)->tv_sec; \ + (tvout)->tv_usec = (tv2)->tv_usec - (tv2)->tv_usec; \ + if ((tvout)->tv_usec < 0) { \ + (tvout)->tv_usec += 1000000; \ + (tvout)->tv_sec--; \ + } \ + } while (0) +#endif + +#ifndef timercmp +/** Replacement for timersub on platforms that do not have it: returns true + * iff the relational operator "op" makes the expression tv1 op tv2 true. + * + * Note that while this definition should work for all boolean opeators, some + * platforms' native timercmp definitions do not support >=, <=, or ==. So + * don't use those. + */ +#define timercmp(tv1,tv2,op) \ + (((tv1)->tv_sec == (tv2)->tv_sec) ? \ + ((tv1)->tv_usec op (tv2)->tv_usec) : \ + ((tv1)->tv_sec op (tv2)->tv_sec)) #endif /* ===== File compatibility */ @@ -329,9 +398,9 @@ int get_n_open_sockets(void); #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) -/* Define struct in6_addr on platforms that do not have it. Generally, - * these platforms are ones without IPv6 support, but we want to have - * a working in6_addr there anyway, so we can use it to parse IPv6 +/** Implementatino of struct in6_addr for platforms that do not have it. + * Generally, these platforms are ones without IPv6 support, but we want to + * have a working in6_addr there anyway, so we can use it to parse IPv6 * addresses. */ #if !defined(HAVE_STRUCT_IN6_ADDR) struct in6_addr @@ -347,9 +416,10 @@ struct in6_addr }; #endif +/** @{ */ +/** Many BSD variants seem not to define these. */ #if defined(__APPLE__) || defined(__darwin__) || defined(__FreeBSD__) \ || defined(__NetBSD__) || defined(__OpenBSD__) -/* Many BSD variants seem not to define these. */ #ifndef s6_addr16 #define s6_addr16 __u6_addr.__u6_addr16 #endif @@ -357,12 +427,15 @@ struct in6_addr #define s6_addr32 __u6_addr.__u6_addr32 #endif #endif +/** @} */ #ifndef HAVE_SA_FAMILY_T typedef uint16_t sa_family_t; #endif -/* Apparently, MS and Solaris don't define s6_addr16 or s6_addr32. */ +/** @{ */ +/** Apparently, MS and Solaris don't define s6_addr16 or s6_addr32; these + * macros get you a pointer to s6_addr32 or local equivalent. */ #ifdef HAVE_STRUCT_IN6_ADDR_S6_ADDR32 #define S6_ADDR32(x) ((uint32_t*)(x).s6_addr32) #else @@ -373,9 +446,10 @@ typedef uint16_t sa_family_t; #else #define S6_ADDR16(x) ((uint16_t*)((char*)&(x).s6_addr)) #endif +/** @} */ -/* Define struct sockaddr_in6 on platforms that do not have it. See notes - * on struct in6_addr. */ +/** Implementation of struct sockaddr_in6 on platforms that do not have + * it. See notes on struct in6_addr. */ #if !defined(HAVE_STRUCT_SOCKADDR_IN6) struct sockaddr_in6 { sa_family_t sin6_family; @@ -445,6 +519,11 @@ typedef enum { SOCKS5_ADDRESS_TYPE_NOT_SUPPORTED = 0x08, } socks5_reply_status_t; +/* ===== Insecure rng */ +void tor_init_weak_random(unsigned seed); +long tor_weak_random(void); +#define TOR_RAND_MAX (RAND_MAX) + /* ===== OS compatibility */ const char *get_uname(void); @@ -494,14 +573,20 @@ void spawn_exit(void) ATTR_NORETURN; /** 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); @@ -536,6 +621,19 @@ 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 + * depending on that safety would be dangerous, since not every platform + * has it.} + **/ +#ifndef MAX +#define MAX(a,b) ( ((a)<(b)) ? (b) : (a) ) +#endif +#ifndef MIN +#define MIN(a,b) ( ((a)>(b)) ? (b) : (a) ) +#endif + /* Platform-specific helpers. */ #ifdef MS_WINDOWS char *format_win32_error(DWORD err); |