Back to index

tor  0.2.3.18-rc
Classes | Defines | Typedefs | Enumerations | Functions | Variables
compat.h File Reference
#include "orconfig.h"
#include "torint.h"
#include <stdarg.h>
#include <stdio.h>
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  tor_mmap_t
 Represents an mmaped file. More...
struct  timeval
 Implementation of timeval for platforms that don't have it. More...
struct  in6_addr
 Implementation of struct in6_addr for platforms that do not have it. More...
struct  sockaddr_in6
 Implementation of struct sockaddr_in6 on platforms that do not have it. More...
struct  tor_mutex_t
 A generic lock structure for multithreaded builds. More...
union  in6_addr.in6_u

Defines

#define CHECK_PRINTF(formatIdx, firstArg)
#define INLINE   inline
#define __func__   "???"
#define U64_TO_DBL(x)   ((double) (x))
#define DBL_TO_U64(x)   ((uint64_t) (x))
#define ATTR_NORETURN
#define ATTR_CONST
#define ATTR_MALLOC
#define ATTR_NORETURN
#define ATTR_NONNULL(x)
#define PREDICT_LIKELY(exp)   (exp)
#define PREDICT_UNLIKELY(exp)   (exp)
#define STMT_NIL   (void)0
 Expands to a syntactically valid empty statement.
#define STMT_VOID(a)   while (0) { (void)(a); }
 Expands to a syntactically valid empty statement, explicitly (void)ing its argument.
#define STMT_BEGIN   do {
#define STMT_END   } while (0)
#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)
#define U64_FORMAT   "%llu"
#define I64_FORMAT   "%lld"
#define DECLARE_CTYPE_FN(name)
#define TOR_TOLOWER(c)   (TOR_TOLOWER_TABLE[(uint8_t)c])
#define TOR_TOUPPER(c)   (TOR_TOUPPER_TABLE[(uint8_t)c])
#define tor_strtok_r(str, sep, lasts)   tor_strtok_r_impl(str, sep, lasts)
#define _SHORT_FILE_   (__FILE__)
#define tor_fix_source_file(s)   (s)
#define timeradd(tv1, tv2, tvout)
 Replacement for timeradd on platforms that do not have it: sets tvout to the sum of tv1 and tv2.
#define timersub(tv1, tv2, tvout)
 Replacement for timersub on platforms that do not have it: sets tvout to tv1 minus tv2.
#define timercmp(tv1, tv2, op)
 Replacement for timersub on platforms that do not have it: returns true iff the relational operator "op" makes the expression tv1 op tv2 true.
#define PATH_SEPARATOR   "/"
#define tor_socket_t   int
 Type used for a network socket.
#define SOCKET_OK(s)   ((s) >= 0)
 Macro: true iff 's' is a possible value for a valid initialized socket.
#define TOR_INVALID_SOCKET   (-1)
 Error/uninitialized value for a tor_socket_t.
#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 s6_addr   in6_u.u6_addr8
#define s6_addr16   in6_u.u6_addr16
#define s6_addr32   in6_u.u6_addr32
#define ERRNO_IS_EAGAIN(e)   ((e) == EAGAIN)
#define ERRNO_IS_EINPROGRESS(e)   ((e) == EINPROGRESS)
#define ERRNO_IS_CONN_EINPROGRESS(e)   ((e) == EINPROGRESS)
#define ERRNO_IS_ACCEPT_EAGAIN(e)   ((e) == EAGAIN || (e) == ECONNABORTED)
#define ERRNO_IS_ACCEPT_RESOURCE_LIMIT(e)   ((e) == EMFILE || (e) == ENFILE || (e) == ENOBUFS || (e) == ENOMEM)
#define ERRNO_IS_EADDRINUSE(e)   ((e) == EADDRINUSE)
#define tor_socket_errno(sock)   (errno)
#define tor_socket_strerror(e)   strerror(e)
#define TOR_RAND_MAX   (RAND_MAX)
#define get_uint8(cp)   (*(const uint8_t*)(cp))
#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
#define MAX(a, b)   ( ((a)<(b)) ? (b) : (a) )
 Macros for MIN/MAX.
#define MIN(a, b)   ( ((a)>(b)) ? (b) : (a) )
#define S6_ADDR32(x)   ((uint32_t*)((char*)&(x).s6_addr))
 Apparently, MS and Solaris don't define s6_addr16 or s6_addr32; these macros get you a pointer to s6_addr32 or local equivalent.
#define S6_ADDR16(x)   ((uint16_t*)((char*)&(x).s6_addr))

Typedefs

typedef struct tor_mmap_t tor_mmap_t
 Represents an mmaped file.
typedef struct tor_lockfile_t
typedef int socklen_t
typedef uint16_t sa_family_t
 Many BSD variants seem not to define these.
typedef unsigned long rlim_t
typedef struct tor_mutex_t tor_mutex_t
 A generic lock structure for multithreaded builds.

Enumerations

enum  socks5_reply_status_t {
  SOCKS5_SUCCEEDED = 0x00, SOCKS5_GENERAL_ERROR = 0x01, SOCKS5_NOT_ALLOWED = 0x02, SOCKS5_NET_UNREACHABLE = 0x03,
  SOCKS5_HOST_UNREACHABLE = 0x04, SOCKS5_CONNECTION_REFUSED = 0x05, SOCKS5_TTL_EXPIRED = 0x06, SOCKS5_COMMAND_NOT_SUPPORTED = 0x07,
  SOCKS5_ADDRESS_TYPE_NOT_SUPPORTED = 0x08
}
 Specified SOCKS5 status codes. More...

Functions

