This source file includes following definitions.
- uv_handle_size
- uv_req_size
- uv_strlcpy
- uv_strlcat
- uv_buf_init
- uv_err_name
- uv_strerror
- uv_ip4_addr
- uv_ip6_addr
- uv_ip4_name
- uv_ip6_name
- uv_tcp_bind
- uv_tcp_bind6
- uv_udp_bind
- uv_udp_bind6
- uv_tcp_connect
- uv_tcp_connect6
- uv_udp_send
- uv_udp_send6
- uv_udp_recv_start
- uv_udp_recv_stop
- uv__thread_start
- uv_thread_create
- uv_thread_self
- uv_walk
- uv__print_handles
- uv_print_all_handles
- uv_print_active_handles
- uv_ref
- uv_unref
- uv_has_ref
- uv_stop
- uv_now
- uv__getaddrinfo_translate_error
#include "uv.h"
#include "uv-common.h"
#include <stdio.h>
#include <assert.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#if defined(UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS) && !defined(_WIN32)
# include <net/if.h>
#endif
#if !defined(_WIN32)
# include <sys/types.h>
# include <sys/socket.h>
# include <netdb.h>
#endif
#define XX(uc, lc) case UV_##uc: return sizeof(uv_##lc##_t);
size_t uv_handle_size(uv_handle_type type) {
switch (type) {
UV_HANDLE_TYPE_MAP(XX)
default:
return -1;
}
}
size_t uv_req_size(uv_req_type type) {
switch(type) {
UV_REQ_TYPE_MAP(XX)
default:
return -1;
}
}
#undef XX
size_t uv_strlcpy(char* dst, const char* src, size_t size) {
size_t n;
if (size == 0)
return 0;
for (n = 0; n < (size - 1) && *src != '\0'; n++)
*dst++ = *src++;
*dst = '\0';
return n;
}
size_t uv_strlcat(char* dst, const char* src, size_t size) {
size_t n;
if (size == 0)
return 0;
for (n = 0; n < size && *dst != '\0'; n++, dst++);
if (n == size)
return n;
while (n < (size - 1) && *src != '\0')
n++, *dst++ = *src++;
*dst = '\0';
return n;
}
uv_buf_t uv_buf_init(char* base, unsigned int len) {
uv_buf_t buf;
buf.base = base;
buf.len = len;
return buf;
}
#define UV_ERR_NAME_GEN(name, _) case UV_ ## name: return #name;
const char* uv_err_name(int err) {
switch (err) {
UV_ERRNO_MAP(UV_ERR_NAME_GEN)
default:
assert(0);
return NULL;
}
}
#undef UV_ERR_NAME_GEN
#define UV_STRERROR_GEN(name, msg) case UV_ ## name: return msg;
const char* uv_strerror(int err) {
switch (err) {
UV_ERRNO_MAP(UV_STRERROR_GEN)
default:
return "Unknown system error";
}
}
#undef UV_STRERROR_GEN
struct sockaddr_in uv_ip4_addr(const char* ip, int port) {
struct sockaddr_in addr;
memset(&addr, 0, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr(ip);
return addr;
}
struct sockaddr_in6 uv_ip6_addr(const char* ip, int port) {
struct sockaddr_in6 addr;
#if defined(UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS)
char address_part[40];
size_t address_part_size;
const char* zone_index;
#endif
memset(&addr, 0, sizeof(struct sockaddr_in6));
addr.sin6_family = AF_INET6;
addr.sin6_port = htons(port);
#if defined(UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS)
zone_index = strchr(ip, '%');
if (zone_index != NULL) {
address_part_size = zone_index - ip;
if (address_part_size >= sizeof(address_part))
address_part_size = sizeof(address_part) - 1;
memcpy(address_part, ip, address_part_size);
address_part[address_part_size] = '\0';
ip = address_part;
zone_index++;
#ifdef _WIN32
addr.sin6_scope_id = atoi(zone_index);
#else
addr.sin6_scope_id = if_nametoindex(zone_index);
#endif
}
#endif
uv_inet_pton(AF_INET6, ip, &addr.sin6_addr);
return addr;
}
int uv_ip4_name(struct sockaddr_in* src, char* dst, size_t size) {
return uv_inet_ntop(AF_INET, &src->sin_addr, dst, size);
}
int uv_ip6_name(struct sockaddr_in6* src, char* dst, size_t size) {
return uv_inet_ntop(AF_INET6, &src->sin6_addr, dst, size);
}
int uv_tcp_bind(uv_tcp_t* handle, struct sockaddr_in addr) {
if (handle->type != UV_TCP || addr.sin_family != AF_INET)
return UV_EINVAL;
else
return uv__tcp_bind(handle, addr);
}
int uv_tcp_bind6(uv_tcp_t* handle, struct sockaddr_in6 addr) {
if (handle->type != UV_TCP || addr.sin6_family != AF_INET6)
return UV_EINVAL;
else
return uv__tcp_bind6(handle, addr);
}
int uv_udp_bind(uv_udp_t* handle,
struct sockaddr_in addr,
unsigned int flags) {
if (handle->type != UV_UDP || addr.sin_family != AF_INET)
return UV_EINVAL;
else
return uv__udp_bind(handle, addr, flags);
}
int uv_udp_bind6(uv_udp_t* handle,
struct sockaddr_in6 addr,
unsigned int flags) {
if (handle->type != UV_UDP || addr.sin6_family != AF_INET6)
return UV_EINVAL;
else
return uv__udp_bind6(handle, addr, flags);
}
int uv_tcp_connect(uv_connect_t* req,
uv_tcp_t* handle,
struct sockaddr_in address,
uv_connect_cb cb) {
if (handle->type != UV_TCP || address.sin_family != AF_INET)
return UV_EINVAL;
else
return uv__tcp_connect(req, handle, address, cb);
}
int uv_tcp_connect6(uv_connect_t* req,
uv_tcp_t* handle,
struct sockaddr_in6 address,
uv_connect_cb cb) {
if (handle->type != UV_TCP || address.sin6_family != AF_INET6)
return UV_EINVAL;
else
return uv__tcp_connect6(req, handle, address, cb);
}
int uv_udp_send(uv_udp_send_t* req,
uv_udp_t* handle,
uv_buf_t bufs[],
int bufcnt,
struct sockaddr_in addr,
uv_udp_send_cb send_cb) {
if (handle->type != UV_UDP || addr.sin_family != AF_INET)
return UV_EINVAL;
else
return uv__udp_send(req, handle, bufs, bufcnt, addr, send_cb);
}
int uv_udp_send6(uv_udp_send_t* req,
uv_udp_t* handle,
uv_buf_t bufs[],
int bufcnt,
struct sockaddr_in6 addr,
uv_udp_send_cb send_cb) {
if (handle->type != UV_UDP || addr.sin6_family != AF_INET6)
return UV_EINVAL;
else
return uv__udp_send6(req, handle, bufs, bufcnt, addr, send_cb);
}
int uv_udp_recv_start(uv_udp_t* handle,
uv_alloc_cb alloc_cb,
uv_udp_recv_cb recv_cb) {
if (handle->type != UV_UDP || alloc_cb == NULL || recv_cb == NULL)
return UV_EINVAL;
else
return uv__udp_recv_start(handle, alloc_cb, recv_cb);
}
int uv_udp_recv_stop(uv_udp_t* handle) {
if (handle->type != UV_UDP)
return UV_EINVAL;
else
return uv__udp_recv_stop(handle);
}
struct thread_ctx {
void (*entry)(void* arg);
void* arg;
};
#ifdef _WIN32
static UINT __stdcall uv__thread_start(void* arg)
#else
static void* uv__thread_start(void *arg)
#endif
{
struct thread_ctx *ctx_p;
struct thread_ctx ctx;
ctx_p = arg;
ctx = *ctx_p;
free(ctx_p);
ctx.entry(ctx.arg);
return 0;
}
int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) {
struct thread_ctx* ctx;
int err;
ctx = malloc(sizeof(*ctx));
if (ctx == NULL)
return UV_ENOMEM;
ctx->entry = entry;
ctx->arg = arg;
#ifdef _WIN32
*tid = (HANDLE) _beginthreadex(NULL, 0, uv__thread_start, ctx, 0, NULL);
err = *tid ? 0 : errno;
#else
err = pthread_create(tid, NULL, uv__thread_start, ctx);
#endif
if (err)
free(ctx);
return err ? -1 : 0;
}
unsigned long uv_thread_self(void) {
#ifdef _WIN32
return (unsigned long) GetCurrentThreadId();
#else
return (unsigned long) pthread_self();
#endif
}
void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg) {
QUEUE* q;
uv_handle_t* h;
QUEUE_FOREACH(q, &loop->handle_queue) {
h = QUEUE_DATA(q, uv_handle_t, handle_queue);
if (h->flags & UV__HANDLE_INTERNAL) continue;
walk_cb(h, arg);
}
}
#ifndef NDEBUG
static void uv__print_handles(uv_loop_t* loop, int only_active) {
const char* type;
QUEUE* q;
uv_handle_t* h;
if (loop == NULL)
loop = uv_default_loop();
QUEUE_FOREACH(q, &loop->handle_queue) {
h = QUEUE_DATA(q, uv_handle_t, handle_queue);
if (only_active && !uv__is_active(h))
continue;
switch (h->type) {
#define X(uc, lc) case UV_##uc: type = #lc; break;
UV_HANDLE_TYPE_MAP(X)
#undef X
default: type = "<unknown>";
}
fprintf(stderr,
"[%c%c%c] %-8s %p\n",
"R-"[!(h->flags & UV__HANDLE_REF)],
"A-"[!(h->flags & UV__HANDLE_ACTIVE)],
"I-"[!(h->flags & UV__HANDLE_INTERNAL)],
type,
(void*)h);
}
}
void uv_print_all_handles(uv_loop_t* loop) {
uv__print_handles(loop, 0);
}
void uv_print_active_handles(uv_loop_t* loop) {
uv__print_handles(loop, 1);
}
#endif
void uv_ref(uv_handle_t* handle) {
uv__handle_ref(handle);
}
void uv_unref(uv_handle_t* handle) {
uv__handle_unref(handle);
}
int uv_has_ref(const uv_handle_t* handle) {
return uv__has_ref(handle);
}
void uv_stop(uv_loop_t* loop) {
loop->stop_flag = 1;
}
uint64_t uv_now(uv_loop_t* loop) {
return loop->time;
}
int uv__getaddrinfo_translate_error(int sys_err) {
switch (sys_err) {
case 0: return 0;
#if defined(EAI_ADDRFAMILY)
case EAI_ADDRFAMILY: return UV_EAI_ADDRFAMILY;
#endif
#if defined(EAI_AGAIN)
case EAI_AGAIN: return UV_EAI_AGAIN;
#endif
#if defined(EAI_BADFLAGS)
case EAI_BADFLAGS: return UV_EAI_BADFLAGS;
#endif
#if defined(EAI_CANCELED)
case EAI_CANCELED: return UV_EAI_CANCELED;
#endif
#if defined(EAI_FAIL)
case EAI_FAIL: return UV_EAI_FAIL;
#endif
#if defined(EAI_FAMILY)
case EAI_FAMILY: return UV_EAI_FAMILY;
#endif
#if defined(EAI_MEMORY)
case EAI_MEMORY: return UV_EAI_MEMORY;
#endif
#if defined(EAI_NODATA)
case EAI_NODATA: return UV_EAI_NODATA;
#endif
#if defined(EAI_NONAME)
# if !defined(EAI_NODATA) || EAI_NODATA != EAI_NONAME
case EAI_NONAME: return UV_EAI_NONAME;
# endif
#endif
#if defined(EAI_SERVICE)
case EAI_SERVICE: return UV_EAI_SERVICE;
#endif
#if defined(EAI_SOCKTYPE)
case EAI_SOCKTYPE: return UV_EAI_SOCKTYPE;
#endif
#if defined(EAI_SYSTEM)
case EAI_SYSTEM: return UV_EAI_SYSTEM;
#endif
}
assert(!"unknown EAI_* error code");
abort();
return 0;
}