1275970Scy/*
2275970Scy * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
3275970Scy *
4275970Scy * Redistribution and use in source and binary forms, with or without
5275970Scy * modification, are permitted provided that the following conditions
6275970Scy * are met:
7275970Scy * 1. Redistributions of source code must retain the above copyright
8275970Scy *    notice, this list of conditions and the following disclaimer.
9275970Scy * 2. Redistributions in binary form must reproduce the above copyright
10275970Scy *    notice, this list of conditions and the following disclaimer in the
11275970Scy *    documentation and/or other materials provided with the distribution.
12275970Scy * 3. The name of the author may not be used to endorse or promote products
13275970Scy *    derived from this software without specific prior written permission.
14275970Scy *
15275970Scy * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16275970Scy * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17275970Scy * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18275970Scy * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19275970Scy * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20275970Scy * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21275970Scy * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22275970Scy * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23275970Scy * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24275970Scy * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25275970Scy */
26275970Scy#ifndef UTIL_INTERNAL_H_INCLUDED_
27275970Scy#define UTIL_INTERNAL_H_INCLUDED_
28275970Scy
29275970Scy#include "event2/event-config.h"
30275970Scy#include "evconfig-private.h"
31275970Scy
32275970Scy#include <errno.h>
33275970Scy
34275970Scy/* For EVUTIL_ASSERT */
35275970Scy#include "log-internal.h"
36275970Scy#include <stdio.h>
37275970Scy#include <stdlib.h>
38275970Scy#ifdef EVENT__HAVE_SYS_SOCKET_H
39275970Scy#include <sys/socket.h>
40275970Scy#endif
41275970Scy#ifdef EVENT__HAVE_SYS_EVENTFD_H
42275970Scy#include <sys/eventfd.h>
43275970Scy#endif
44275970Scy#include "event2/util.h"
45275970Scy
46275970Scy#include "time-internal.h"
47275970Scy#include "ipv6-internal.h"
48275970Scy
49275970Scy#ifdef __cplusplus
50275970Scyextern "C" {
51275970Scy#endif
52275970Scy
53275970Scy/* If we need magic to say "inline", get it for free internally. */
54275970Scy#ifdef EVENT__inline
55275970Scy#define inline EVENT__inline
56275970Scy#endif
57275970Scy#ifdef EVENT____func__
58275970Scy#define __func__ EVENT____func__
59275970Scy#endif
60275970Scy
61275970Scy/* A good no-op to use in macro definitions. */
62275970Scy#define EVUTIL_NIL_STMT_ ((void)0)
63275970Scy/* A no-op that tricks the compiler into thinking a condition is used while
64275970Scy * definitely not making any code for it.  Used to compile out asserts while
65275970Scy * avoiding "unused variable" warnings.  The "!" forces the compiler to
66275970Scy * do the sizeof() on an int, in case "condition" is a bitfield value.
67275970Scy */
68275970Scy#define EVUTIL_NIL_CONDITION_(condition) do { \
69275970Scy	(void)sizeof(!(condition));  \
70275970Scy} while(0)
71275970Scy
72275970Scy/* Internal use only: macros to match patterns of error codes in a
73275970Scy   cross-platform way.  We need these macros because of two historical
74275970Scy   reasons: first, nonblocking IO functions are generally written to give an
75275970Scy   error on the "blocked now, try later" case, so sometimes an error from a
76275970Scy   read, write, connect, or accept means "no error; just wait for more
77275970Scy   data," and we need to look at the error code.  Second, Windows defines
78275970Scy   a different set of error codes for sockets. */
79275970Scy
80275970Scy#ifndef _WIN32
81275970Scy
82275970Scy#if EAGAIN == EWOULDBLOCK
83275970Scy#define EVUTIL_ERR_IS_EAGAIN(e) \
84275970Scy	((e) == EAGAIN)
85275970Scy#else
86275970Scy#define EVUTIL_ERR_IS_EAGAIN(e) \
87275970Scy	((e) == EAGAIN || (e) == EWOULDBLOCK)
88275970Scy#endif
89275970Scy
90275970Scy/* True iff e is an error that means a read/write operation can be retried. */
91275970Scy#define EVUTIL_ERR_RW_RETRIABLE(e)				\
92275970Scy	((e) == EINTR || EVUTIL_ERR_IS_EAGAIN(e))
93275970Scy/* True iff e is an error that means an connect can be retried. */
94275970Scy#define EVUTIL_ERR_CONNECT_RETRIABLE(e)			\
95275970Scy	((e) == EINTR || (e) == EINPROGRESS)
96275970Scy/* True iff e is an error that means a accept can be retried. */
97275970Scy#define EVUTIL_ERR_ACCEPT_RETRIABLE(e)			\
98275970Scy	((e) == EINTR || EVUTIL_ERR_IS_EAGAIN(e) || (e) == ECONNABORTED)
99275970Scy
100275970Scy/* True iff e is an error that means the connection was refused */
101275970Scy#define EVUTIL_ERR_CONNECT_REFUSED(e)					\
102275970Scy	((e) == ECONNREFUSED)
103275970Scy
104275970Scy#else
105275970Scy/* Win32 */
106275970Scy
107275970Scy#define EVUTIL_ERR_IS_EAGAIN(e) \
108275970Scy	((e) == WSAEWOULDBLOCK || (e) == EAGAIN)
109275970Scy
110275970Scy#define EVUTIL_ERR_RW_RETRIABLE(e)					\
111275970Scy	((e) == WSAEWOULDBLOCK ||					\
112275970Scy	    (e) == WSAEINTR)
113275970Scy
114275970Scy#define EVUTIL_ERR_CONNECT_RETRIABLE(e)					\
115275970Scy	((e) == WSAEWOULDBLOCK ||					\
116275970Scy	    (e) == WSAEINTR ||						\
117275970Scy	    (e) == WSAEINPROGRESS ||					\
118275970Scy	    (e) == WSAEINVAL)
119275970Scy
120275970Scy#define EVUTIL_ERR_ACCEPT_RETRIABLE(e)			\
121275970Scy	EVUTIL_ERR_RW_RETRIABLE(e)
122275970Scy
123275970Scy#define EVUTIL_ERR_CONNECT_REFUSED(e)					\
124275970Scy	((e) == WSAECONNREFUSED)
125275970Scy
126275970Scy#endif
127275970Scy
128275970Scy/* Arguments for shutdown() */
129275970Scy#ifdef SHUT_RD
130275970Scy#define EVUTIL_SHUT_RD SHUT_RD
131275970Scy#else
132275970Scy#define EVUTIL_SHUT_RD 0
133275970Scy#endif
134275970Scy#ifdef SHUT_WR
135275970Scy#define EVUTIL_SHUT_WR SHUT_WR
136275970Scy#else
137275970Scy#define EVUTIL_SHUT_WR 1
138275970Scy#endif
139275970Scy#ifdef SHUT_BOTH
140275970Scy#define EVUTIL_SHUT_BOTH SHUT_BOTH
141275970Scy#else
142275970Scy#define EVUTIL_SHUT_BOTH 2
143275970Scy#endif
144275970Scy
145275970Scy/* Helper: Verify that all the elements in 'dlist' are internally consistent.
146275970Scy * Checks for circular lists and bad prev/next pointers.
147275970Scy *
148275970Scy * Example usage:
149275970Scy *    EVUTIL_ASSERT_LIST_OK(eventlist, event, ev_next);
150275970Scy */
151275970Scy#define EVUTIL_ASSERT_LIST_OK(dlist, type, field) do {			\
152275970Scy		struct type *elm1, *elm2, **nextp;			\
153275970Scy		if (LIST_EMPTY((dlist)))				\
154275970Scy			break;						\
155275970Scy									\
156275970Scy		/* Check list for circularity using Floyd's */		\
157275970Scy		/* 'Tortoise and Hare' algorithm */			\
158275970Scy		elm1 = LIST_FIRST((dlist));				\
159275970Scy		elm2 = LIST_NEXT(elm1, field);				\
160275970Scy		while (elm1 && elm2) {					\
161275970Scy			EVUTIL_ASSERT(elm1 != elm2);			\
162275970Scy			elm1 = LIST_NEXT(elm1, field);			\
163275970Scy			elm2 = LIST_NEXT(elm2, field);			\
164275970Scy			if (!elm2)					\
165275970Scy				break;					\
166275970Scy			EVUTIL_ASSERT(elm1 != elm2);			\
167275970Scy			elm2 = LIST_NEXT(elm2, field);			\
168275970Scy		}							\
169275970Scy									\
170275970Scy		/* Now check next and prev pointers for consistency. */ \
171275970Scy		nextp = &LIST_FIRST((dlist));				\
172275970Scy		elm1 = LIST_FIRST((dlist));				\
173275970Scy		while (elm1) {						\
174275970Scy			EVUTIL_ASSERT(*nextp == elm1);			\
175275970Scy			EVUTIL_ASSERT(nextp == elm1->field.le_prev);	\
176275970Scy			nextp = &LIST_NEXT(elm1, field);		\
177275970Scy			elm1 = *nextp;					\
178275970Scy		}							\
179275970Scy	} while (0)
180275970Scy
181275970Scy/* Helper: Verify that all the elements in a TAILQ are internally consistent.
182275970Scy * Checks for circular lists and bad prev/next pointers.
183275970Scy *
184275970Scy * Example usage:
185275970Scy *    EVUTIL_ASSERT_TAILQ_OK(activelist, event, ev_active_next);
186275970Scy */
187275970Scy#define EVUTIL_ASSERT_TAILQ_OK(tailq, type, field) do {			\
188275970Scy		struct type *elm1, *elm2, **nextp;			\
189275970Scy		if (TAILQ_EMPTY((tailq)))				\
190275970Scy			break;						\
191275970Scy									\
192275970Scy		/* Check list for circularity using Floyd's */		\
193275970Scy		/* 'Tortoise and Hare' algorithm */			\
194275970Scy		elm1 = TAILQ_FIRST((tailq));				\
195275970Scy		elm2 = TAILQ_NEXT(elm1, field);				\
196275970Scy		while (elm1 && elm2) {					\
197275970Scy			EVUTIL_ASSERT(elm1 != elm2);			\
198275970Scy			elm1 = TAILQ_NEXT(elm1, field);			\
199275970Scy			elm2 = TAILQ_NEXT(elm2, field);			\
200275970Scy			if (!elm2)					\
201275970Scy				break;					\
202275970Scy			EVUTIL_ASSERT(elm1 != elm2);			\
203275970Scy			elm2 = TAILQ_NEXT(elm2, field);			\
204275970Scy		}							\
205275970Scy									\
206275970Scy		/* Now check next and prev pointers for consistency. */ \
207275970Scy		nextp = &TAILQ_FIRST((tailq));				\
208275970Scy		elm1 = TAILQ_FIRST((tailq));				\
209275970Scy		while (elm1) {						\
210275970Scy			EVUTIL_ASSERT(*nextp == elm1);			\
211275970Scy			EVUTIL_ASSERT(nextp == elm1->field.tqe_prev);	\
212275970Scy			nextp = &TAILQ_NEXT(elm1, field);		\
213275970Scy			elm1 = *nextp;					\
214275970Scy		}							\
215275970Scy		EVUTIL_ASSERT(nextp == (tailq)->tqh_last);		\
216275970Scy	} while (0)
217275970Scy
218275970Scy/* Locale-independent replacements for some ctypes functions.  Use these
219275970Scy * when you care about ASCII's notion of character types, because you are about
220275970Scy * to send those types onto the wire.
221275970Scy */
222275970Scyint EVUTIL_ISALPHA_(char c);
223275970Scyint EVUTIL_ISALNUM_(char c);
224275970Scyint EVUTIL_ISSPACE_(char c);
225275970Scyint EVUTIL_ISDIGIT_(char c);
226275970Scyint EVUTIL_ISXDIGIT_(char c);
227275970Scyint EVUTIL_ISPRINT_(char c);
228275970Scyint EVUTIL_ISLOWER_(char c);
229275970Scyint EVUTIL_ISUPPER_(char c);
230275970Scychar EVUTIL_TOUPPER_(char c);
231275970Scychar EVUTIL_TOLOWER_(char c);
232275970Scy
233275970Scy/** Remove all trailing horizontal whitespace (space or tab) from the end of a
234275970Scy * string */
235275970Scyvoid evutil_rtrim_lws_(char *);
236275970Scy
237275970Scy
238275970Scy/** Helper macro.  If we know that a given pointer points to a field in a
239275970Scy    structure, return a pointer to the structure itself.  Used to implement
240275970Scy    our half-baked C OO.  Example:
241275970Scy
242275970Scy    struct subtype {
243275970Scy	int x;
244275970Scy	struct supertype common;
245275970Scy	int y;
246275970Scy    };
247275970Scy    ...
248275970Scy    void fn(struct supertype *super) {
249275970Scy	struct subtype *sub = EVUTIL_UPCAST(super, struct subtype, common);
250275970Scy	...
251275970Scy    }
252275970Scy */
253275970Scy#define EVUTIL_UPCAST(ptr, type, field)				\
254275970Scy	((type *)(((char*)(ptr)) - evutil_offsetof(type, field)))
255275970Scy
256275970Scy/* As open(pathname, flags, mode), except that the file is always opened with
257275970Scy * the close-on-exec flag set. (And the mode argument is mandatory.)
258275970Scy */
259275970Scyint evutil_open_closeonexec_(const char *pathname, int flags, unsigned mode);
260275970Scy
261275970Scyint evutil_read_file_(const char *filename, char **content_out, size_t *len_out,
262275970Scy    int is_binary);
263275970Scy
264275970Scyint evutil_socket_connect_(evutil_socket_t *fd_ptr, struct sockaddr *sa, int socklen);
265275970Scy
266275970Scyint evutil_socket_finished_connecting_(evutil_socket_t fd);
267275970Scy
268275970Scyint evutil_ersatz_socketpair_(int, int , int, evutil_socket_t[]);
269275970Scy
270275970Scyint evutil_resolve_(int family, const char *hostname, struct sockaddr *sa,
271275970Scy    ev_socklen_t *socklen, int port);
272275970Scy
273275970Scyconst char *evutil_getenv_(const char *name);
274275970Scy
275275970Scy/* Structure to hold the state of our weak random number generator.
276275970Scy */
277275970Scystruct evutil_weakrand_state {
278275970Scy	ev_uint32_t seed;
279275970Scy};
280275970Scy
281275970Scy#define EVUTIL_WEAKRAND_MAX EV_INT32_MAX
282275970Scy
283275970Scy/* Initialize the state of a week random number generator based on 'seed'.  If
284275970Scy * the seed is 0, construct a new seed based on not-very-strong platform
285275970Scy * entropy, like the PID and the time of day.
286275970Scy *
287275970Scy * This function, and the other evutil_weakrand* functions, are meant for
288275970Scy * speed, not security or statistical strength.  If you need a RNG which an
289275970Scy * attacker can't predict, or which passes strong statistical tests, use the
290275970Scy * evutil_secure_rng* functions instead.
291275970Scy */
292275970Scyev_uint32_t evutil_weakrand_seed_(struct evutil_weakrand_state *state, ev_uint32_t seed);
293275970Scy/* Return a pseudorandom value between 0 and EVUTIL_WEAKRAND_MAX inclusive.
294275970Scy * Updates the state in 'seed' as needed -- this value must be protected by a
295275970Scy * lock.
296275970Scy */
297275970Scyev_int32_t evutil_weakrand_(struct evutil_weakrand_state *seed);
298275970Scy/* Return a pseudorandom value x such that 0 <= x < top. top must be no more
299275970Scy * than EVUTIL_WEAKRAND_MAX. Updates the state in 'seed' as needed -- this
300275970Scy * value must be proteced by a lock */
301275970Scyev_int32_t evutil_weakrand_range_(struct evutil_weakrand_state *seed, ev_int32_t top);
302275970Scy
303275970Scy/* Evaluates to the same boolean value as 'p', and hints to the compiler that
304275970Scy * we expect this value to be false. */
305275970Scy#if defined(__GNUC__) && __GNUC__ >= 3         /* gcc 3.0 or later */
306275970Scy#define EVUTIL_UNLIKELY(p) __builtin_expect(!!(p),0)
307275970Scy#else
308275970Scy#define EVUTIL_UNLIKELY(p) (p)
309275970Scy#endif
310275970Scy
311275970Scy/* Replacement for assert() that calls event_errx on failure. */
312275970Scy#ifdef NDEBUG
313275970Scy#define EVUTIL_ASSERT(cond) EVUTIL_NIL_CONDITION_(cond)
314275970Scy#define EVUTIL_FAILURE_CHECK(cond) 0
315275970Scy#else
316275970Scy#define EVUTIL_ASSERT(cond)						\
317275970Scy	do {								\
318275970Scy		if (EVUTIL_UNLIKELY(!(cond))) {				\
319275970Scy			event_errx(EVENT_ERR_ABORT_,			\
320275970Scy			    "%s:%d: Assertion %s failed in %s",		\
321275970Scy			    __FILE__,__LINE__,#cond,__func__);		\
322275970Scy			/* In case a user-supplied handler tries to */	\
323275970Scy			/* return control to us, log and abort here. */	\
324275970Scy			(void)fprintf(stderr,				\
325275970Scy			    "%s:%d: Assertion %s failed in %s",		\
326275970Scy			    __FILE__,__LINE__,#cond,__func__);		\
327275970Scy			abort();					\
328275970Scy		}							\
329275970Scy	} while (0)
330275970Scy#define EVUTIL_FAILURE_CHECK(cond) EVUTIL_UNLIKELY(cond)
331275970Scy#endif
332275970Scy
333275970Scy#ifndef EVENT__HAVE_STRUCT_SOCKADDR_STORAGE
334275970Scy/* Replacement for sockaddr storage that we can use internally on platforms
335275970Scy * that lack it.  It is not space-efficient, but neither is sockaddr_storage.
336275970Scy */
337275970Scystruct sockaddr_storage {
338275970Scy	union {
339275970Scy		struct sockaddr ss_sa;
340275970Scy		struct sockaddr_in ss_sin;
341275970Scy		struct sockaddr_in6 ss_sin6;
342275970Scy		char ss_padding[128];
343275970Scy	} ss_union;
344275970Scy};
345275970Scy#define ss_family ss_union.ss_sa.sa_family
346275970Scy#endif
347275970Scy
348275970Scy/* Internal addrinfo error code.  This one is returned from only from
349275970Scy * evutil_getaddrinfo_common_, when we are sure that we'll have to hit a DNS
350275970Scy * server. */
351275970Scy#define EVUTIL_EAI_NEED_RESOLVE      -90002
352275970Scy
353275970Scystruct evdns_base;
354275970Scystruct evdns_getaddrinfo_request;
355275970Scytypedef struct evdns_getaddrinfo_request* (*evdns_getaddrinfo_fn)(
356275970Scy    struct evdns_base *base,
357275970Scy    const char *nodename, const char *servname,
358275970Scy    const struct evutil_addrinfo *hints_in,
359275970Scy    void (*cb)(int, struct evutil_addrinfo *, void *), void *arg);
360275970Scy
361275970Scyvoid evutil_set_evdns_getaddrinfo_fn_(evdns_getaddrinfo_fn fn);
362275970Scy
363275970Scystruct evutil_addrinfo *evutil_new_addrinfo_(struct sockaddr *sa,
364275970Scy    ev_socklen_t socklen, const struct evutil_addrinfo *hints);
365275970Scystruct evutil_addrinfo *evutil_addrinfo_append_(struct evutil_addrinfo *first,
366275970Scy    struct evutil_addrinfo *append);
367275970Scyvoid evutil_adjust_hints_for_addrconfig_(struct evutil_addrinfo *hints);
368275970Scyint evutil_getaddrinfo_common_(const char *nodename, const char *servname,
369275970Scy    struct evutil_addrinfo *hints, struct evutil_addrinfo **res, int *portnum);
370275970Scy
371275970Scyint evutil_getaddrinfo_async_(struct evdns_base *dns_base,
372275970Scy    const char *nodename, const char *servname,
373275970Scy    const struct evutil_addrinfo *hints_in,
374275970Scy    void (*cb)(int, struct evutil_addrinfo *, void *), void *arg);
375275970Scy
376275970Scy/** Return true iff sa is a looback address. (That is, it is 127.0.0.1/8, or
377275970Scy * ::1). */
378275970Scyint evutil_sockaddr_is_loopback_(const struct sockaddr *sa);
379275970Scy
380275970Scy
381275970Scy/**
382275970Scy    Formats a sockaddr sa into a string buffer of size outlen stored in out.
383275970Scy    Returns a pointer to out.  Always writes something into out, so it's safe
384275970Scy    to use the output of this function without checking it for NULL.
385275970Scy */
386275970Scyconst char *evutil_format_sockaddr_port_(const struct sockaddr *sa, char *out, size_t outlen);
387275970Scy
388275970Scyint evutil_hex_char_to_int_(char c);
389275970Scy
390275970Scy
391275970Scyvoid evutil_free_secure_rng_globals_(void);
392275970Scyvoid evutil_free_globals_(void);
393275970Scy
394275970Scy#ifdef _WIN32
395282408ScyHMODULE evutil_load_windows_system_library_(const TCHAR *library_name);
396275970Scy#endif
397275970Scy
398275970Scy#ifndef EV_SIZE_FMT
399275970Scy#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__)
400275970Scy#define EV_U64_FMT "%I64u"
401275970Scy#define EV_I64_FMT "%I64d"
402275970Scy#define EV_I64_ARG(x) ((__int64)(x))
403275970Scy#define EV_U64_ARG(x) ((unsigned __int64)(x))
404275970Scy#else
405275970Scy#define EV_U64_FMT "%llu"
406275970Scy#define EV_I64_FMT "%lld"
407275970Scy#define EV_I64_ARG(x) ((long long)(x))
408275970Scy#define EV_U64_ARG(x) ((unsigned long long)(x))
409275970Scy#endif
410275970Scy#endif
411275970Scy
412275970Scy#ifdef _WIN32
413275970Scy#define EV_SOCK_FMT EV_I64_FMT
414275970Scy#define EV_SOCK_ARG(x) EV_I64_ARG((x))
415275970Scy#else
416275970Scy#define EV_SOCK_FMT "%d"
417275970Scy#define EV_SOCK_ARG(x) (x)
418275970Scy#endif
419275970Scy
420275970Scy#if defined(__STDC__) && defined(__STDC_VERSION__)
421275970Scy#if (__STDC_VERSION__ >= 199901L)
422275970Scy#define EV_SIZE_FMT "%zu"
423275970Scy#define EV_SSIZE_FMT "%zd"
424275970Scy#define EV_SIZE_ARG(x) (x)
425275970Scy#define EV_SSIZE_ARG(x) (x)
426275970Scy#endif
427275970Scy#endif
428275970Scy
429275970Scy#ifndef EV_SIZE_FMT
430275970Scy#if (EVENT__SIZEOF_SIZE_T <= EVENT__SIZEOF_LONG)
431275970Scy#define EV_SIZE_FMT "%lu"
432275970Scy#define EV_SSIZE_FMT "%ld"
433275970Scy#define EV_SIZE_ARG(x) ((unsigned long)(x))
434275970Scy#define EV_SSIZE_ARG(x) ((long)(x))
435275970Scy#else
436275970Scy#define EV_SIZE_FMT EV_U64_FMT
437275970Scy#define EV_SSIZE_FMT EV_I64_FMT
438275970Scy#define EV_SIZE_ARG(x) EV_U64_ARG(x)
439275970Scy#define EV_SSIZE_ARG(x) EV_I64_ARG(x)
440275970Scy#endif
441275970Scy#endif
442275970Scy
443275970Scyevutil_socket_t evutil_socket_(int domain, int type, int protocol);
444275970Scyevutil_socket_t evutil_accept4_(evutil_socket_t sockfd, struct sockaddr *addr,
445275970Scy    ev_socklen_t *addrlen, int flags);
446275970Scy
447275970Scy    /* used by one of the test programs.. */
448275970ScyEVENT2_EXPORT_SYMBOL
449275970Scyint evutil_make_internal_pipe_(evutil_socket_t fd[2]);
450275970Scyevutil_socket_t evutil_eventfd_(unsigned initval, int flags);
451275970Scy
452275970Scy#ifdef SOCK_NONBLOCK
453275970Scy#define EVUTIL_SOCK_NONBLOCK SOCK_NONBLOCK
454275970Scy#else
455275970Scy#define EVUTIL_SOCK_NONBLOCK 0x4000000
456275970Scy#endif
457275970Scy#ifdef SOCK_CLOEXEC
458275970Scy#define EVUTIL_SOCK_CLOEXEC SOCK_CLOEXEC
459275970Scy#else
460275970Scy#define EVUTIL_SOCK_CLOEXEC 0x80000000
461275970Scy#endif
462275970Scy#ifdef EFD_NONBLOCK
463275970Scy#define EVUTIL_EFD_NONBLOCK EFD_NONBLOCK
464275970Scy#else
465275970Scy#define EVUTIL_EFD_NONBLOCK 0x4000
466275970Scy#endif
467275970Scy#ifdef EFD_CLOEXEC
468275970Scy#define EVUTIL_EFD_CLOEXEC EFD_CLOEXEC
469275970Scy#else
470275970Scy#define EVUTIL_EFD_CLOEXEC 0x8000
471275970Scy#endif
472275970Scy
473275970Scyvoid evutil_memclear_(void *mem, size_t len);
474275970Scy
475275970Scy#ifdef __cplusplus
476275970Scy}
477275970Scy#endif
478275970Scy
479275970Scy#endif
480