1. Basic types

Evutil_socket_t:

Socket handles on systems other than Windows are an int, and Windows is a type defined by a specific socket API

#ifdef WIN32
#define evutil_socket_t intptr_t
#else
#define evutil_socket_t int
#endif
Copy the code

Standard integer type: compatible with pre-C99 systems

The title Width Signed Maximum Minimum
ev_uint64_t 64 No EV_UINT64_MAX 0
ev_int64_t 64 Yes EV_INT64_MAX EV_INT64_MIN
ev_uint32_t 32 No EV_UINT32_MAX 0
ev_int32_t 32 Yes EV_INT32_MAX EV_INT32_MIN
ev_uint16_t 16 No EV_UINT16_MAX 0
ev_int16_t 16 Yes EV_INT16_MAX EV_INT16_MIN
ev_uint8_t 8 No EV_UINT8_MAX 0
ev_int8_t 8 Yes EV_INT8_MAX EV_INT8_MIN

2 timer portable function

Timeval is not defined on all systems. On Linux, timeval is included in <time.h>

\\linux
struct timeval
{
     __time_t tv_sec;                /* Seconds. */
     __suseconds_t tv_usec;      /* Microseconds. */
};
Copy the code

Where, tv_sec is the number of seconds from the Epoch (1970-1-1 zero zero minute) to the creation of struct timeval, and tv_usec is the number of microseconds, that is, the odd digit after the second. To meet the cross-platform requirements, Libevent implements the following timeVal functionality

#define evutil_timeradd(tvp, uvp, vvp) / *... * /#define evutil_timerSub (TVP, UVP, VVP)/ *... * /\\ Time minus #define Evutil_timerClear (TVP)/ *... * /\ \ clear0
#define evutil_timerisset(tvp) / *... * /\\ Check whether the time is0,0returntrue#define evutil_timercmp(TVP, uvp, CMP) \\ time compare int evutil_gettimeofday(struct timeval * TV, struct timezone *tz); \\ Get the current time through TV without tzCopy the code

Sample code:

//BUILD: FUNCTIONBODY INC:event2/util.h INC:stdio.h
.Example
[code,C]
--------
struct timeval tv1, tv2, tv3;

/* Set tv1 = 5.5 seconds */
tv1.tv_sec = 5; tv1.tv_usec = 500*1000;

/* Set tv2 = now */
evutil_gettimeofday(&tv2, NULL);

/* Set tv3 = 5.5 seconds in the future */
evutil_timeradd(&tv1, &tv2, &tv3);

/* all 3 should print true */
if (evutil_timercmp(&tv1, &tv1, ==))  /* == "If tv1 == tv1" */
   puts("5.5 sec == 5.5 sec");
if (evutil_timercmp(&tv3, &tv2, >=))  /* == "If tv3 >= tv2" */
   puts("The future is after the present.");
if (evutil_timercmp(&tv1, &tv2, <))   /* == "If tv1 < tv2" */
   puts("It is no longer the past.");
Copy the code

3. Socket API compatibility

int evutil_closesocket(evutil_socket_t s); #define EVUTIL_CLOSESOCKET(s) EVUTIL_CLOSESOCKET(s) \\ Socket closing functions compatible with Windows and other platformsCopy the code
#define EVUTIL_SOCKET_ERROR() \\ Returns a global error number for the last socket operation of this thread #define EVUTIL_SET_SOCKET_ERROR(errcode) \\ Returns an error number for a specified socket #define Evutil_socket_geterror (sock) \ change the current socket error number #define evutil_socket_error_to_string(errcode) \\ Returns the error number of a specified socket as a stringCopy the code
int evutil_make_socket_nonblocking(evutil_socket_t sock); \\ socket non-blocking IO call int evutil_make_listen_socket_reuseable(evutil_socket_t sock); Int evutil_make_socket_closeonexec(evutil_socket_t sock); \\ If exec() is called, the specified socket should be closed. int evutil_socketpair(int family, int type, int protocol,evutil_socket_t sv[2]); \\ Creates two interconnected sockets that can be used with normal socket IO calls.Copy the code

Portable string manipulation functions

ev_int64_t evutil_strtoll(constchar *s, char **endptr, int base); \\ Similar to strtol,base is baseCopy the code
int evutil_snprintf(char *buf, size_t buflen, constchar *format, ...) ; \\ replace snprintf int evutil_vsnprintf(char *buf, size_t buflen,constchar *format, va_list ap); \ \ vsnsprintf insteadCopy the code
\\ Always compare using ASCII character sets int evutil_ASCIi_strcasecmp (const char *str1, const char *str2);
int evutil_ascii_strncasecmp(const char *str1, const char *str2, size_t n);
Copy the code

5.IPV6 assistance and compatibility functions

These functions parse and format IPv4 and IPv6 addresses as specified in RFC 3493 and behave the same as the standard inet_ntop() and inet_pton() functions.

const char *evutil_inet_ntop(int af, const void *src, char *dst, size_t len);
int evutil_inet_pton(int af, const char *src, void *dst);

int evutil_parse_sockaddr_port(const char *str, struct sockaddr *out,
    int *outlen);

int evutil_sockaddr_cmp(const struct sockaddr *sa1,
    const struct sockaddr *sa2, int include_port);
Copy the code

6. Structure portability function

Instead of the standard offsetof macro

#define evutil_offsetof(type, field) / *... * /
Copy the code

7. Random number generator

This function fills n bytes at buf with random data. If the platform provides arc4Random (), libevent uses this function. Otherwise, libevent uses its own arc4Random () implementation, the seed of which comes from the operating system’s entropy pool (CryptGenRandom on Windows, /dev/urandom on other platforms)

There is no need to initialize the secure random number generator manually, but evutil_secure_rng_init() can be called to verify that it has been successfully initialized. The function seeds RNG (if not sown) and returns 0 on success. The function returns -1 to indicate that libevent cannot find an appropriate source of entropy in the operating system and cannot safely use RNG without initializing it itself.

If the program is running in an environment where permission could be relinquashed (for example, by chroot()), evutil_secure_rng_init() should be called before permission is relinquashed. Evutil_secure_rng_add_bytes () can be called to add more random bytes to the entropy pool, but this is not usually necessary.

void evutil_secure_rng_get_bytes(void*buf, size_t n); \\ Fill n bytes at buf with random data int evutil_secure_rng_init(void);
void evutil_secure_rng_add_bytes(const char *dat, size_t datlen);
Copy the code