summaryrefslogtreecommitdiff
path: root/src/common/compat.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/compat.h')
-rw-r--r--src/common/compat.h132
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);