libevent reference Mannual IV --Helper functions and types

FYI: http://www.wangafu.net/~nickm/libevent-book/Ref5_evutil.html

Helper functions and types for Libevent

Basic types

1 #ifdef WIN32
2 #define evutil_socket_t intptr_t
3 #else
4 #define evutil_socket_t int
5 #endif

Miscellaneous compatibility types

The ev_ssize_t type is defined to ssize_t (signed size_t) on platforms that have one, and to a reasonable default on platforms that don’t. The largest possible value of ev_ssize_t is EV_SSIZE_MAX; the smallest is EV_SSIZE_MIN. (The largest possible value for size_t is EV_SIZE_MAX, in case your platform doesn’t define a SIZE_MAX for you.)

The ev_off_t type is used to represent offset into a file or a chunk of memory. It is defined to off_t on platforms with a reasonable off_t definition, and to ev_int64_t on Windows.

Some implementations of the sockets API provide a length type, socklen_t, and some do not. The ev_socklen_t is defined to this type where it exists, and a reasonable default otherwise.

The ev_intptr_t type is a signed integer that is large enough to hold a pointer without loss of bits. The ev_uintptr_t type is an unsigned integer large enough to hold a pointer without loss of bits.

Timer portability functions

1 #define evutil_timeradd(tvp, uvp, vvp) /* .+. */
2 #define evutil_timersub(tvp, uvp, vvp) /* .-. */
3 #define evutil_timerclear(tvp) /* .clear. */
4 #define evutil_timerisset(tvp) /* .clear. */
5 #define evutil_timercmp(tvp, uvp, cmp) /* <=, <, ==, >, >=, !=*/
6 int evutil_gettimeofday(struct timeval *tv, struct timezone *tz);
Note It wasn’t safe to use ⇐ or >= with timercmp before Libevent 1.4.4.

Socket API compatibility

This section exists because, for historical reasons, Windows has never really implemented the Berkeley sockets API in a nice compatible (and nicely compatible) way. Here are some functions you can use in order to pretend that it has.

Interface
1 int evutil_closesocket(evutil_socket_t s);
2 #define EVUTIL_CLOSESOCKET(s) evutil_closesocket(s)
3 #define EVUTIL_SOCKET_ERROR()
4 #define EVUTIL_SET_SOCKET_ERROR(errcode)
5 #define evutil_socket_geterror(sock)
6 #define evutil_socket_error_to_string(errcode)

These macros access and manipulate socket error codes. EVUTIL_SOCKET_ERROR() returns the global error code for the last socket operation from this thread, and evutil_socket_geterror() does so for a particular socket. (Both are errno on Unix-like systems.) EVUTIL_SET_SOCKET_ERROR() changes the current socket error code (like setting errno on Unix), and evutil_socket_error_to_string() returns a string representation of a given socket error code (like strerror() on Unix).

(We need these functions because Windows doesn’t use errno for errors from socket functions, but instead uses WSAGetLastError().)

Note that the Windows socket errors are not the same as the standard-C errors you would see in errno; watch out.

Interface
1 int evutil_make_socket_nonblocking(evutil_socket_t sock);

Even the call you need to do nonblocking IO on a socket is not portable to Windows. The evutil_make_socket_nonblocking() function takes a new socket (from socket() or accept()) and turns it into a nonblocking socket. (It sets O_NONBLOCK on Unix and FIONBIO on Windows.)

Interface
int evutil_make_listen_socket_reuseable(evutil_socket_t sock);

This function makes sure that the address used by a listener socket will be available to another socket immediately after the socket is closed. (It sets SO_REUSEADDR on Unix and does nothing on Windows. You don’t want to use SO_REUSEADDR on Windows; it means something different there.)

Interface
int evutil_make_socket_closeonexec(evutil_socket_t sock);

This call tells the operating system that this socket should be closed if we ever call exec(). It sets the FD_CLOEXEC flag on Unix, and does nothing on Windows.

Interface
int evutil_socketpair(int family, int type, int protocol, evutil_socket_t sv[2]);

This function behaves as the Unix socketpair() call: it makes two sockets that are connected with each other and can be used with ordinary socket IO calls. It stores the two sockets in sv[0] and sv[1], and returns 0 for success and -1 for failure.

