tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

util-internal.h (17702B)


      1 /*
      2 * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
      3 *
      4 * Redistribution and use in source and binary forms, with or without
      5 * modification, are permitted provided that the following conditions
      6 * are met:
      7 * 1. Redistributions of source code must retain the above copyright
      8 *    notice, this list of conditions and the following disclaimer.
      9 * 2. Redistributions in binary form must reproduce the above copyright
     10 *    notice, this list of conditions and the following disclaimer in the
     11 *    documentation and/or other materials provided with the distribution.
     12 * 3. The name of the author may not be used to endorse or promote products
     13 *    derived from this software without specific prior written permission.
     14 *
     15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     25 */
     26 #ifndef UTIL_INTERNAL_H_INCLUDED_
     27 #define UTIL_INTERNAL_H_INCLUDED_
     28 
     29 #include "event2/event-config.h"
     30 #include "evconfig-private.h"
     31 
     32 #include <errno.h>
     33 
     34 /* For EVUTIL_ASSERT */
     35 #include "log-internal.h"
     36 #include <stdio.h>
     37 #include <stdlib.h>
     38 #ifdef EVENT__HAVE_SYS_SOCKET_H
     39 #include <sys/socket.h>
     40 #endif
     41 #ifdef EVENT__HAVE_SYS_EVENTFD_H
     42 #include <sys/eventfd.h>
     43 #endif
     44 #include "event2/util.h"
     45 
     46 #include "time-internal.h"
     47 #include "ipv6-internal.h"
     48 
     49 #ifdef __cplusplus
     50 extern "C" {
     51 #endif
     52 
     53 /* __has_attribute() wrapper */
     54 #ifdef __has_attribute
     55 # define EVUTIL_HAS_ATTRIBUTE __has_attribute
     56 #endif
     57 /** clang 3 __has_attribute misbehaves in some versions */
     58 #if defined(__clang__) && __clang__ == 1
     59 # if defined(__apple_build_version__)
     60 #  if __clang_major__ <= 6
     61 #   undef EVUTIL_HAS_ATTRIBUTE
     62 #  endif
     63 # else /* !__apple_build_version__ */
     64 #  if __clang_major__ == 3 && __clang_minor__ >= 2 && __clang_minor__ <= 5
     65 #   undef EVUTIL_HAS_ATTRIBUTE
     66 #  endif
     67 # endif /* __apple_build_version__ */
     68 #endif /*\ defined(__clang__) && __clang__ == 1 */
     69 #ifndef EVUTIL_HAS_ATTRIBUTE
     70 # define EVUTIL_HAS_ATTRIBUTE(x) 0
     71 #endif
     72 
     73 /* If we need magic to say "inline", get it for free internally. */
     74 #ifdef EVENT__inline
     75 #define inline EVENT__inline
     76 #endif
     77 
     78 /* Define to appropriate substitute if compiler doesnt have __func__ */
     79 #if defined(EVENT__HAVE___func__)
     80 # ifndef __func__
     81 #  define __func__ __func__
     82 # endif
     83 #elif defined(EVENT__HAVE___FUNCTION__)
     84 # define __func__ __FUNCTION__
     85 #else
     86 # define __func__ __FILE__
     87 #endif
     88 
     89 /* A good no-op to use in macro definitions. */
     90 #define EVUTIL_NIL_STMT_ ((void)0)
     91 /* A no-op that tricks the compiler into thinking a condition is used while
     92 * definitely not making any code for it.  Used to compile out asserts while
     93 * avoiding "unused variable" warnings.  The "!" forces the compiler to
     94 * do the sizeof() on an int, in case "condition" is a bitfield value.
     95 */
     96 #define EVUTIL_NIL_CONDITION_(condition) do { \
     97 (void)sizeof(!(condition));  \
     98 } while(0)
     99 
    100 /* Internal use only: macros to match patterns of error codes in a
    101   cross-platform way.  We need these macros because of two historical
    102   reasons: first, nonblocking IO functions are generally written to give an
    103   error on the "blocked now, try later" case, so sometimes an error from a
    104   read, write, connect, or accept means "no error; just wait for more
    105   data," and we need to look at the error code.  Second, Windows defines
    106   a different set of error codes for sockets. */
    107 
    108 #ifndef _WIN32
    109 
    110 #if EAGAIN == EWOULDBLOCK
    111 #define EVUTIL_ERR_IS_EAGAIN(e) \
    112 ((e) == EAGAIN)
    113 #else
    114 #define EVUTIL_ERR_IS_EAGAIN(e) \
    115 ((e) == EAGAIN || (e) == EWOULDBLOCK)
    116 #endif
    117 
    118 /* True iff e is an error that means a read/write operation can be retried. */
    119 #define EVUTIL_ERR_RW_RETRIABLE(e)				\
    120 ((e) == EINTR || EVUTIL_ERR_IS_EAGAIN(e))
    121 /* True iff e is an error that means an connect can be retried. */
    122 #define EVUTIL_ERR_CONNECT_RETRIABLE(e)			\
    123 ((e) == EINTR || (e) == EINPROGRESS)
    124 /* True iff e is an error that means a accept can be retried. */
    125 #define EVUTIL_ERR_ACCEPT_RETRIABLE(e)			\
    126 ((e) == EINTR || EVUTIL_ERR_IS_EAGAIN(e) || (e) == ECONNABORTED)
    127 
    128 /* True iff e is an error that means the connection was refused */
    129 #define EVUTIL_ERR_CONNECT_REFUSED(e)					\
    130 ((e) == ECONNREFUSED)
    131 
    132 #else
    133 /* Win32 */
    134 
    135 #define EVUTIL_ERR_IS_EAGAIN(e) \
    136 ((e) == WSAEWOULDBLOCK || (e) == EAGAIN)
    137 
    138 #define EVUTIL_ERR_RW_RETRIABLE(e)					\
    139 ((e) == WSAEWOULDBLOCK ||					\
    140     (e) == WSAEINTR)
    141 
    142 #define EVUTIL_ERR_CONNECT_RETRIABLE(e)					\
    143 ((e) == WSAEWOULDBLOCK ||					\
    144     (e) == WSAEINTR ||						\
    145     (e) == WSAEINPROGRESS ||					\
    146     (e) == WSAEINVAL)
    147 
    148 #define EVUTIL_ERR_ACCEPT_RETRIABLE(e)			\
    149 EVUTIL_ERR_RW_RETRIABLE(e)
    150 
    151 #define EVUTIL_ERR_CONNECT_REFUSED(e)					\
    152 ((e) == WSAECONNREFUSED)
    153 
    154 #endif
    155 
    156 /* Arguments for shutdown() */
    157 #ifdef SHUT_RD
    158 #define EVUTIL_SHUT_RD SHUT_RD
    159 #else
    160 #define EVUTIL_SHUT_RD 0
    161 #endif
    162 #ifdef SHUT_WR
    163 #define EVUTIL_SHUT_WR SHUT_WR
    164 #else
    165 #define EVUTIL_SHUT_WR 1 /* SD_SEND */
    166 #endif
    167 #ifdef SHUT_BOTH
    168 #define EVUTIL_SHUT_BOTH SHUT_BOTH
    169 #else
    170 #define EVUTIL_SHUT_BOTH 2
    171 #endif
    172 
    173 /* Helper: Verify that all the elements in 'dlist' are internally consistent.
    174 * Checks for circular lists and bad prev/next pointers.
    175 *
    176 * Example usage:
    177 *    EVUTIL_ASSERT_LIST_OK(eventlist, event, ev_next);
    178 */
    179 #define EVUTIL_ASSERT_LIST_OK(dlist, type, field) do {			\
    180 	struct type *elm1, *elm2, **nextp;			\
    181 	if (LIST_EMPTY((dlist)))				\
    182 		break;						\
    183 								\
    184 	/* Check list for circularity using Floyd's */		\
    185 	/* 'Tortoise and Hare' algorithm */			\
    186 	elm1 = LIST_FIRST((dlist));				\
    187 	elm2 = LIST_NEXT(elm1, field);				\
    188 	while (elm1 && elm2) {					\
    189 		EVUTIL_ASSERT(elm1 != elm2);			\
    190 		elm1 = LIST_NEXT(elm1, field);			\
    191 		elm2 = LIST_NEXT(elm2, field);			\
    192 		if (!elm2)					\
    193 			break;					\
    194 		EVUTIL_ASSERT(elm1 != elm2);			\
    195 		elm2 = LIST_NEXT(elm2, field);			\
    196 	}							\
    197 								\
    198 	/* Now check next and prev pointers for consistency. */ \
    199 	nextp = &LIST_FIRST((dlist));				\
    200 	elm1 = LIST_FIRST((dlist));				\
    201 	while (elm1) {						\
    202 		EVUTIL_ASSERT(*nextp == elm1);			\
    203 		EVUTIL_ASSERT(nextp == elm1->field.le_prev);	\
    204 		nextp = &LIST_NEXT(elm1, field);		\
    205 		elm1 = *nextp;					\
    206 	}							\
    207 } while (0)
    208 
    209 /* Helper: Verify that all the elements in a TAILQ are internally consistent.
    210 * Checks for circular lists and bad prev/next pointers.
    211 *
    212 * Example usage:
    213 *    EVUTIL_ASSERT_TAILQ_OK(activelist, event, ev_active_next);
    214 */
    215 #define EVUTIL_ASSERT_TAILQ_OK(tailq, type, field) do {			\
    216 	struct type *elm1, *elm2, **nextp;			\
    217 	if (TAILQ_EMPTY((tailq)))				\
    218 		break;						\
    219 								\
    220 	/* Check list for circularity using Floyd's */		\
    221 	/* 'Tortoise and Hare' algorithm */			\
    222 	elm1 = TAILQ_FIRST((tailq));				\
    223 	elm2 = TAILQ_NEXT(elm1, field);				\
    224 	while (elm1 && elm2) {					\
    225 		EVUTIL_ASSERT(elm1 != elm2);			\
    226 		elm1 = TAILQ_NEXT(elm1, field);			\
    227 		elm2 = TAILQ_NEXT(elm2, field);			\
    228 		if (!elm2)					\
    229 			break;					\
    230 		EVUTIL_ASSERT(elm1 != elm2);			\
    231 		elm2 = TAILQ_NEXT(elm2, field);			\
    232 	}							\
    233 								\
    234 	/* Now check next and prev pointers for consistency. */ \
    235 	nextp = &TAILQ_FIRST((tailq));				\
    236 	elm1 = TAILQ_FIRST((tailq));				\
    237 	while (elm1) {						\
    238 		EVUTIL_ASSERT(*nextp == elm1);			\
    239 		EVUTIL_ASSERT(nextp == elm1->field.tqe_prev);	\
    240 		nextp = &TAILQ_NEXT(elm1, field);		\
    241 		elm1 = *nextp;					\
    242 	}							\
    243 	EVUTIL_ASSERT(nextp == (tailq)->tqh_last);		\
    244 } while (0)
    245 
    246 /* Locale-independent replacements for some ctypes functions.  Use these
    247 * when you care about ASCII's notion of character types, because you are about
    248 * to send those types onto the wire.
    249 */
    250 EVENT2_EXPORT_SYMBOL
    251 int EVUTIL_ISALPHA_(char c);
    252 EVENT2_EXPORT_SYMBOL
    253 int EVUTIL_ISALNUM_(char c);
    254 int EVUTIL_ISSPACE_(char c);
    255 EVENT2_EXPORT_SYMBOL
    256 int EVUTIL_ISDIGIT_(char c);
    257 EVENT2_EXPORT_SYMBOL
    258 int EVUTIL_ISXDIGIT_(char c);
    259 int EVUTIL_ISPRINT_(char c);
    260 int EVUTIL_ISLOWER_(char c);
    261 int EVUTIL_ISUPPER_(char c);
    262 EVENT2_EXPORT_SYMBOL
    263 char EVUTIL_TOUPPER_(char c);
    264 EVENT2_EXPORT_SYMBOL
    265 char EVUTIL_TOLOWER_(char c);
    266 
    267 /** Remove all trailing horizontal whitespace (space or tab) from the end of a
    268 * string */
    269 EVENT2_EXPORT_SYMBOL
    270 void evutil_rtrim_lws_(char *);
    271 
    272 
    273 /** Helper macro.  If we know that a given pointer points to a field in a
    274    structure, return a pointer to the structure itself.  Used to implement
    275    our half-baked C OO.  Example:
    276 
    277    struct subtype {
    278 int x;
    279 struct supertype common;
    280 int y;
    281    };
    282    ...
    283    void fn(struct supertype *super) {
    284 struct subtype *sub = EVUTIL_UPCAST(super, struct subtype, common);
    285 ...
    286    }
    287 */
    288 #define EVUTIL_UPCAST(ptr, type, field)				\
    289 ((type *)(((char*)(ptr)) - evutil_offsetof(type, field)))
    290 
    291 /* As open(pathname, flags, mode), except that the file is always opened with
    292 * the close-on-exec flag set. (And the mode argument is mandatory.)
    293 */
    294 int evutil_open_closeonexec_(const char *pathname, int flags, unsigned mode);
    295 
    296 EVENT2_EXPORT_SYMBOL
    297 int evutil_read_file_(const char *filename, char **content_out, size_t *len_out,
    298    int is_binary);
    299 
    300 EVENT2_EXPORT_SYMBOL
    301 int evutil_socket_connect_(evutil_socket_t *fd_ptr, const struct sockaddr *sa, int socklen);
    302 
    303 int evutil_socket_finished_connecting_(evutil_socket_t fd);
    304 
    305 EVENT2_EXPORT_SYMBOL
    306 int evutil_ersatz_socketpair_(int, int , int, evutil_socket_t[]);
    307 
    308 int evutil_resolve_(int family, const char *hostname, struct sockaddr *sa,
    309    ev_socklen_t *socklen, int port);
    310 
    311 const char *evutil_getenv_(const char *name);
    312 
    313 /* Structure to hold the state of our weak random number generator.
    314 */
    315 struct evutil_weakrand_state {
    316 ev_uint32_t seed;
    317 };
    318 
    319 #define EVUTIL_WEAKRAND_MAX EV_INT32_MAX
    320 
    321 /* Initialize the state of a week random number generator based on 'seed'.  If
    322 * the seed is 0, construct a new seed based on not-very-strong platform
    323 * entropy, like the PID and the time of day.
    324 *
    325 * This function, and the other evutil_weakrand* functions, are meant for
    326 * speed, not security or statistical strength.  If you need a RNG which an
    327 * attacker can't predict, or which passes strong statistical tests, use the
    328 * evutil_secure_rng* functions instead.
    329 */
    330 EVENT2_EXPORT_SYMBOL
    331 ev_uint32_t evutil_weakrand_seed_(struct evutil_weakrand_state *state, ev_uint32_t seed);
    332 /* Return a pseudorandom value between 0 and EVUTIL_WEAKRAND_MAX inclusive.
    333 * Updates the state in 'seed' as needed -- this value must be protected by a
    334 * lock.
    335 */
    336 EVENT2_EXPORT_SYMBOL
    337 ev_int32_t evutil_weakrand_(struct evutil_weakrand_state *seed);
    338 /* Return a pseudorandom value x such that 0 <= x < top. top must be no more
    339 * than EVUTIL_WEAKRAND_MAX. Updates the state in 'seed' as needed -- this
    340 * value must be proteced by a lock */
    341 EVENT2_EXPORT_SYMBOL
    342 ev_int32_t evutil_weakrand_range_(struct evutil_weakrand_state *seed, ev_int32_t top);
    343 
    344 /* Evaluates to the same boolean value as 'p', and hints to the compiler that
    345 * we expect this value to be false. */
    346 #if defined(__GNUC__) && __GNUC__ >= 3         /* gcc 3.0 or later */
    347 #define EVUTIL_UNLIKELY(p) __builtin_expect(!!(p),0)
    348 #else
    349 #define EVUTIL_UNLIKELY(p) (p)
    350 #endif
    351 
    352 #if EVUTIL_HAS_ATTRIBUTE(fallthrough)
    353 #define EVUTIL_FALLTHROUGH __attribute__((fallthrough))
    354 #else
    355 #define EVUTIL_FALLTHROUGH /* fallthrough */
    356 #endif
    357 
    358 /* Replacement for assert() that calls event_errx on failure. */
    359 #ifdef NDEBUG
    360 #define EVUTIL_ASSERT(cond) EVUTIL_NIL_CONDITION_(cond)
    361 #define EVUTIL_FAILURE_CHECK(cond) 0
    362 #else
    363 #define EVUTIL_ASSERT(cond)						\
    364 do {								\
    365 	if (EVUTIL_UNLIKELY(!(cond))) {				\
    366 		event_errx(EVENT_ERR_ABORT_,			\
    367 		    "%s:%d: Assertion %s failed in %s",		\
    368 		    __FILE__,__LINE__,#cond,__func__);		\
    369 		/* In case a user-supplied handler tries to */	\
    370 		/* return control to us, log and abort here. */	\
    371 		(void)fprintf(stderr,				\
    372 		    "%s:%d: Assertion %s failed in %s",		\
    373 		    __FILE__,__LINE__,#cond,__func__);		\
    374 		abort();					\
    375 	}							\
    376 } while (0)
    377 #define EVUTIL_FAILURE_CHECK(cond) EVUTIL_UNLIKELY(cond)
    378 #endif
    379 
    380 #ifndef EVENT__HAVE_STRUCT_SOCKADDR_STORAGE
    381 /* Replacement for sockaddr storage that we can use internally on platforms
    382 * that lack it.  It is not space-efficient, but neither is sockaddr_storage.
    383 */
    384 struct sockaddr_storage {
    385 union {
    386 	struct sockaddr ss_sa;
    387 	struct sockaddr_in ss_sin;
    388 	struct sockaddr_in6 ss_sin6;
    389 	char ss_padding[128];
    390 } ss_union;
    391 };
    392 #define ss_family ss_union.ss_sa.sa_family
    393 #endif
    394 
    395 /* Internal addrinfo error code.  This one is returned from only from
    396 * evutil_getaddrinfo_common_, when we are sure that we'll have to hit a DNS
    397 * server. */
    398 #define EVUTIL_EAI_NEED_RESOLVE      -90002
    399 
    400 struct evdns_base;
    401 struct evdns_getaddrinfo_request;
    402 typedef struct evdns_getaddrinfo_request* (*evdns_getaddrinfo_fn)(
    403    struct evdns_base *base,
    404    const char *nodename, const char *servname,
    405    const struct evutil_addrinfo *hints_in,
    406    void (*cb)(int, struct evutil_addrinfo *, void *), void *arg);
    407 EVENT2_EXPORT_SYMBOL
    408 void evutil_set_evdns_getaddrinfo_fn_(evdns_getaddrinfo_fn fn);
    409 typedef void (*evdns_getaddrinfo_cancel_fn)(
    410    struct evdns_getaddrinfo_request *req);
    411 EVENT2_EXPORT_SYMBOL
    412 void evutil_set_evdns_getaddrinfo_cancel_fn_(evdns_getaddrinfo_cancel_fn fn);
    413 
    414 EVENT2_EXPORT_SYMBOL
    415 struct evutil_addrinfo *evutil_new_addrinfo_(struct sockaddr *sa,
    416    ev_socklen_t socklen, const struct evutil_addrinfo *hints);
    417 EVENT2_EXPORT_SYMBOL
    418 struct evutil_addrinfo *evutil_addrinfo_append_(struct evutil_addrinfo *first,
    419    struct evutil_addrinfo *append);
    420 EVENT2_EXPORT_SYMBOL
    421 void evutil_adjust_hints_for_addrconfig_(struct evutil_addrinfo *hints);
    422 EVENT2_EXPORT_SYMBOL
    423 int evutil_getaddrinfo_common_(const char *nodename, const char *servname,
    424    struct evutil_addrinfo *hints, struct evutil_addrinfo **res, int *portnum);
    425 
    426 struct evdns_getaddrinfo_request *evutil_getaddrinfo_async_(
    427    struct evdns_base *dns_base,
    428    const char *nodename, const char *servname,
    429    const struct evutil_addrinfo *hints_in,
    430    void (*cb)(int, struct evutil_addrinfo *, void *), void *arg);
    431 void evutil_getaddrinfo_cancel_async_(struct evdns_getaddrinfo_request *data);
    432 
    433 /** Return true iff sa is a looback address. (That is, it is 127.0.0.1/8, or
    434 * ::1). */
    435 EVENT2_EXPORT_SYMBOL
    436 int evutil_sockaddr_is_loopback_(const struct sockaddr *sa);
    437 
    438 
    439 /**
    440    Formats a sockaddr sa into a string buffer of size outlen stored in out.
    441    Returns a pointer to out.  Always writes something into out, so it's safe
    442    to use the output of this function without checking it for NULL.
    443 */
    444 EVENT2_EXPORT_SYMBOL
    445 const char *evutil_format_sockaddr_port_(const struct sockaddr *sa, char *out, size_t outlen);
    446 
    447 int evutil_hex_char_to_int_(char c);
    448 
    449 
    450 void evutil_free_secure_rng_globals_(void);
    451 void evutil_free_globals_(void);
    452 
    453 #ifdef _WIN32
    454 EVENT2_EXPORT_SYMBOL
    455 HMODULE evutil_load_windows_system_library_(const TCHAR *library_name);
    456 #endif
    457 
    458 #ifndef EV_SIZE_FMT
    459 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__)
    460 #define EV_U64_FMT "%I64u"
    461 #define EV_I64_FMT "%I64d"
    462 #define EV_I64_ARG(x) ((__int64)(x))
    463 #define EV_U64_ARG(x) ((unsigned __int64)(x))
    464 #else
    465 #define EV_U64_FMT "%llu"
    466 #define EV_I64_FMT "%lld"
    467 #define EV_I64_ARG(x) ((long long)(x))
    468 #define EV_U64_ARG(x) ((unsigned long long)(x))
    469 #endif
    470 #endif
    471 
    472 #ifdef _WIN32
    473 #define EV_SOCK_FMT EV_I64_FMT
    474 #define EV_SOCK_ARG(x) EV_I64_ARG((x))
    475 #else
    476 #define EV_SOCK_FMT "%d"
    477 #define EV_SOCK_ARG(x) (x)
    478 #endif
    479 
    480 #if defined(__STDC__) && defined(__STDC_VERSION__) && !defined(__MINGW64_VERSION_MAJOR)
    481 #if (__STDC_VERSION__ >= 199901L)
    482 #define EV_SIZE_FMT "%zu"
    483 #define EV_SSIZE_FMT "%zd"
    484 #define EV_SIZE_ARG(x) (x)
    485 #define EV_SSIZE_ARG(x) (x)
    486 #endif
    487 #endif
    488 
    489 #ifndef EV_SIZE_FMT
    490 #if (EVENT__SIZEOF_SIZE_T <= EVENT__SIZEOF_LONG)
    491 #define EV_SIZE_FMT "%lu"
    492 #define EV_SSIZE_FMT "%ld"
    493 #define EV_SIZE_ARG(x) ((unsigned long)(x))
    494 #define EV_SSIZE_ARG(x) ((long)(x))
    495 #else
    496 #define EV_SIZE_FMT EV_U64_FMT
    497 #define EV_SSIZE_FMT EV_I64_FMT
    498 #define EV_SIZE_ARG(x) EV_U64_ARG(x)
    499 #define EV_SSIZE_ARG(x) EV_I64_ARG(x)
    500 #endif
    501 #endif
    502 
    503 EVENT2_EXPORT_SYMBOL
    504 evutil_socket_t evutil_socket_(int domain, int type, int protocol);
    505 evutil_socket_t evutil_accept4_(evutil_socket_t sockfd, struct sockaddr *addr,
    506    ev_socklen_t *addrlen, int flags);
    507 
    508    /* used by one of the test programs.. */
    509 EVENT2_EXPORT_SYMBOL
    510 int evutil_make_internal_pipe_(evutil_socket_t fd[2]);
    511 evutil_socket_t evutil_eventfd_(unsigned initval, int flags);
    512 
    513 #ifdef SOCK_NONBLOCK
    514 #define EVUTIL_SOCK_NONBLOCK SOCK_NONBLOCK
    515 #else
    516 #define EVUTIL_SOCK_NONBLOCK 0x4000000
    517 #endif
    518 #ifdef SOCK_CLOEXEC
    519 #define EVUTIL_SOCK_CLOEXEC SOCK_CLOEXEC
    520 #else
    521 #define EVUTIL_SOCK_CLOEXEC 0x80000000
    522 #endif
    523 #ifdef EFD_NONBLOCK
    524 #define EVUTIL_EFD_NONBLOCK EFD_NONBLOCK
    525 #else
    526 #define EVUTIL_EFD_NONBLOCK 0x4000
    527 #endif
    528 #ifdef EFD_CLOEXEC
    529 #define EVUTIL_EFD_CLOEXEC EFD_CLOEXEC
    530 #else
    531 #define EVUTIL_EFD_CLOEXEC 0x8000
    532 #endif
    533 
    534 void evutil_memclear_(void *mem, size_t len);
    535 
    536 struct in_addr;
    537 struct in6_addr;
    538 
    539 /* This is a any, loopback, link-local, multicast */
    540 EVENT2_EXPORT_SYMBOL
    541 int evutil_v4addr_is_local_(const struct in_addr *in);
    542 /* This is a reserved, ipv4compat, ipv4map, loopback,
    543 * link-local, multicast, or unspecified address. */
    544 EVENT2_EXPORT_SYMBOL
    545 int evutil_v6addr_is_local_(const struct in6_addr *in);
    546 
    547 #ifdef __cplusplus
    548 }
    549 #endif
    550 
    551 #endif