size_t strlcat (char *dst, const char *src, size_t siz) ATTR_NONNULL((1
size_t size_t strlcpy (char *dst, const char *src, size_t siz) ATTR_NONNULL((1
tor_mmap_ttor_mmap_file (const char *filename) ATTR_NONNULL((1))
void tor_munmap_file (tor_mmap_t *handle) ATTR_NONNULL((1))
int tor_snprintf (char *str, size_t size, const char *format,...) CHECK_PRINTF(3
int ATTR_NONNULL ((1, 3))
int tor_vsnprintf (char *str, size_t size, const char *format, va_list args) CHECK_PRINTF(3
int tor_asprintf (char **strp, const char *fmt,...) CHECK_PRINTF(2
int int tor_vasprintf (char **strp, const char *fmt, va_list args) CHECK_PRINTF(2
int int const void * tor_memmem (const void *haystack, size_t hlen, const void *needle, size_t nlen) ATTR_NONNULL((1
int int const void static
const void * 
tor_memstr (const void *haystack, size_t hlen, const char *needle) ATTR_NONNULL((1
char * tor_strtok_r_impl (char *str, const char *sep, char **lasts)
 Implementation of strtok_r for platforms whose coders haven't figured out how to write one.
void tor_gettimeofday (struct timeval *timeval)
 Set *timeval to the current time of day.
struct tm * tor_localtime_r (const time_t *timep, struct tm *result)
 As localtime_r, but defined for platforms that don't have it:
struct tm * tor_gmtime_r (const time_t *timep, struct tm *result)
 As gmtimee_r, but defined for platforms that don't have it:
int tor_open_cloexec (const char *path, int flags, unsigned mode)
 As open(path, flags, mode), but return an fd with the close-on-exec mode set.
FILE * tor_fopen_cloexec (const char *path, const char *mode)
 As fopen(path,mode), but ensures that the O_CLOEXEC bit is set on the underlying file handle.
int replace_file (const char *from, const char *to)
 Rename the file from to the file to.
int touch_file (const char *fname)
 Change fname's modification time to now.
tor_lockfile_ttor_lockfile_lock (const char *filename, int blocking, int *locked_out)
 Try to get a lock on the lockfile filename, creating it as necessary.
void tor_lockfile_unlock (tor_lockfile_t *lockfile)
 Release the lock held as lockfile.
off_t tor_fd_getpos (int fd)
 Return the position of fd with respect to the start of the file.
int tor_fd_seekend (int fd)
 Move fd to the end of the file.
int tor_close_socket (tor_socket_t s)
 As close(), but guaranteed to work for sockets across platforms (including Windows, where close()ing a socket doesn't work.
tor_socket_t tor_open_socket (int domain, int type, int protocol)
 As socket(), but counts the number of open sockets.
tor_socket_t tor_accept_socket (tor_socket_t sockfd, struct sockaddr *addr, socklen_t *len)
 As socket(), but counts the number of open sockets.
int get_n_open_sockets (void)
 Return the number of sockets we currently have opened.
int tor_inet_aton (const char *cp, struct in_addr *addr) ATTR_NONNULL((1
int const char * tor_inet_ntop (int af, const void *src, char *dst, size_t len)
 Given af==AF_INET and src a struct in_addr, or af==AF_INET6 and src a struct in6_addr, try to format the address and store it in the len-byte buffer dst.
int tor_inet_pton (int af, const char *src, void *dst)
 Given af==AF_INET or af==AF_INET6, and a string src encoding an IPv4 address or IPv6 address correspondingly, try to parse the address and store the result in dst (which must have space for a struct in_addr or a struct in6_addr, as appropriate).
int tor_lookup_hostname (const char *name, uint32_t *addr) ATTR_NONNULL((1
int void set_socket_nonblocking (tor_socket_t socket)
 Turn socket into a nonblocking socket.
int tor_socketpair (int family, int type, int protocol, tor_socket_t fd[2])
 Allocate a pair of connected sockets.
int network_init (void)
 On Windows, WSAEWOULDBLOCK is not always correct: when you see it, you need to ask the socket for its actual errno.
void tor_init_weak_random (unsigned seed)
 Initialize the insecure libc RNG.
long tor_weak_random (void)
 Return a randomly chosen value in the range 0..TOR_RAND_MAX.
const char * get_uname (void)
 Return a pointer to a description of our platform.
uint16_t get_uint16 (const void *cp) ATTR_NONNULL((1))
 Read a 16-bit value beginning at cp.
uint32_t get_uint32 (const void *cp) ATTR_NONNULL((1))
 Read a 32-bit value beginning at cp.
uint64_t get_uint64 (const void *cp) ATTR_NONNULL((1))
 Read a 64-bit value beginning at cp.
void set_uint16 (void *cp, uint16_t v) ATTR_NONNULL((1))
 Set a 16-bit value beginning at cp to v.
void set_uint32 (void *cp, uint32_t v) ATTR_NONNULL((1))
 Set a 32-bit value beginning at cp to v.
void set_uint64 (void *cp, uint64_t v) ATTR_NONNULL((1))
 Set a 64-bit value beginning at cp to v.
static void set_uint8 (void *cp, uint8_t v)
int set_max_file_descriptors (rlim_t limit, int *max)
 Learn the maximum allowed number of file descriptors, and tell the system we want to use up to that number.
int tor_disable_debugger_attach (void)
 Attempt to disable debugger attachment: return 1 on success, -1 on failure, and 0 if we don't know how to try on this platform.
int switch_id (const char *user)
 Call setuid and setgid to run as user and switch to their primary group.
int get_parent_directory (char *fname)
 Modify fname to contain the name of its parent directory.
char * make_path_absolute (char *fname)
 Expand possibly relative path fname to an absolute path.
char ** get_environment (void)
 Return the current environment.
int spawn_func (void(*func)(void *), void *data)
 Minimalist interface to run a void function in the background.
void spawn_exit (void) ATTR_NORETURN
 End the current thread/process.
int compute_num_cpus (void)
 Return how many CPUs we are running with.
int tor_mlockall (void)
 Attempt to lock all current and all future memory pages.
void set_main_thread (void)
 Start considering the current thread to be the 'main thread'.
int in_main_thread (void)
 Return true iff called from the main thread.

Variables

const char TOR_TOUPPER_TABLE []
 Upper-casing and lowercasing tables to map characters to upper/lowercase equivalents.
const char TOR_TOLOWER_TABLE []

Class Documentation

struct tor_mmap_t

Represents an mmaped file.

Allocated via tor_mmap_file; freed with tor_munmap_file.

Definition at line 244 of file compat.h.

Class Members
const char * data Mapping of the file's contents.
size_t size Size of the file.
struct timeval

Implementation of timeval for platforms that don't have it.

Definition at line 321 of file compat.h.

Class Members
time_t tv_sec
unsigned int tv_usec
struct in6_addr

Implementation 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.

Definition at line 431 of file compat.h.

Class Members
union in6_addr in6_u
u8 s6_addr
struct sockaddr_in6

Implementation of struct sockaddr_in6 on platforms that do not have it.

See notes on struct in6_addr.

Definition at line 479 of file compat.h.

Class Members
sa_family_t sin6_family
uint16_t sin6_port
struct tor_mutex_t

A generic lock structure for multithreaded builds.

Definition at line 607 of file compat.h.

Class Members
int _unused No-threads only: Dummy variable so that tor_mutex_t takes up space.
union in6_addr.in6_u

Definition at line 433 of file compat.h.

Class Members
uint16_t u6_addr16
uint32_t u6_addr32
uint8_t u6_addr8

Define Documentation

#define __func__   "???"

Definition at line 117 of file compat.h.

#define _SHORT_FILE_   (__FILE__)

Definition at line 314 of file compat.h.

#define ATTR_CONST

Definition at line 170 of file compat.h.

#define ATTR_MALLOC

Definition at line 171 of file compat.h.

#define ATTR_NONNULL (   x)

Definition at line 173 of file compat.h.

#define ATTR_NORETURN

Definition at line 172 of file compat.h.

#define ATTR_NORETURN

Definition at line 172 of file compat.h.

#define CHECK_PRINTF (   formatIdx,
  firstArg 
)

Definition at line 88 of file compat.h.

#define DBL_TO_U64 (   x)    ((uint64_t) (x))

Definition at line 132 of file compat.h.

#define DECLARE_CTYPE_FN (   name)
Value:
static int TOR_##name(char c);                                        \
  extern const uint32_t TOR_##name##_TABLE[];                           \
  static INLINE int TOR_##name(char c) {                                \
    uint8_t u = c;                                                      \
    return !!(TOR_##name##_TABLE[(u >> 5) & 7] & (1 << (u & 31)));      \
  }

Definition at line 283 of file compat.h.

#define ERRNO_IS_ACCEPT_EAGAIN (   e)    ((e) == EAGAIN || (e) == ECONNABORTED)

Definition at line 526 of file compat.h.

#define ERRNO_IS_ACCEPT_RESOURCE_LIMIT (   e)    ((e) == EMFILE || (e) == ENFILE || (e) == ENOBUFS || (e) == ENOMEM)

Definition at line 527 of file compat.h.

#define ERRNO_IS_CONN_EINPROGRESS (   e)    ((e) == EINPROGRESS)

Definition at line 525 of file compat.h.

#define ERRNO_IS_EADDRINUSE (   e)    ((e) == EADDRINUSE)

Definition at line 529 of file compat.h.

#define ERRNO_IS_EAGAIN (   e)    ((e) == EAGAIN)

Definition at line 523 of file compat.h.

#define ERRNO_IS_EINPROGRESS (   e)    ((e) == EINPROGRESS)

Definition at line 524 of file compat.h.

#define get_uint8 (   cp)    (*(const uint8_t*)(cp))

Definition at line 563 of file compat.h.

#define I64_FORMAT   "%lld"

Definition at line 239 of file compat.h.

#define I64_LITERAL (   n)    (n ## ll)

Definition at line 229 of file compat.h.

#define I64_PRINTF_ARG (   a)    ((long long signed int)(a))

Definition at line 227 of file compat.h.

#define I64_SCANF_ARG (   a)    ((long long signed int*)(a))

Definition at line 228 of file compat.h.

#define INLINE   inline

Definition at line 95 of file compat.h.

#define MAX (   a,
 
)    ( ((a)<(b)) ? (b) : (a) )

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.}

Definition at line 664 of file compat.h.

#define MIN (   a,
 
)    ( ((a)>(b)) ? (b) : (a) )

Definition at line 667 of file compat.h.

#define PATH_SEPARATOR   "/"

Definition at line 392 of file compat.h.

#define PREDICT_LIKELY (   exp)    (exp)

Definition at line 174 of file compat.h.

#define PREDICT_UNLIKELY (   exp)    (exp)

Definition at line 175 of file compat.h.

#define s6_addr   in6_u.u6_addr8

Definition at line 438 of file compat.h.

#define s6_addr16   in6_u.u6_addr16

Definition at line 439 of file compat.h.

#define S6_ADDR16 (   x)    ((uint16_t*)((char*)&(x).s6_addr))

Definition at line 472 of file compat.h.

#define s6_addr32   in6_u.u6_addr32

Definition at line 440 of file compat.h.

#define S6_ADDR32 (   x)    ((uint32_t*)((char*)&(x).s6_addr))

Apparently, MS and Solaris don't define s6_addr16 or s6_addr32; these macros get you a pointer to s6_addr32 or local equivalent.

Definition at line 467 of file compat.h.

#define SOCKET_OK (   s)    ((s) >= 0)

Macro: true iff 's' is a possible value for a valid initialized socket.

Definition at line 412 of file compat.h.

#define STMT_BEGIN   do {

Definition at line 194 of file compat.h.

#define STMT_END   } while (0)

Definition at line 195 of file compat.h.

#define STMT_NIL   (void)0

Expands to a syntactically valid empty statement.

Definition at line 179 of file compat.h.

#define STMT_VOID (   a)    while (0) { (void)(a); }

Expands to a syntactically valid empty statement, explicitly (void)ing its argument.

Definition at line 183 of file compat.h.

#define timeradd (   tv1,
  tv2,
  tvout 
)
Value:
do {                                                  \
    (tvout)->tv_sec = (tv1)->tv_sec + (tv2)->tv_sec;    \
    (tvout)->tv_usec = (tv1)->tv_usec + (tv2)->tv_usec; \
    if ((tvout)->tv_usec >= 1000000) {                  \
      (tvout)->tv_usec -= 1000000;                      \
      (tvout)->tv_sec++;                                \
    }                                                   \
  } while (0)

Replacement for timeradd on platforms that do not have it: sets tvout to the sum of tv1 and tv2.

Definition at line 335 of file compat.h.

#define timercmp (   tv1,
  tv2,
  op 
)
Value:
(((tv1)->tv_sec == (tv2)->tv_sec) ?           \
   ((tv1)->tv_usec op (tv2)->tv_usec) :         \
   ((tv1)->tv_sec op (tv2)->tv_sec))

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.

Definition at line 368 of file compat.h.

#define timersub (   tv1,
  tv2,
  tvout 
)
Value:
do {                                                  \
    (tvout)->tv_sec = (tv1)->tv_sec - (tv2)->tv_sec;    \
    (tvout)->tv_usec = (tv1)->tv_usec - (tv2)->tv_usec; \
    if ((tvout)->tv_usec < 0) {                         \
      (tvout)->tv_usec += 1000000;                      \
      (tvout)->tv_sec--;                                \
    }                                                   \
  } while (0)

Replacement for timersub on platforms that do not have it: sets tvout to tv1 minus tv2.

Definition at line 349 of file compat.h.

#define tor_fix_source_file (   s)    (s)

Definition at line 315 of file compat.h.

#define tor_get_thread_id ( )    (1UL)

Definition at line 639 of file compat.h.

#define TOR_INVALID_SOCKET   (-1)

Error/uninitialized value for a tor_socket_t.

Definition at line 414 of file compat.h.

#define tor_mutex_acquire (   m)    STMT_VOID(m)

Definition at line 635 of file compat.h.

#define tor_mutex_free (   m)    STMT_BEGIN tor_free(m); STMT_END

Definition at line 637 of file compat.h.

#define tor_mutex_init (   m)    STMT_NIL

Definition at line 634 of file compat.h.

#define tor_mutex_new ( )    ((tor_mutex_t*)tor_malloc(sizeof(int)))

Definition at line 633 of file compat.h.

#define tor_mutex_release (   m)    STMT_NIL

Definition at line 636 of file compat.h.

#define tor_mutex_uninit (   m)    STMT_NIL

Definition at line 638 of file compat.h.

#define TOR_RAND_MAX   (RAND_MAX)

Definition at line 550 of file compat.h.

#define tor_socket_errno (   sock)    (errno)

Definition at line 530 of file compat.h.

#define tor_socket_recv (   s,
  buf,
  len,
  flags 
)    recv(s, buf, len, flags)

Definition at line 424 of file compat.h.

#define tor_socket_send (   s,
  buf,
  len,
  flags 
)    send(s, buf, len, flags)

Definition at line 423 of file compat.h.

#define tor_socket_strerror (   e)    strerror(e)

Definition at line 531 of file compat.h.

#define tor_socket_t   int

Type used for a network socket.

Definition at line 410 of file compat.h.

#define tor_strtok_r (   str,
  sep,
  lasts 
)    tor_strtok_r_impl(str, sep, lasts)

Definition at line 307 of file compat.h.

#define tor_threads_init ( )    STMT_NIL

Definition at line 640 of file compat.h.

#define TOR_TOLOWER (   c)    (TOR_TOLOWER_TABLE[(uint8_t)c])

Definition at line 300 of file compat.h.

#define TOR_TOUPPER (   c)    (TOR_TOUPPER_TABLE[(uint8_t)c])

Definition at line 301 of file compat.h.

#define U64_FORMAT   "%llu"

Definition at line 238 of file compat.h.

#define U64_LITERAL (   n)    (n ## llu)

Definition at line 226 of file compat.h.

#define U64_PRINTF_ARG (   a)    ((long long unsigned int)(a))

Definition at line 224 of file compat.h.

#define U64_SCANF_ARG (   a)    ((long long unsigned int*)(a))

Definition at line 225 of file compat.h.

#define U64_TO_DBL (   x)    ((double) (x))

Definition at line 131 of file compat.h.


Typedef Documentation

typedef unsigned long rlim_t

Definition at line 572 of file compat.h.

typedef uint16_t sa_family_t

Many BSD variants seem not to define these.

Definition at line 458 of file compat.h.

typedef int socklen_t

Definition at line 398 of file compat.h.

typedef struct tor_lockfile_t

Definition at line 381 of file compat.h.

typedef struct tor_mmap_t tor_mmap_t

Represents an mmaped file.

Allocated via tor_mmap_file; freed with tor_munmap_file.

typedef struct tor_mutex_t tor_mutex_t

A generic lock structure for multithreaded builds.


Enumeration Type Documentation

Specified SOCKS5 status codes.

Enumerator:
SOCKS5_SUCCEEDED 
SOCKS5_GENERAL_ERROR 
SOCKS5_NOT_ALLOWED 
SOCKS5_NET_UNREACHABLE 
SOCKS5_HOST_UNREACHABLE 
SOCKS5_CONNECTION_REFUSED 
SOCKS5_TTL_EXPIRED 
SOCKS5_COMMAND_NOT_SUPPORTED 
SOCKS5_ADDRESS_TYPE_NOT_SUPPORTED 

Definition at line 535 of file compat.h.


Function Documentation

int ATTR_NONNULL ( (1, 3)  )
int compute_num_cpus ( void  )

Return how many CPUs we are running with.

We assume that nobody is using hot-swappable CPUs, so we don't recompute this after the first time. Return -1 if we don't know how to tell the number of CPUs on this system.

Definition at line 2312 of file compat.c.

{
  static int num_cpus = -2;
  if (num_cpus == -2) {
    num_cpus = compute_num_cpus_impl();
    tor_assert(num_cpus != -2);
    if (num_cpus > MAX_DETECTABLE_CPUS)
      log_notice(LD_GENERAL, "Wow!  I detected that you have %d CPUs. I "
                 "will not autodetect any more than %d, though.  If you "
                 "want to configure more, set NumCPUs in your torrc",
                 num_cpus, MAX_DETECTABLE_CPUS);
  }
  return num_cpus;
}

Here is the call graph for this function:

Here is the caller graph for this function:

char** get_environment ( void  )

Return the current environment.

This is a portable replacement for 'environ'.

Definition at line 1814 of file compat.c.

{
#ifdef HAVE__NSGETENVIRON
  /* This is for compatibility between OSX versions.  Otherwise (for example)
   * when we do a mostly-static build on OSX 10.7, the resulting binary won't
   * work on OSX 10.6. */
  return *_NSGetEnviron();
#else
  return environ;
#endif
}

Here is the caller graph for this function:

int get_n_open_sockets ( void  )

Return the number of sockets we currently have opened.

Definition at line 1078 of file compat.c.

Here is the call graph for this function:

Here is the caller graph for this function:

int get_parent_directory ( char *  fname)

Modify fname to contain the name of its parent directory.

Doesn't actually examine the filesystem; does a purely syntactic modification.

The parent of the root director is considered to be iteself.

Definition at line 1689 of file compat.c.

{
  char *cp;
  int at_end = 1;
  tor_assert(fname);
#ifdef _WIN32
  /* If we start with, say, c:, then don't consider that the start of the path
   */
  if (fname[0] && fname[1] == ':') {
    fname += 2;
  }
#endif
  /* Now we want to remove all path-separators at the end of the string,
   * and to remove the end of the string starting with the path separator
   * before the last non-path-separator.  In perl, this would be
   *   s#[/]*$##; s#/[^/]*$##;
   * on a unixy platform.
   */
  cp = fname + strlen(fname);
  at_end = 1;
  while (--cp >= fname) {
    int is_sep = (*cp == '/'
#ifdef _WIN32
                  || *cp == '\\'
#endif
                  );
    if (is_sep) {
      if (cp == fname) {
        /* This is the first separator in the file name; don't remove it! */
        cp[1] = '\0';
        return 0;
      }
      *cp = '\0';
      if (! at_end)
        return 0;
    } else {
      at_end = 0;
    }
  }
  return -1;
}
uint16_t get_uint16 ( const void *  cp)

Read a 16-bit value beginning at cp.

Equivalent to *(uint16_t*)(cp), but will not cause segfaults on platforms that forbid unaligned memory access.

Definition at line 654 of file compat.c.

{
  uint16_t v;
  memcpy(&v,cp,2);
  return v;
}

Here is the caller graph for this function:

uint32_t get_uint32 ( const void *  cp)

Read a 32-bit value beginning at cp.

Equivalent to *(uint32_t*)(cp), but will not cause segfaults on platforms that forbid unaligned memory access.

Definition at line 666 of file compat.c.

{
  uint32_t v;
  memcpy(&v,cp,4);
  return v;
}

Here is the caller graph for this function:

uint64_t get_uint64 ( const void *  cp)

Read a 64-bit value beginning at cp.

Equivalent to *(uint64_t*)(cp), but will not cause segfaults on platforms that forbid unaligned memory access.

Definition at line 678 of file compat.c.

{
  uint64_t v;
  memcpy(&v,cp,8);
  return v;
}

Here is the caller graph for this function:

const char* get_uname ( void  )

Return a pointer to a description of our platform.

Definition at line 2095 of file compat.c.

{
#ifdef HAVE_UNAME
  struct utsname u;
#endif
  if (!uname_result_is_set) {
#ifdef HAVE_UNAME
    if (uname(&u) != -1) {
      /* (Linux says 0 is success, Solaris says 1 is success) */
      strlcpy(uname_result, u.sysname, sizeof(uname_result));
    } else
#endif
      {
#ifdef _WIN32
        OSVERSIONINFOEX info;
        int i;
        const char *plat = NULL;
        static struct {
          unsigned major; unsigned minor; const char *version;
        } win_version_table[] = {
          { 6, 2, "Windows 8" },
          { 6, 1, "Windows 7" },
          { 6, 0, "Windows Vista" },
          { 5, 2, "Windows Server 2003" },
          { 5, 1, "Windows XP" },
          { 5, 0, "Windows 2000" },
          /* { 4, 0, "Windows NT 4.0" }, */
          { 4, 90, "Windows Me" },
          { 4, 10, "Windows 98" },
          /* { 4, 0, "Windows 95" } */
          { 3, 51, "Windows NT 3.51" },
          { 0, 0, NULL }
        };
        memset(&info, 0, sizeof(info));
        info.dwOSVersionInfoSize = sizeof(info);
        if (! GetVersionEx((LPOSVERSIONINFO)&info)) {
          strlcpy(uname_result, "Bizarre version of Windows where GetVersionEx"
                  " doesn't work.", sizeof(uname_result));
          uname_result_is_set = 1;
          return uname_result;
        }
        if (info.dwMajorVersion == 4 && info.dwMinorVersion == 0) {
          if (info.dwPlatformId == VER_PLATFORM_WIN32_NT)
            plat = "Windows NT 4.0";
          else
            plat = "Windows 95";
        } else {
          for (i=0; win_version_table[i].major>0; ++i) {
            if (win_version_table[i].major == info.dwMajorVersion &&
                win_version_table[i].minor == info.dwMinorVersion) {
              plat = win_version_table[i].version;
              break;
            }
          }
        }
        if (plat) {
          strlcpy(uname_result, plat, sizeof(uname_result));
        } else {
          if (info.dwMajorVersion > 6 ||
              (info.dwMajorVersion==6 && info.dwMinorVersion>2))
            tor_snprintf(uname_result, sizeof(uname_result),
                         "Very recent version of Windows [major=%d,minor=%d]",
                         (int)info.dwMajorVersion,(int)info.dwMinorVersion);
          else
            tor_snprintf(uname_result, sizeof(uname_result),
                         "Unrecognized version of Windows [major=%d,minor=%d]",
                         (int)info.dwMajorVersion,(int)info.dwMinorVersion);
        }
#if !defined (WINCE)
#ifdef VER_NT_SERVER
      if (info.wProductType == VER_NT_SERVER ||
          info.wProductType == VER_NT_DOMAIN_CONTROLLER) {
        strlcat(uname_result, " [server]", sizeof(uname_result));
      }
#endif
#endif
#else
        strlcpy(uname_result, "Unknown platform", sizeof(uname_result));
#endif
      }
    uname_result_is_set = 1;
  }
  return uname_result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int in_main_thread ( void  )

Return true iff called from the main thread.

Definition at line 2912 of file compat.c.

Here is the caller graph for this function:

char* make_path_absolute ( char *  fname)

Expand possibly relative path fname to an absolute path.

Return a newly allocated string, possibly equal to fname.

Definition at line 1767 of file compat.c.

{
#ifdef _WIN32
  char *absfname_malloced = _fullpath(NULL, fname, 1);

  /* We don't want to assume that tor_free can free a string allocated
   * with malloc.  On failure, return fname (it's better than nothing). */
  char *absfname = tor_strdup(absfname_malloced ? absfname_malloced : fname);
  if (absfname_malloced) free(absfname_malloced);

  return absfname;
#else
  char *absfname = NULL, *path = NULL;

  tor_assert(fname);

  if (fname[0] == '/') {
    absfname = tor_strdup(fname);
  } else {
    path = alloc_getcwd();
    if (path) {
      tor_asprintf(&absfname, "%s/%s", path, fname);
      tor_free(path);
    } else {
      /* If getcwd failed, the best we can do here is keep using the
       * relative path.  (Perhaps / isn't readable by this UID/GID.) */
      log_warn(LD_GENERAL, "Unable to find current working directory: %s",
               strerror(errno));
      absfname = tor_strdup(fname);
    }
  }
  return absfname;
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

int network_init ( void  )

On Windows, WSAEWOULDBLOCK is not always correct: when you see it, you need to ask the socket for its actual errno.

Also, you need to get your errors from WSAGetLastError, not errno. (If you supply a socket of -1, we check WSAGetLastError, but don't correct WSAEWOULDBLOCKs.)

The upshot of all of this is that when a socket call fails, you should call tor_socket_errno at most once on the failing socket to get the error. Called before we make any calls to network-related functions. (Some operating systems require their network libraries to be initialized.)

Definition at line 3024 of file compat.c.

{
#ifdef _WIN32
  /* This silly exercise is necessary before windows will allow
   * gethostbyname to work. */
  WSADATA WSAData;
  int r;
  r = WSAStartup(0x101,&WSAData);
  if (r) {
    log_warn(LD_NET,"Error initializing windows network layer: code was %d",r);
    return -1;
  }
  if (sizeof(SOCKET) != sizeof(tor_socket_t)) {
    log_warn(LD_BUG,"The tor_socket_t type does not match SOCKET in size; Tor "
             "might not work. (Sizes are %d and %d respectively.)",
             (int)sizeof(tor_socket_t), (int)sizeof(SOCKET));
  }
  /* WSAData.iMaxSockets might show the max sockets we're allowed to use.
   * We might use it to complain if we're trying to be a server but have
   * too few sockets available. */
#endif
  return 0;
}

Here is the caller graph for this function:

int replace_file ( const char *  from,
const char *  to 
)

Rename the file from to the file to.

On Unix, this is the same as rename(2). On windows, this removes to first if it already exists. Returns 0 on success. Returns -1 and sets errno on failure.

Definition at line 720 of file compat.c.

{
#ifndef _WIN32
  return rename(from,to);
#else
  switch (file_status(to))
    {
    case FN_NOENT:
      break;
    case FN_FILE:
      if (unlink(to)) return -1;
      break;
    case FN_ERROR:
      return -1;
    case FN_DIR:
      errno = EISDIR;
      return -1;
    }
  return rename(from,to);
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

void set_main_thread ( void  )

Start considering the current thread to be the 'main thread'.

This has no effect on anything besides in_main_thread().

Definition at line 2906 of file compat.c.

Here is the caller graph for this function:

int set_max_file_descriptors ( rlim_t  limit,
int *  max_out 
)

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 we can't find a number greater than or equal to limit, then we fail: return -1.

If limit is 0, then do not adjust the current maximum.

Otherwise, return 0 and store the maximum we found inside max_out.

Definition at line 1273 of file compat.c.

{
  /* Define some maximum connections values for systems where we cannot
   * automatically determine a limit. Re Cygwin, see
   * http://archives.seul.org/or/talk/Aug-2006/msg00210.html
   * For an iPhone, 9999 should work. For Windows and all other unknown
   * systems we use 15000 as the default. */
#ifndef HAVE_GETRLIMIT
#if defined(CYGWIN) || defined(__CYGWIN__)
  const char *platform = "Cygwin";
  const unsigned long MAX_CONNECTIONS = 3200;
#elif defined(_WIN32)
  const char *platform = "Windows";
  const unsigned long MAX_CONNECTIONS = 15000;
#else
  const char *platform = "unknown platforms with no getrlimit()";
  const unsigned long MAX_CONNECTIONS = 15000;
#endif
  log_fn(LOG_INFO, LD_NET,
         "This platform is missing getrlimit(). Proceeding.");
  if (limit > MAX_CONNECTIONS) {
    log_warn(LD_CONFIG,
             "We do not support more than %lu file descriptors "
             "on %s. Tried to raise to %lu.",
             (unsigned long)MAX_CONNECTIONS, platform, (unsigned long)limit);
    return -1;
  }
  limit = MAX_CONNECTIONS;
#else /* HAVE_GETRLIMIT */
  struct rlimit rlim;

  if (getrlimit(RLIMIT_NOFILE, &rlim) != 0) {
    log_warn(LD_NET, "Could not get maximum number of file descriptors: %s",
             strerror(errno));
    return -1;
  }
  if (limit == 0) {
    /* If limit == 0, return the maximum value without setting it. */
    limit = rlim.rlim_max;
    if (limit > INT_MAX)
      limit = INT_MAX;
    *max_out = (int)limit - ULIMIT_BUFFER;
    return 0;
  }
  if (rlim.rlim_max < limit) {
    log_warn(LD_CONFIG,"We need %lu file descriptors available, and we're "
             "limited to %lu. Please change your ulimit -n.",
             (unsigned long)limit, (unsigned long)rlim.rlim_max);
    return -1;
  }

  if (rlim.rlim_max > rlim.rlim_cur) {
    log_info(LD_NET,"Raising max file descriptors from %lu to %lu.",
             (unsigned long)rlim.rlim_cur, (unsigned long)rlim.rlim_max);
  }
  rlim.rlim_cur = rlim.rlim_max;

  if (setrlimit(RLIMIT_NOFILE, &rlim) != 0) {
    int bad = 1;
#ifdef OPEN_MAX
    if (errno == EINVAL && OPEN_MAX < rlim.rlim_cur) {
      /* On some platforms, OPEN_MAX is the real limit, and getrlimit() is
       * full of nasty lies.  I'm looking at you, OSX 10.5.... */
      rlim.rlim_cur = OPEN_MAX;
      if (setrlimit(RLIMIT_NOFILE, &rlim) == 0) {
        if (rlim.rlim_cur < (rlim_t)limit) {
          log_warn(LD_CONFIG, "We are limited to %lu file descriptors by "
                 "OPEN_MAX, and ConnLimit is %lu.  Changing ConnLimit; sorry.",
                   (unsigned long)OPEN_MAX, (unsigned long)limit);
        } else {
          log_info(LD_CONFIG, "Dropped connection limit to OPEN_MAX (%lu); "
                   "Apparently, %lu was too high and rlimit lied to us.",
                   (unsigned long)OPEN_MAX, (unsigned long)rlim.rlim_max);
        }
        bad = 0;
      }
    }
#endif /* OPEN_MAX */
    if (bad) {
      log_warn(LD_CONFIG,"Couldn't set maximum number of file descriptors: %s",
               strerror(errno));
      return -1;
    }
  }
  /* leave some overhead for logs, etc, */
  limit = rlim.rlim_cur;
#endif /* HAVE_GETRLIMIT */

  if (limit < ULIMIT_BUFFER) {
    log_warn(LD_CONFIG,
             "ConnLimit must be at least %d. Failing.", ULIMIT_BUFFER);
    return -1;
  }
  if (limit > INT_MAX)
    limit = INT_MAX;
  tor_assert(max_out);
  *max_out = (int)limit - ULIMIT_BUFFER;
  return 0;
}

Here is the caller graph for this function:

int void set_socket_nonblocking ( tor_socket_t  socket)

Turn socket into a nonblocking socket.

Definition at line 1090 of file compat.c.

{
#if defined(_WIN32)
  unsigned long nonblocking = 1;
  ioctlsocket(socket, FIONBIO, (unsigned long*) &nonblocking);
#else
  fcntl(socket, F_SETFL, O_NONBLOCK);
#endif
}

Here is the caller graph for this function:

void set_uint16 ( void *  cp,
uint16_t  v 
)

Set a 16-bit value beginning at cp to v.

Equivalent to *(uint16_t*)(cp) = v, but will not cause segfaults on platforms that forbid unaligned memory access.

Definition at line 690 of file compat.c.

{
  memcpy(cp,&v,2);
}

Here is the caller graph for this function:

void set_uint32 ( void *  cp,
uint32_t  v 
)

Set a 32-bit value beginning at cp to v.

Equivalent to *(uint32_t*)(cp) = v, but will not cause segfaults on platforms that forbid unaligned memory access.

Definition at line 699 of file compat.c.

{
  memcpy(cp,&v,4);
}

Here is the caller graph for this function:

void set_uint64 ( void *  cp,
uint64_t  v 
)

Set a 64-bit value beginning at cp to v.

Equivalent to *(uint64_t*)(cp) = v, but will not cause segfaults on platforms that forbid unaligned memory access.

Definition at line 708 of file compat.c.

{
  memcpy(cp,&v,8);
}

Here is the caller graph for this function:

static INLINE void set_uint8 ( void *  cp,
uint8_t  v 
) [static]

Definition at line 566 of file compat.h.

{
  *(uint8_t*)cp = v;
}

Here is the caller graph for this function:

void spawn_exit ( void  )

End the current thread/process.

Definition at line 2264 of file compat.c.

{
#if defined(USE_WIN32_THREADS)
  _endthread();
  //we should never get here. my compiler thinks that _endthread returns, this
  //is an attempt to fool it.
  tor_assert(0);
  _exit(0);
#elif defined(USE_PTHREADS)
  pthread_exit(NULL);
#else
  /* http://www.erlenstar.demon.co.uk/unix/faq_2.html says we should
   * call _exit, not exit, from child processes. */
  _exit(0);
#endif
}

Here is the caller graph for this function:

int spawn_func ( void(*)(void *)  func,
void *  data 
)

Minimalist interface to run a void function in the background.

On Unix calls fork, on win32 calls beginthread. Returns -1 on failure. func should not return, but rather should call spawn_exit.

NOTE: if data is used, it should not be allocated on the stack, since in a multithreaded environment, there is no way to be sure that the caller's stack will still be around when the called function is running.

Definition at line 2225 of file compat.c.

{
#if defined(USE_WIN32_THREADS)
  int rv;
  rv = (int)_beginthread(func, 0, data);
  if (rv == (int)-1)
    return -1;
  return 0;
#elif defined(USE_PTHREADS)
  pthread_t thread;
  tor_pthread_data_t *d;
  d = tor_malloc(sizeof(tor_pthread_data_t));
  d->data = data;
  d->func = func;
  if (pthread_create(&thread,NULL,tor_pthread_helper_fn,d))
    return -1;
  if (pthread_detach(thread))
    return -1;
  return 0;
#else
  pid_t pid;
  pid = fork();
  if (pid<0)
    return -1;
  if (pid==0) {
    /* Child */
    func(data);
    tor_assert(0); /* Should never reach here. */
    return 0; /* suppress "control-reaches-end-of-non-void" warning. */
  } else {
    /* Parent */
    return 0;
  }
#endif
}

Here is the caller graph for this function:

size_t strlcat ( char *  dst,
const char *  src,
size_t  siz 
)

Here is the caller graph for this function:

size_t size_t strlcpy ( char *  dst,
const char *  src,
size_t  siz 
)
int switch_id ( const char *  user)

Call setuid and setgid to run as user and switch to their primary group.

Return 0 on success. On failure, log and return -1.

Definition at line 1477 of file compat.c.

{
#ifndef _WIN32
  struct passwd *pw = NULL;
  uid_t old_uid;
  gid_t old_gid;
  static int have_already_switched_id = 0;

  tor_assert(user);

  if (have_already_switched_id)
    return 0;

  /* Log the initial credential state */
  if (log_credential_status())
    return -1;

  log_fn(CREDENTIAL_LOG_LEVEL, LD_GENERAL, "Changing user and groups");

  /* Get old UID/GID to check if we changed correctly */
  old_uid = getuid();
  old_gid = getgid();

  /* Lookup the user and group information, if we have a problem, bail out. */
  pw = getpwnam(user);
  if (pw == NULL) {
    log_warn(LD_CONFIG, "Error setting configured user: %s not found", user);
    return -1;
  }

  /* Properly switch egid,gid,euid,uid here or bail out */
  if (setgroups(1, &pw->pw_gid)) {
    log_warn(LD_GENERAL, "Error setting groups to gid %d: \"%s\".",
             (int)pw->pw_gid, strerror(errno));
    if (old_uid == pw->pw_uid) {
      log_warn(LD_GENERAL, "Tor is already running as %s.  You do not need "
               "the \"User\" option if you are already running as the user "
               "you want to be.  (If you did not set the User option in your "
               "torrc, check whether it was specified on the command line "
               "by a startup script.)", user);
    } else {
      log_warn(LD_GENERAL, "If you set the \"User\" option, you must start Tor"
               " as root.");
    }
    return -1;
  }

  if (setegid(pw->pw_gid)) {
    log_warn(LD_GENERAL, "Error setting egid to %d: %s",
             (int)pw->pw_gid, strerror(errno));
    return -1;
  }

  if (setgid(pw->pw_gid)) {
    log_warn(LD_GENERAL, "Error setting gid to %d: %s",
             (int)pw->pw_gid, strerror(errno));
    return -1;
  }

  if (setuid(pw->pw_uid)) {
    log_warn(LD_GENERAL, "Error setting configured uid to %s (%d): %s",
             user, (int)pw->pw_uid, strerror(errno));
    return -1;
  }

  if (seteuid(pw->pw_uid)) {
    log_warn(LD_GENERAL, "Error setting configured euid to %s (%d): %s",
             user, (int)pw->pw_uid, strerror(errno));
    return -1;
  }

  /* This is how OpenBSD rolls:
  if (setgroups(1, &pw->pw_gid) || setegid(pw->pw_gid) ||
      setgid(pw->pw_gid) || setuid(pw->pw_uid) || seteuid(pw->pw_uid)) {
      setgid(pw->pw_gid) || seteuid(pw->pw_uid) || setuid(pw->pw_uid)) {
    log_warn(LD_GENERAL, "Error setting configured UID/GID: %s",
    strerror(errno));
    return -1;
  }
  */

  /* We've properly switched egid, gid, euid, uid, and supplementary groups if
   * we're here. */

#if !defined(CYGWIN) && !defined(__CYGWIN__)
  /* If we tried to drop privilege to a group/user other than root, attempt to
   * restore root (E)(U|G)ID, and abort if the operation succeeds */

  /* Only check for privilege dropping if we were asked to be non-root */
  if (pw->pw_uid) {
    /* Try changing GID/EGID */
    if (pw->pw_gid != old_gid &&
        (setgid(old_gid) != -1 || setegid(old_gid) != -1)) {
      log_warn(LD_GENERAL, "Was able to restore group credentials even after "
               "switching GID: this means that the setgid code didn't work.");
      return -1;
    }

    /* Try changing UID/EUID */
    if (pw->pw_uid != old_uid &&
        (setuid(old_uid) != -1 || seteuid(old_uid) != -1)) {
      log_warn(LD_GENERAL, "Was able to restore user credentials even after "
               "switching UID: this means that the setuid code didn't work.");
      return -1;
    }
  }
#endif

  /* Check what really happened */
  if (log_credential_status()) {
    return -1;
  }

  have_already_switched_id = 1; /* mark success so we never try again */

#if defined(__linux__) && defined(HAVE_SYS_PRCTL_H) && defined(HAVE_PRCTL)
#ifdef PR_SET_DUMPABLE
  if (pw->pw_uid) {
    /* Re-enable core dumps if we're not running as root. */
    log_info(LD_CONFIG, "Re-enabling coredumps");
    if (prctl(PR_SET_DUMPABLE, 1)) {
      log_warn(LD_CONFIG, "Unable to re-enable coredumps: %s",strerror(errno));
    }
  }
#endif
#endif
  return 0;

#else
  (void)user;

  log_warn(LD_CONFIG,
           "User specified but switching users is unsupported on your OS.");
  return -1;
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

tor_socket_t tor_accept_socket ( tor_socket_t  sockfd,
struct sockaddr *  addr,
socklen_t len 
)

As socket(), but counts the number of open sockets.

Definition at line 1043 of file compat.c.

{
  tor_socket_t s;
#if defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC)
  s = accept4(sockfd, addr, len, SOCK_CLOEXEC);
  if (SOCKET_OK(s))
    goto socket_ok;
  /* If we got an error, see if it is ENOSYS. ENOSYS indicates that,
   * even though we were built on a system with accept4 support, we
   * are running on one without. Also, check for EINVAL, which indicates that
   * we are missing SOCK_CLOEXEC support. */
  if (errno != EINVAL && errno != ENOSYS)
    return s;
#endif

  s = accept(sockfd, addr, len);
  if (!SOCKET_OK(s))
    return s;

#if defined(FD_CLOEXEC)
  fcntl(s, F_SETFD, FD_CLOEXEC);
#endif

  goto socket_ok; /* So that socket_ok will not be unused. */

 socket_ok:
  socket_accounting_lock();
  ++n_sockets_open;
  mark_socket_open(s);
  socket_accounting_unlock();
  return s;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int tor_asprintf ( char **  strp,
const char *  fmt,
  ... 
)

As close(), but guaranteed to work for sockets across platforms (including Windows, where close()ing a socket doesn't work.

Returns 0 on success, -1 on failure.

Definition at line 930 of file compat.c.

{
  int r = 0;

  /* On Windows, you have to call close() on fds returned by open(),
   * and closesocket() on fds returned by socket().  On Unix, everything
   * gets close()'d.  We abstract this difference by always using
   * tor_close_socket to close sockets, and always using close() on
   * files.
   */
#if defined(_WIN32)
  r = closesocket(s);
#else
  r = close(s);
#endif

  socket_accounting_lock();
#ifdef DEBUG_SOCKET_COUNTING
  if (s > max_socket || ! bitarray_is_set(open_sockets, s)) {
    log_warn(LD_BUG, "Closing a socket (%d) that wasn't returned by tor_open_"
             "socket(), or that was already closed or something.", s);
  } else {
    tor_assert(open_sockets && s <= max_socket);
    bitarray_clear(open_sockets, s);
  }
#endif
  if (r == 0) {
    --n_sockets_open;
  } else {
    int err = tor_socket_errno(-1);
    log_info(LD_NET, "Close returned an error: %s", tor_socket_strerror(err));
#ifdef _WIN32
    if (err != WSAENOTSOCK)
      --n_sockets_open;
#else
    if (err != EBADF)
      --n_sockets_open;
#endif
    r = -1;
  }

  if (n_sockets_open < 0)
    log_warn(LD_BUG, "Our socket count is below zero: %d. Please submit a "
             "bug report.", n_sockets_open);
  socket_accounting_unlock();
  return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Attempt to disable debugger attachment: return 1 on success, -1 on failure, and 0 if we don't know how to try on this platform.

Definition at line 1632 of file compat.c.

{
  int r, attempted;
  r = -1;
  attempted = 0;
  log_debug(LD_CONFIG,
            "Attemping to disable debugger attachment to Tor for "
            "unprivileged users.");
#if defined(__linux__) && defined(HAVE_SYS_PRCTL_H) && defined(HAVE_PRCTL)
#ifdef PR_SET_DUMPABLE
  attempted = 1;
  r = prctl(PR_SET_DUMPABLE, 0);
#endif
#endif
#if defined(__APPLE__) && defined(PT_DENY_ATTACH)
  if (r < 0) {
    attempted = 1;
    r = ptrace(PT_DENY_ATTACH, 0, 0, 0);
  }
#endif

  // XXX: TODO - Mac OS X has dtrace and this may be disabled.
  // XXX: TODO - Windows probably has something similar
  if (r == 0 && attempted) {
    log_debug(LD_CONFIG,"Debugger attachment disabled for "
              "unprivileged users.");
    return 1;
  } else if (attempted) {
    log_warn(LD_CONFIG, "Unable to disable debugger attaching: %s",
             strerror(errno));
  }
  return r;
}

Here is the caller graph for this function:

off_t tor_fd_getpos ( int  fd)

Return the position of fd with respect to the start of the file.

Definition at line 874 of file compat.c.

{
#ifdef _WIN32
  return (off_t) _lseek(fd, 0, SEEK_CUR);
#else
  return (off_t) lseek(fd, 0, SEEK_CUR);
#endif
}

Here is the caller graph for this function:

int tor_fd_seekend ( int  fd)

Move fd to the end of the file.

Return -1 on error, 0 on success.

Definition at line 885 of file compat.c.

{
#ifdef _WIN32
  return _lseek(fd, 0, SEEK_END) < 0 ? -1 : 0;
#else
  return lseek(fd, 0, SEEK_END) < 0 ? -1 : 0;
#endif
}

Here is the caller graph for this function:

FILE* tor_fopen_cloexec ( const char *  path,
const char *  mode 
)

As fopen(path,mode), but ensures that the O_CLOEXEC bit is set on the underlying file handle.

Definition at line 149 of file compat.c.

{
  FILE *result = fopen(path, mode);
#ifdef FD_CLOEXEC
  if (result != NULL)
    fcntl(fileno(result), F_SETFD, FD_CLOEXEC);
#endif
  return result;
}

Here is the caller graph for this function:

void tor_gettimeofday ( struct timeval timeval)

Set *timeval to the current time of day.

On error, log and terminate. (Same as gettimeofday(timeval,NULL), but never returns -1.)

Definition at line 2331 of file compat.c.

{
#ifdef _WIN32
  /* Epoch bias copied from perl: number of units between windows epoch and
   * Unix epoch. */
#define EPOCH_BIAS U64_LITERAL(116444736000000000)
#define UNITS_PER_SEC U64_LITERAL(10000000)
#define USEC_PER_SEC U64_LITERAL(1000000)
#define UNITS_PER_USEC U64_LITERAL(10)
  union {
    uint64_t ft_64;
    FILETIME ft_ft;
  } ft;
#if defined (WINCE)
  /* wince do not have GetSystemTimeAsFileTime */
  SYSTEMTIME stime;
  GetSystemTime(&stime);
  SystemTimeToFileTime(&stime,&ft.ft_ft);
#else
  /* number of 100-nsec units since Jan 1, 1601 */
  GetSystemTimeAsFileTime(&ft.ft_ft);
#endif
  if (ft.ft_64 < EPOCH_BIAS) {
    log_err(LD_GENERAL,"System time is before 1970; failing.");
    exit(1);
  }
  ft.ft_64 -= EPOCH_BIAS;
  timeval->tv_sec = (unsigned) (ft.ft_64 / UNITS_PER_SEC);
  timeval->tv_usec = (unsigned) ((ft.ft_64 / UNITS_PER_USEC) % USEC_PER_SEC);
#elif defined(HAVE_GETTIMEOFDAY)
  if (gettimeofday(timeval, NULL)) {
    log_err(LD_GENERAL,"gettimeofday failed.");
    /* If gettimeofday dies, we have either given a bad timezone (we didn't),
       or segfaulted.*/
    exit(1);
  }
#elif defined(HAVE_FTIME)
  struct timeb tb;
  ftime(&tb);
  timeval->tv_sec = tb.time;
  timeval->tv_usec = tb.millitm * 1000;
#else
#error "No way to get time."
#endif
  return;
}

Here is the caller graph for this function:

struct tm* tor_gmtime_r ( const time_t *  timep,
struct tm *  result 
) [read]

As gmtimee_r, but defined for platforms that don't have it:

Convert *timep to a struct tm in UTC, and store the value in *result. Return the result on success, or NULL on failure.

Definition at line 2530 of file compat.c.

{
  struct tm *r;
  tor_assert(result);
  r = gmtime(timep);
  if (r)
    memcpy(result, r, sizeof(struct tm));
  return correct_tm(0, timep, result, r);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int tor_inet_aton ( const char *  cp,
struct in_addr *  addr 
)
int const char* tor_inet_ntop ( int  af,
const void *  src,
char *  dst,
size_t  len 
)

Given af==AF_INET and src a struct in_addr, or af==AF_INET6 and src a struct in6_addr, try to format the address and store it in the len-byte buffer dst.

Returns dst on success, NULL on failure.

(Like inet_ntop(af,src,dst,len), but works on platforms that don't have it: Tor sometimes needs to format ipv6 addresses even on platforms without ipv6 support.)

Definition at line 1854 of file compat.c.

{
  if (af == AF_INET) {
    if (tor_inet_ntoa(src, dst, len) < 0)
      return NULL;
    else
      return dst;
  } else if (af == AF_INET6) {
    const struct in6_addr *addr = src;
    char buf[64], *cp;
    int longestGapLen = 0, longestGapPos = -1, i,
      curGapPos = -1, curGapLen = 0;
    uint16_t words[8];
    for (i = 0; i < 8; ++i) {
      words[i] = (((uint16_t)addr->s6_addr[2*i])<<8) + addr->s6_addr[2*i+1];
    }
    if (words[0] == 0 && words[1] == 0 && words[2] == 0 && words[3] == 0 &&
        words[4] == 0 && ((words[5] == 0 && words[6] && words[7]) ||
                          (words[5] == 0xffff))) {
      /* This is an IPv4 address. */
      if (words[5] == 0) {
        tor_snprintf(buf, sizeof(buf), "::%d.%d.%d.%d",
                     addr->s6_addr[12], addr->s6_addr[13],
                     addr->s6_addr[14], addr->s6_addr[15]);
      } else {
        tor_snprintf(buf, sizeof(buf), "::%x:%d.%d.%d.%d", words[5],
                     addr->s6_addr[12], addr->s6_addr[13],
                     addr->s6_addr[14], addr->s6_addr[15]);
      }
      if ((strlen(buf) + 1) > len) /* +1 for \0 */
        return NULL;
      strlcpy(dst, buf, len);
      return dst;
    }
    i = 0;
    while (i < 8) {
      if (words[i] == 0) {
        curGapPos = i++;
        curGapLen = 1;
        while (i<8 && words[i] == 0) {
          ++i; ++curGapLen;
        }
        if (curGapLen > longestGapLen) {
          longestGapPos = curGapPos;
          longestGapLen = curGapLen;
        }
      } else {
        ++i;
      }
    }
    if (longestGapLen<=1)
      longestGapPos = -1;

    cp = buf;
    for (i = 0; i < 8; ++i) {
      if (words[i] == 0 && longestGapPos == i) {
        if (i == 0)
          *cp++ = ':';
        *cp++ = ':';
        while (i < 8 && words[i] == 0)
          ++i;
        --i; /* to compensate for loop increment. */
      } else {
        tor_snprintf(cp, sizeof(buf)-(cp-buf), "%x", (unsigned)words[i]);
        cp += strlen(cp);
        if (i != 7)
          *cp++ = ':';
      }
    }
    *cp = '\0';
    if ((strlen(buf) + 1) > len) /* +1 for \0 */
      return NULL;
    strlcpy(dst, buf, len);
    return dst;
  } else {
    return NULL;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

int tor_inet_pton ( int  af,
const char *  src,
void *  dst 
)

Given af==AF_INET or af==AF_INET6, and a string src encoding an IPv4 address or IPv6 address correspondingly, try to parse the address and store the result in dst (which must have space for a struct in_addr or a struct in6_addr, as appropriate).

Return 1 on success, 0 on a bad parse, and -1 on a bad af.

(Like inet_pton(af,src,dst) but works on platforms that don't have it: Tor sometimes needs to format ipv6 addresses even on platforms without ipv6 support.)

Definition at line 1943 of file compat.c.

{
  if (af == AF_INET) {
    return tor_inet_aton(src, dst);
  } else if (af == AF_INET6) {
    struct in6_addr *out = dst;
    uint16_t words[8];
    int gapPos = -1, i, setWords=0;
    const char *dot = strchr(src, '.');
    const char *eow; /* end of words. */
    if (dot == src)
      return 0;
    else if (!dot)
      eow = src+strlen(src);
    else {
      unsigned byte1,byte2,byte3,byte4;
      char more;
      for (eow = dot-1; eow >= src && TOR_ISDIGIT(*eow); --eow)
        ;
      ++eow;

      /* We use "scanf" because some platform inet_aton()s are too lax
       * about IPv4 addresses of the form "1.2.3" */
      if (tor_sscanf(eow, "%3u.%3u.%3u.%3u%c",
                     &byte1,&byte2,&byte3,&byte4,&more) != 4)
        return 0;

      if (byte1 > 255 || byte2 > 255 || byte3 > 255 || byte4 > 255)
        return 0;

      words[6] = (byte1<<8) | byte2;
      words[7] = (byte3<<8) | byte4;
      setWords += 2;
    }

    i = 0;
    while (src < eow) {
      if (i > 7)
        return 0;
      if (TOR_ISXDIGIT(*src)) {
        char *next;
        ssize_t len;
        long r = strtol(src, &next, 16);
        tor_assert(next != NULL);
        tor_assert(next != src);

        len = *next == '\0' ? eow - src : next - src;
        if (len > 4)
          return 0;
        if (len > 1 && !TOR_ISXDIGIT(src[1]))
          return 0; /* 0x is not valid */

        tor_assert(r >= 0);
        tor_assert(r < 65536);
        words[i++] = (uint16_t)r;
        setWords++;
        src = next;
        if (*src != ':' && src != eow)
          return 0;
        ++src;
      } else if (*src == ':' && i > 0 && gapPos == -1) {
        gapPos = i;
        ++src;
      } else if (*src == ':' && i == 0 && src+1 < eow && src[1] == ':' &&
                 gapPos == -1) {
        gapPos = i;
        src += 2;
      } else {
        return 0;
      }
    }

    if (setWords > 8 ||
        (setWords == 8 && gapPos != -1) ||
        (setWords < 8 && gapPos == -1))
      return 0;

    if (gapPos >= 0) {
      int nToMove = setWords - (dot ? 2 : 0) - gapPos;
      int gapLen = 8 - setWords;
      tor_assert(nToMove >= 0);
      memmove(&words[gapPos+gapLen], &words[gapPos],
              sizeof(uint16_t)*nToMove);
      memset(&words[gapPos], 0, sizeof(uint16_t)*gapLen);
    }
    for (i = 0; i < 8; ++i) {
      out->s6_addr[2*i  ] = words[i] >> 8;
      out->s6_addr[2*i+1] = words[i] & 0xff;
    }

    return 1;
  } else {
    return -1;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void tor_init_weak_random ( unsigned  seed)

Initialize the insecure libc RNG.

Definition at line 2065 of file compat.c.

{
#ifdef _WIN32
  srand(seed);
#else
  srandom(seed);
#endif
}

Here is the caller graph for this function:

struct tm* tor_localtime_r ( const time_t *  timep,
struct tm *  result 
) [read]

As localtime_r, but defined for platforms that don't have it:

Convert *timep to a struct tm in local time, and store the value in *result. Return the result on success, or NULL on failure.

Definition at line 2487 of file compat.c.

{
  struct tm *r;
  tor_assert(result);
  r = localtime(timep);
  if (r)
    memcpy(result, r, sizeof(struct tm));
  return correct_tm(1, timep, result, r);
}

Here is the call graph for this function:

Here is the caller graph for this function:

tor_lockfile_t* tor_lockfile_lock ( const char *  filename,
int  blocking,
int *  locked_out 
)

Try to get a lock on the lockfile filename, creating it as necessary.

If someone else has the lock and blocking is true, wait until the lock is available. Otherwise return immediately whether we succeeded or not.

Set *locked_out to true if somebody else had the lock, and to false otherwise.

Return a tor_lockfile_t on success, NULL on failure.

(Implementation note: because we need to fall back to fcntl on some platforms, these locks are per-process, not per-thread. If you want to do in-process locking, use tor_mutex_t like a normal person. On Windows, when blocking is true, the maximum time that is actually waited is 10 seconds, after which NULL is returned and locked_out is set to 1.)

Definition at line 777 of file compat.c.

{
  tor_lockfile_t *result;
  int fd;
  *locked_out = 0;

  log_info(LD_FS, "Locking \"%s\"", filename);
  fd = tor_open_cloexec(filename, O_RDWR|O_CREAT|O_TRUNC, 0600);
  if (fd < 0) {
    log_warn(LD_FS,"Couldn't open \"%s\" for locking: %s", filename,
             strerror(errno));
    return NULL;
  }

#ifdef _WIN32
  _lseek(fd, 0, SEEK_SET);
  if (_locking(fd, blocking ? _LK_LOCK : _LK_NBLCK, 1) < 0) {
    if (errno != EACCES && errno != EDEADLOCK)
      log_warn(LD_FS,"Couldn't lock \"%s\": %s", filename, strerror(errno));
    else
      *locked_out = 1;
    close(fd);
    return NULL;
  }
#elif defined(HAVE_FLOCK)
  if (flock(fd, LOCK_EX|(blocking ? 0 : LOCK_NB)) < 0) {
    if (errno != EWOULDBLOCK)
      log_warn(LD_FS,"Couldn't lock \"%s\": %s", filename, strerror(errno));
    else
      *locked_out = 1;
    close(fd);
    return NULL;
  }
#else
  {
    struct flock lock;
    memset(&lock, 0, sizeof(lock));
    lock.l_type = F_WRLCK;
    lock.l_whence = SEEK_SET;
    if (fcntl(fd, blocking ? F_SETLKW : F_SETLK, &lock) < 0) {
      if (errno != EACCES && errno != EAGAIN)
        log_warn(LD_FS, "Couldn't lock \"%s\": %s", filename, strerror(errno));
      else
        *locked_out = 1;
      close(fd);
      return NULL;
    }
  }
#endif

  result = tor_malloc(sizeof(tor_lockfile_t));
  result->filename = tor_strdup(filename);
  result->fd = fd;
  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void tor_lockfile_unlock ( tor_lockfile_t lockfile)

Release the lock held as lockfile.

Definition at line 835 of file compat.c.

{
  tor_assert(lockfile);

  log_info(LD_FS, "Unlocking \"%s\"", lockfile->filename);
#ifdef _WIN32
  _lseek(lockfile->fd, 0, SEEK_SET);
  if (_locking(lockfile->fd, _LK_UNLCK, 1) < 0) {
    log_warn(LD_FS,"Error unlocking \"%s\": %s", lockfile->filename,
             strerror(errno));
  }
#elif defined(HAVE_FLOCK)
  if (flock(lockfile->fd, LOCK_UN) < 0) {
    log_warn(LD_FS, "Error unlocking \"%s\": %s", lockfile->filename,
             strerror(errno));
  }
#else
  /* Closing the lockfile is sufficient. */
#endif

  close(lockfile->fd);
  lockfile->fd = -1;
  tor_free(lockfile->filename);
  tor_free(lockfile);
}

Here is the caller graph for this function:

int tor_lookup_hostname ( const char *  name,
uint32_t *  addr 
)
int int const void* tor_memmem ( const void *  haystack,
size_t  hlen,
const void *  needle,
size_t  nlen 
)
int int const void static const void static INLINE const void * tor_memstr ( const void *  haystack,
size_t  hlen,
const char *  needle 
) [static]

Definition at line 276 of file compat.h.

{
  return tor_memmem(haystack, hlen, needle, strlen(needle));
}

Here is the call graph for this function:

Here is the caller graph for this function:

int tor_mlockall ( void  )

Attempt to lock all current and all future memory pages.

This should only be called once and while we're privileged. Like mlockall() we return 0 when we're successful and -1 when we're not. Unlike mlockall() we return 1 if we've already attempted to lock memory.

Definition at line 2856 of file compat.c.

{
  static int memory_lock_attempted = 0;

  if (memory_lock_attempted) {
    return 1;
  }

  memory_lock_attempted = 1;

  /*
   * Future consideration for Windows may be VirtualLock
   * VirtualLock appears to implement mlock() but not mlockall()
   *
   * http://msdn.microsoft.com/en-us/library/aa366895(VS.85).aspx
   */

#if defined(HAVE_MLOCKALL) && HAVE_DECL_MLOCKALL && defined(RLIMIT_MEMLOCK)
  if (tor_set_max_memlock() == 0) {
    log_debug(LD_GENERAL, "RLIMIT_MEMLOCK is now set to RLIM_INFINITY.");
  }

  if (mlockall(MCL_CURRENT|MCL_FUTURE) == 0) {
    log_info(LD_GENERAL, "Insecure OS paging is effectively disabled.");
    return 0;
  } else {
    if (errno == ENOSYS) {
      /* Apple - it's 2009! I'm looking at you. Grrr. */
      log_notice(LD_GENERAL, "It appears that mlockall() is not available on "
                             "your platform.");
    } else if (errno == EPERM) {
      log_notice(LD_GENERAL, "It appears that you lack the permissions to "
                             "lock memory. Are you root?");
    }
    log_notice(LD_GENERAL, "Unable to lock all current and future memory "
                           "pages: %s", strerror(errno));
    return -1;
  }
#else
  log_warn(LD_GENERAL, "Unable to lock memory pages. mlockall() unsupported?");
  return -1;
#endif
}

Here is the caller graph for this function:

tor_mmap_t* tor_mmap_file ( const char *  filename)

Definition at line 318 of file compat.c.

{
  struct stat st;
  char *res = read_file_to_str(filename, RFTS_BIN|RFTS_IGNORE_MISSING, &st);
  tor_mmap_t *handle;
  if (! res)
    return NULL;
  handle = tor_malloc_zero(sizeof(tor_mmap_t));
  handle->data = res;
  handle->size = st.st_size;
  return handle;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void tor_munmap_file ( tor_mmap_t handle)

Definition at line 331 of file compat.c.

{
  char *d = (char*)handle->data;
  tor_free(d);
  memset(handle, 0, sizeof(tor_mmap_t));
  tor_free(handle);
}

Here is the caller graph for this function:

int tor_open_cloexec ( const char *  path,
int  flags,
unsigned  mode 
)

As open(path, flags, mode), but return an fd with the close-on-exec mode set.

Definition at line 124 of file compat.c.

{
  int fd;
#ifdef O_CLOEXEC
  fd = open(path, flags|O_CLOEXEC, mode);
  if (fd >= 0)
    return fd;
  /* If we got an error, see if it is EINVAL. EINVAL might indicate that,
   * even though we were built on a system with O_CLOEXEC support, we
   * are running on one without. */
  if (errno != EINVAL)
    return -1;
#endif

  fd = open(path, flags, mode);
#ifdef FD_CLOEXEC
  if (fd >= 0)
        fcntl(fd, F_SETFD, FD_CLOEXEC);
#endif
  return fd;
}

Here is the caller graph for this function:

tor_socket_t tor_open_socket ( int  domain,
int  type,
int  protocol 
)

As socket(), but counts the number of open sockets.

Definition at line 1009 of file compat.c.

{
  tor_socket_t s;
#ifdef SOCK_CLOEXEC
  s = socket(domain, type|SOCK_CLOEXEC, protocol);
  if (SOCKET_OK(s))
    goto socket_ok;
  /* If we got an error, see if it is EINVAL. EINVAL might indicate that,
   * even though we were built on a system with SOCK_CLOEXEC support, we
   * are running on one without. */
  if (errno != EINVAL)
    return s;
#endif /* SOCK_CLOEXEC */

  s = socket(domain, type, protocol);
  if (! SOCKET_OK(s))
    return s;

#if defined(FD_CLOEXEC)
  fcntl(s, F_SETFD, FD_CLOEXEC);
#endif

  goto socket_ok; /* So that socket_ok will not be unused. */

 socket_ok:
  socket_accounting_lock();
  ++n_sockets_open;
  mark_socket_open(s);
  socket_accounting_unlock();
  return s;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int tor_snprintf ( char *  str,
size_t  size,
const char *  format,
  ... 
)
int tor_socketpair ( int  family,
int  type,
int  protocol,
tor_socket_t  fd[2] 
)

Allocate a pair of connected sockets.

(Like socketpair(family, type,protocol,fd), but works on systems that don't have socketpair.)

Currently, only (AF_UNIX, SOCK_STREAM, 0) sockets are supported.

Note that on systems without socketpair, this call will fail if localhost is inaccessible (for example, if the networking stack is down). And even if it succeeds, the socket pair will not be able to read while localhost is down later (the socket pair may even close, depending on OS-specific timeouts).

Returns 0 on success and -errno on failure; do not rely on the value of errno or WSAGetLastError().

Definition at line 1118 of file compat.c.

{
//don't use win32 socketpairs (they are always bad)
#if defined(HAVE_SOCKETPAIR) && !defined(_WIN32)
  int r;

#ifdef SOCK_CLOEXEC
  r = socketpair(family, type|SOCK_CLOEXEC, protocol, fd);
  if (r == 0)
    goto sockets_ok;
  /* If we got an error, see if it is EINVAL. EINVAL might indicate that,
   * even though we were built on a system with SOCK_CLOEXEC support, we
   * are running on one without. */
  if (errno != EINVAL)
    return -errno;
#endif

  r = socketpair(family, type, protocol, fd);
  if (r < 0)
    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);
#endif
  goto sockets_ok; /* So that sockets_ok will not be unused. */

 sockets_ok:
  socket_accounting_lock();
  if (SOCKET_OK(fd[0])) {
    ++n_sockets_open;
    mark_socket_open(fd[0]);
  }
  if (SOCKET_OK(fd[1])) {
    ++n_sockets_open;
    mark_socket_open(fd[1]);
  }
  socket_accounting_unlock();

  return 0;
#else
    /* This socketpair does not work when localhost is down. So
     * it's really not the same thing at all. But it's close enough
     * for now, and really, when localhost is down sometimes, we
     * have other problems too.
     */
    tor_socket_t listener = -1;
    tor_socket_t connector = -1;
    tor_socket_t acceptor = -1;
    struct sockaddr_in listen_addr;
    struct sockaddr_in connect_addr;
    int size;
    int saved_errno = -1;

    if (protocol
#ifdef AF_UNIX
        || family != AF_UNIX
#endif
        ) {
#ifdef _WIN32
      return -WSAEAFNOSUPPORT;
#else
      return -EAFNOSUPPORT;
#endif
    }
    if (!fd) {
      return -EINVAL;
    }

    listener = tor_open_socket(AF_INET, type, 0);
    if (!SOCKET_OK(listener))
      return -tor_socket_errno(-1);
    memset(&listen_addr, 0, sizeof(listen_addr));
    listen_addr.sin_family = AF_INET;
    listen_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
    listen_addr.sin_port = 0;   /* kernel chooses port.  */
    if (bind(listener, (struct sockaddr *) &listen_addr, sizeof (listen_addr))
        == -1)
      goto tidy_up_and_fail;
    if (listen(listener, 1) == -1)
      goto tidy_up_and_fail;

    connector = tor_open_socket(AF_INET, type, 0);
    if (!SOCKET_OK(connector))
      goto tidy_up_and_fail;
    /* We want to find out the port number to connect to.  */
    size = sizeof(connect_addr);
    if (getsockname(listener, (struct sockaddr *) &connect_addr, &size) == -1)
      goto tidy_up_and_fail;
    if (size != sizeof (connect_addr))
      goto abort_tidy_up_and_fail;
    if (connect(connector, (struct sockaddr *) &connect_addr,
                sizeof(connect_addr)) == -1)
      goto tidy_up_and_fail;

    size = sizeof(listen_addr);
    acceptor = tor_accept_socket(listener,
                                 (struct sockaddr *) &listen_addr, &size);
    if (!SOCKET_OK(acceptor))
      goto tidy_up_and_fail;
    if (size != sizeof(listen_addr))
      goto abort_tidy_up_and_fail;
    tor_close_socket(listener);
    /* Now check we are talking to ourself by matching port and host on the
       two sockets.  */
    if (getsockname(connector, (struct sockaddr *) &connect_addr, &size) == -1)
      goto tidy_up_and_fail;
    if (size != sizeof (connect_addr)
        || listen_addr.sin_family != connect_addr.sin_family
        || listen_addr.sin_addr.s_addr != connect_addr.sin_addr.s_addr
        || listen_addr.sin_port != connect_addr.sin_port) {
      goto abort_tidy_up_and_fail;
    }
    fd[0] = connector;
    fd[1] = acceptor;

    return 0;

  abort_tidy_up_and_fail:
#ifdef _WIN32
    saved_errno = WSAECONNABORTED;
#else
    saved_errno = ECONNABORTED; /* I hope this is portable and appropriate.  */
#endif
  tidy_up_and_fail:
    if (saved_errno < 0)
      saved_errno = errno;
    if (listener != -1)
      tor_close_socket(listener);
    if (connector != -1)
      tor_close_socket(connector);
    if (acceptor != -1)
      tor_close_socket(acceptor);
    return -saved_errno;
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* tor_strtok_r_impl ( char *  str,
const char *  sep,
char **  lasts 
)

Implementation of strtok_r for platforms whose coders haven't figured out how to write one.

Hey guys! You can use this code here for free!

Definition at line 591 of file compat.c.

{
  char *cp, *start;
  tor_assert(*sep);
  if (str) {
    str = strtok_helper(str, sep);
    if (!*str)
      return NULL;
    start = cp = *lasts = str;
  } else if (!*lasts || !**lasts) {
    return NULL;
  } else {
    start = cp = *lasts;
  }

  if (sep[1]) {
    while (*cp && !strchr(sep, *cp))
      ++cp;
  } else {
    cp = strchr(cp, *sep);
  }

  if (!cp || !*cp) {
    *lasts = NULL;
  } else {
    *cp++ = '\0';
    *lasts = strtok_helper(cp, sep);
  }
  return start;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int int tor_vasprintf ( char **  strp,
const char *  fmt,
va_list  args 
)
int tor_vsnprintf ( char *  str,
size_t  size,
const char *  format,
va_list  args 
)
long tor_weak_random ( void  )

Return a randomly chosen value in the range 0..TOR_RAND_MAX.

This entropy will not be cryptographically strong; do not rely on it for anything an adversary should not be able to predict.

Definition at line 2078 of file compat.c.

{
#ifdef _WIN32
  return rand();
#else
  return random();
#endif
}

Here is the caller graph for this function:

int touch_file ( const char *  fname)

Change fname's modification time to now.

Definition at line 744 of file compat.c.

{
  if (utime(fname, NULL)!=0)
    return -1;
  return 0;
}

Here is the caller graph for this function:


Variable Documentation

const char TOR_TOLOWER_TABLE[]

Definition at line 553 of file compat.c.

const char TOR_TOUPPER_TABLE[]

Upper-casing and lowercasing tables to map characters to upper/lowercase equivalents.

Used by tor_toupper() and tor_tolower().

Definition at line 535 of file compat.c.