On Windows, this only supports family AF_INET, type SOCK_STREAM, and protocol 0. Note that this can fail on some Windows hosts where firewall software has cleverly firewalled 127.0.0.1 to keep the host from talking to itself.

Portable string manipulation functions

1 ev_int64_t evutil_strtoll(const char *s, char **endptr, int base);
2 int evutil_snprintf(char *buf, size_t buflen, const char *format, ...);
3 int evutil_vsnprintf(char *buf, size_t buflen, const char *format, va_list ap);

Locale-independent string manipulation functions

Sometimes, when implementing ASCII-based protocols, you want to manipulate strings according to ASCII’s notion of character type, regardless of your current locale. Libevent provides a few functions to help with this:

Interface
1 int evutil_ascii_strcasecmp(const char *str1, const char *str2);
2 int evutil_ascii_strncasecmp(const char *str1, const char *str2, size_t n);

IPv6 helper and portability functions

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

These functions behave as the standard inet_ntop() and inet_pton() functions for parsing and formatting IPv4 and IPv6 addresses, as specified in RFC3493.

evutil_inet_ntop():

an IPv4 address,  af set to AF_INET, src pointing to a struct in_addr, and dst pointing to a character buffer of size len.

an IPv6 address, af is AF_INET6 and src is a struct in6_addr.

To parse an IPv4 address, call evutil_inet_pton() with af set to AF_INET or AF_INET6, the string to parse in src, and dst pointing to an in_addr or an in_addr6 as appropriate.

The return value from evutil_inet_ntop() is NULL on failure and otherwise points to dst. The return value from evutil_inet_pton() is 0 on success and -1 on failure.

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

This function parses an address from str and writes the result to out. The outlen argument must point to an integer holding the number of bytes available in out; it is altered to hold the number of bytes actually used. This function returns 0 on success and -1 on failure. It recognizes the following address formats:

  • [ipv6]:port (as in "[ffff::]:80")

  • ipv6 (as in "ffff::")

  • [ipv6] (as in "[ffff::]")

  • ipv4:port (as in "1.2.3.4:80")

  • ipv4 (as in "1.2.3.4")

If no port is given, the port in the resulting sockaddr is set to 0.

Interface
int evutil_sockaddr_cmp(const struct sockaddr *sa1,
    const struct sockaddr *sa2, int include_port);

The evutil_sockaddr_cmp() function compares two addresses, and returns negative if sa1 precedes sa2, 0 if they are equal, and positive if sa2 precedes sa1. It works for AF_INET and AF_INET6 addresses, and returns undefined output for other addresses. It’s guaranteed to give a total order for these addresses, but the ordering may change between Libevent versions.

If the include_port argument is false, then two sockaddrs are treated as equal if they differ only in their port. Otherwise, sockaddrs with different ports are treated as unequal.

Structure macro portability functions

Interface
#define evutil_offsetof(type, field) /* ... */

As the standard offsetof macro, this macro yields the number of bytes from the start of type at which field occurs.

This macro was introduced in Libevent 2.0.1-alpha. It was buggy in every version before Libevent 2.0.3-alpha.

Secure random number generator

Many applications (including evdns) need a source of hard-to-predict random numbers for their security.

Interface
void evutil_secure_rng_get_bytes(void *buf, size_t n);

This function fills n-byte buffer at buf with n bytes of random data.

If your platform provides the arc4random() function, Libevent uses that. Otherwise, it uses its own implementation of arc4random(), seeded by your operating system’s entropy pool (CryptGenRandom on Windows, /dev/urandom everywhere else).

Interface
int evutil_secure_rng_init(void);
void evutil_secure_rng_add_bytes(const char *dat, size_t datlen);

You do not need to manually initialize the secure random number generator, but if you want to make sure it is successfully initialized, you can do so by calling evutil_secure_rng_init(). It seeds the RNG (if it was not already seeded) and returns 0 on success. If it returns -1, Libevent wasn’t able to find a good source of entropy on your OS, and you can’t use the RNG safely without initializing it yourself.

 
 
 

猜你喜欢

转载自www.cnblogs.com/tadeas/p/10118194.html
IV