1e66f31c5Sopenharmony_ci/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. 2e66f31c5Sopenharmony_ci * 3e66f31c5Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 4e66f31c5Sopenharmony_ci * of this software and associated documentation files (the "Software"), to 5e66f31c5Sopenharmony_ci * deal in the Software without restriction, including without limitation the 6e66f31c5Sopenharmony_ci * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7e66f31c5Sopenharmony_ci * sell copies of the Software, and to permit persons to whom the Software is 8e66f31c5Sopenharmony_ci * furnished to do so, subject to the following conditions: 9e66f31c5Sopenharmony_ci * 10e66f31c5Sopenharmony_ci * The above copyright notice and this permission notice shall be included in 11e66f31c5Sopenharmony_ci * all copies or substantial portions of the Software. 12e66f31c5Sopenharmony_ci * 13e66f31c5Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14e66f31c5Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15e66f31c5Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16e66f31c5Sopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17e66f31c5Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18e66f31c5Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19e66f31c5Sopenharmony_ci * IN THE SOFTWARE. 20e66f31c5Sopenharmony_ci */ 21e66f31c5Sopenharmony_ci 22e66f31c5Sopenharmony_ci#include "uv.h" 23e66f31c5Sopenharmony_ci#include "uv-common.h" 24e66f31c5Sopenharmony_ci#include "uv_log.h" 25e66f31c5Sopenharmony_ci 26e66f31c5Sopenharmony_ci#include <assert.h> 27e66f31c5Sopenharmony_ci#include <errno.h> 28e66f31c5Sopenharmony_ci#include <stdarg.h> 29e66f31c5Sopenharmony_ci#include <stddef.h> /* NULL */ 30e66f31c5Sopenharmony_ci#include <stdio.h> 31e66f31c5Sopenharmony_ci#include <stdlib.h> /* malloc */ 32e66f31c5Sopenharmony_ci#include <string.h> /* memset */ 33e66f31c5Sopenharmony_ci 34e66f31c5Sopenharmony_ci#if defined(_WIN32) 35e66f31c5Sopenharmony_ci# include <malloc.h> /* malloc */ 36e66f31c5Sopenharmony_ci#else 37e66f31c5Sopenharmony_ci# include <net/if.h> /* if_nametoindex */ 38e66f31c5Sopenharmony_ci# include <sys/un.h> /* AF_UNIX, sockaddr_un */ 39e66f31c5Sopenharmony_ci#endif 40e66f31c5Sopenharmony_ci 41e66f31c5Sopenharmony_ci 42e66f31c5Sopenharmony_citypedef struct { 43e66f31c5Sopenharmony_ci uv_malloc_func local_malloc; 44e66f31c5Sopenharmony_ci uv_realloc_func local_realloc; 45e66f31c5Sopenharmony_ci uv_calloc_func local_calloc; 46e66f31c5Sopenharmony_ci uv_free_func local_free; 47e66f31c5Sopenharmony_ci} uv__allocator_t; 48e66f31c5Sopenharmony_ci 49e66f31c5Sopenharmony_cistatic uv__allocator_t uv__allocator = { 50e66f31c5Sopenharmony_ci malloc, 51e66f31c5Sopenharmony_ci realloc, 52e66f31c5Sopenharmony_ci calloc, 53e66f31c5Sopenharmony_ci free, 54e66f31c5Sopenharmony_ci}; 55e66f31c5Sopenharmony_ci 56e66f31c5Sopenharmony_cichar* uv__strdup(const char* s) { 57e66f31c5Sopenharmony_ci size_t len = strlen(s) + 1; 58e66f31c5Sopenharmony_ci char* m = uv__malloc(len); 59e66f31c5Sopenharmony_ci if (m == NULL) 60e66f31c5Sopenharmony_ci return NULL; 61e66f31c5Sopenharmony_ci return memcpy(m, s, len); 62e66f31c5Sopenharmony_ci} 63e66f31c5Sopenharmony_ci 64e66f31c5Sopenharmony_cichar* uv__strndup(const char* s, size_t n) { 65e66f31c5Sopenharmony_ci char* m; 66e66f31c5Sopenharmony_ci size_t len = strlen(s); 67e66f31c5Sopenharmony_ci if (n < len) 68e66f31c5Sopenharmony_ci len = n; 69e66f31c5Sopenharmony_ci m = uv__malloc(len + 1); 70e66f31c5Sopenharmony_ci if (m == NULL) 71e66f31c5Sopenharmony_ci return NULL; 72e66f31c5Sopenharmony_ci m[len] = '\0'; 73e66f31c5Sopenharmony_ci return memcpy(m, s, len); 74e66f31c5Sopenharmony_ci} 75e66f31c5Sopenharmony_ci 76e66f31c5Sopenharmony_civoid* uv__malloc(size_t size) { 77e66f31c5Sopenharmony_ci if (size > 0) 78e66f31c5Sopenharmony_ci return uv__allocator.local_malloc(size); 79e66f31c5Sopenharmony_ci return NULL; 80e66f31c5Sopenharmony_ci} 81e66f31c5Sopenharmony_ci 82e66f31c5Sopenharmony_civoid uv__free(void* ptr) { 83e66f31c5Sopenharmony_ci int saved_errno; 84e66f31c5Sopenharmony_ci 85e66f31c5Sopenharmony_ci /* Libuv expects that free() does not clobber errno. The system allocator 86e66f31c5Sopenharmony_ci * honors that assumption but custom allocators may not be so careful. 87e66f31c5Sopenharmony_ci */ 88e66f31c5Sopenharmony_ci saved_errno = errno; 89e66f31c5Sopenharmony_ci uv__allocator.local_free(ptr); 90e66f31c5Sopenharmony_ci errno = saved_errno; 91e66f31c5Sopenharmony_ci} 92e66f31c5Sopenharmony_ci 93e66f31c5Sopenharmony_civoid* uv__calloc(size_t count, size_t size) { 94e66f31c5Sopenharmony_ci return uv__allocator.local_calloc(count, size); 95e66f31c5Sopenharmony_ci} 96e66f31c5Sopenharmony_ci 97e66f31c5Sopenharmony_civoid* uv__realloc(void* ptr, size_t size) { 98e66f31c5Sopenharmony_ci if (size > 0) 99e66f31c5Sopenharmony_ci return uv__allocator.local_realloc(ptr, size); 100e66f31c5Sopenharmony_ci uv__free(ptr); 101e66f31c5Sopenharmony_ci return NULL; 102e66f31c5Sopenharmony_ci} 103e66f31c5Sopenharmony_ci 104e66f31c5Sopenharmony_civoid* uv__reallocf(void* ptr, size_t size) { 105e66f31c5Sopenharmony_ci void* newptr; 106e66f31c5Sopenharmony_ci 107e66f31c5Sopenharmony_ci newptr = uv__realloc(ptr, size); 108e66f31c5Sopenharmony_ci if (newptr == NULL) 109e66f31c5Sopenharmony_ci if (size > 0) 110e66f31c5Sopenharmony_ci uv__free(ptr); 111e66f31c5Sopenharmony_ci 112e66f31c5Sopenharmony_ci return newptr; 113e66f31c5Sopenharmony_ci} 114e66f31c5Sopenharmony_ci 115e66f31c5Sopenharmony_ciint uv_replace_allocator(uv_malloc_func malloc_func, 116e66f31c5Sopenharmony_ci uv_realloc_func realloc_func, 117e66f31c5Sopenharmony_ci uv_calloc_func calloc_func, 118e66f31c5Sopenharmony_ci uv_free_func free_func) { 119e66f31c5Sopenharmony_ci if (malloc_func == NULL || realloc_func == NULL || 120e66f31c5Sopenharmony_ci calloc_func == NULL || free_func == NULL) { 121e66f31c5Sopenharmony_ci return UV_EINVAL; 122e66f31c5Sopenharmony_ci } 123e66f31c5Sopenharmony_ci 124e66f31c5Sopenharmony_ci uv__allocator.local_malloc = malloc_func; 125e66f31c5Sopenharmony_ci uv__allocator.local_realloc = realloc_func; 126e66f31c5Sopenharmony_ci uv__allocator.local_calloc = calloc_func; 127e66f31c5Sopenharmony_ci uv__allocator.local_free = free_func; 128e66f31c5Sopenharmony_ci 129e66f31c5Sopenharmony_ci return 0; 130e66f31c5Sopenharmony_ci} 131e66f31c5Sopenharmony_ci 132e66f31c5Sopenharmony_ci 133e66f31c5Sopenharmony_civoid uv_os_free_passwd(uv_passwd_t* pwd) { 134e66f31c5Sopenharmony_ci if (pwd == NULL) 135e66f31c5Sopenharmony_ci return; 136e66f31c5Sopenharmony_ci 137e66f31c5Sopenharmony_ci /* On unix, the memory for name, shell, and homedir are allocated in a single 138e66f31c5Sopenharmony_ci * uv__malloc() call. The base of the pointer is stored in pwd->username, so 139e66f31c5Sopenharmony_ci * that is the field that needs to be freed. 140e66f31c5Sopenharmony_ci */ 141e66f31c5Sopenharmony_ci uv__free(pwd->username); 142e66f31c5Sopenharmony_ci#ifdef _WIN32 143e66f31c5Sopenharmony_ci uv__free(pwd->homedir); 144e66f31c5Sopenharmony_ci#endif 145e66f31c5Sopenharmony_ci pwd->username = NULL; 146e66f31c5Sopenharmony_ci pwd->shell = NULL; 147e66f31c5Sopenharmony_ci pwd->homedir = NULL; 148e66f31c5Sopenharmony_ci} 149e66f31c5Sopenharmony_ci 150e66f31c5Sopenharmony_ci 151e66f31c5Sopenharmony_civoid uv_os_free_group(uv_group_t *grp) { 152e66f31c5Sopenharmony_ci if (grp == NULL) 153e66f31c5Sopenharmony_ci return; 154e66f31c5Sopenharmony_ci 155e66f31c5Sopenharmony_ci /* The memory for is allocated in a single uv__malloc() call. The base of the 156e66f31c5Sopenharmony_ci * pointer is stored in grp->members, so that is the only field that needs to 157e66f31c5Sopenharmony_ci * be freed. 158e66f31c5Sopenharmony_ci */ 159e66f31c5Sopenharmony_ci uv__free(grp->members); 160e66f31c5Sopenharmony_ci grp->members = NULL; 161e66f31c5Sopenharmony_ci grp->groupname = NULL; 162e66f31c5Sopenharmony_ci} 163e66f31c5Sopenharmony_ci 164e66f31c5Sopenharmony_ci 165e66f31c5Sopenharmony_ci#define XX(uc, lc) case UV_##uc: return sizeof(uv_##lc##_t); 166e66f31c5Sopenharmony_ci 167e66f31c5Sopenharmony_cisize_t uv_handle_size(uv_handle_type type) { 168e66f31c5Sopenharmony_ci switch (type) { 169e66f31c5Sopenharmony_ci UV_HANDLE_TYPE_MAP(XX) 170e66f31c5Sopenharmony_ci default: 171e66f31c5Sopenharmony_ci return -1; 172e66f31c5Sopenharmony_ci } 173e66f31c5Sopenharmony_ci} 174e66f31c5Sopenharmony_ci 175e66f31c5Sopenharmony_cisize_t uv_req_size(uv_req_type type) { 176e66f31c5Sopenharmony_ci switch(type) { 177e66f31c5Sopenharmony_ci UV_REQ_TYPE_MAP(XX) 178e66f31c5Sopenharmony_ci default: 179e66f31c5Sopenharmony_ci return -1; 180e66f31c5Sopenharmony_ci } 181e66f31c5Sopenharmony_ci} 182e66f31c5Sopenharmony_ci 183e66f31c5Sopenharmony_ci#undef XX 184e66f31c5Sopenharmony_ci 185e66f31c5Sopenharmony_ci 186e66f31c5Sopenharmony_cisize_t uv_loop_size(void) { 187e66f31c5Sopenharmony_ci return sizeof(uv_loop_t); 188e66f31c5Sopenharmony_ci} 189e66f31c5Sopenharmony_ci 190e66f31c5Sopenharmony_ci 191e66f31c5Sopenharmony_ciuv_buf_t uv_buf_init(char* base, unsigned int len) { 192e66f31c5Sopenharmony_ci uv_buf_t buf; 193e66f31c5Sopenharmony_ci buf.base = base; 194e66f31c5Sopenharmony_ci buf.len = len; 195e66f31c5Sopenharmony_ci return buf; 196e66f31c5Sopenharmony_ci} 197e66f31c5Sopenharmony_ci 198e66f31c5Sopenharmony_ci 199e66f31c5Sopenharmony_cistatic const char* uv__unknown_err_code(int err) { 200e66f31c5Sopenharmony_ci char buf[32]; 201e66f31c5Sopenharmony_ci char* copy; 202e66f31c5Sopenharmony_ci 203e66f31c5Sopenharmony_ci snprintf(buf, sizeof(buf), "Unknown system error %d", err); 204e66f31c5Sopenharmony_ci copy = uv__strdup(buf); 205e66f31c5Sopenharmony_ci 206e66f31c5Sopenharmony_ci return copy != NULL ? copy : "Unknown system error"; 207e66f31c5Sopenharmony_ci} 208e66f31c5Sopenharmony_ci 209e66f31c5Sopenharmony_ci#define UV_ERR_NAME_GEN_R(name, _) \ 210e66f31c5Sopenharmony_cicase UV_## name: \ 211e66f31c5Sopenharmony_ci uv__strscpy(buf, #name, buflen); break; 212e66f31c5Sopenharmony_cichar* uv_err_name_r(int err, char* buf, size_t buflen) { 213e66f31c5Sopenharmony_ci switch (err) { 214e66f31c5Sopenharmony_ci UV_ERRNO_MAP(UV_ERR_NAME_GEN_R) 215e66f31c5Sopenharmony_ci default: snprintf(buf, buflen, "Unknown system error %d", err); 216e66f31c5Sopenharmony_ci } 217e66f31c5Sopenharmony_ci return buf; 218e66f31c5Sopenharmony_ci} 219e66f31c5Sopenharmony_ci#undef UV_ERR_NAME_GEN_R 220e66f31c5Sopenharmony_ci 221e66f31c5Sopenharmony_ci 222e66f31c5Sopenharmony_ci#define UV_ERR_NAME_GEN(name, _) case UV_ ## name: return #name; 223e66f31c5Sopenharmony_ciconst char* uv_err_name(int err) { 224e66f31c5Sopenharmony_ci switch (err) { 225e66f31c5Sopenharmony_ci UV_ERRNO_MAP(UV_ERR_NAME_GEN) 226e66f31c5Sopenharmony_ci } 227e66f31c5Sopenharmony_ci return uv__unknown_err_code(err); 228e66f31c5Sopenharmony_ci} 229e66f31c5Sopenharmony_ci#undef UV_ERR_NAME_GEN 230e66f31c5Sopenharmony_ci 231e66f31c5Sopenharmony_ci 232e66f31c5Sopenharmony_ci#define UV_STRERROR_GEN_R(name, msg) \ 233e66f31c5Sopenharmony_cicase UV_ ## name: \ 234e66f31c5Sopenharmony_ci snprintf(buf, buflen, "%s", msg); break; 235e66f31c5Sopenharmony_cichar* uv_strerror_r(int err, char* buf, size_t buflen) { 236e66f31c5Sopenharmony_ci switch (err) { 237e66f31c5Sopenharmony_ci UV_ERRNO_MAP(UV_STRERROR_GEN_R) 238e66f31c5Sopenharmony_ci default: snprintf(buf, buflen, "Unknown system error %d", err); 239e66f31c5Sopenharmony_ci } 240e66f31c5Sopenharmony_ci return buf; 241e66f31c5Sopenharmony_ci} 242e66f31c5Sopenharmony_ci#undef UV_STRERROR_GEN_R 243e66f31c5Sopenharmony_ci 244e66f31c5Sopenharmony_ci 245e66f31c5Sopenharmony_ci#define UV_STRERROR_GEN(name, msg) case UV_ ## name: return msg; 246e66f31c5Sopenharmony_ciconst char* uv_strerror(int err) { 247e66f31c5Sopenharmony_ci switch (err) { 248e66f31c5Sopenharmony_ci UV_ERRNO_MAP(UV_STRERROR_GEN) 249e66f31c5Sopenharmony_ci } 250e66f31c5Sopenharmony_ci return uv__unknown_err_code(err); 251e66f31c5Sopenharmony_ci} 252e66f31c5Sopenharmony_ci#undef UV_STRERROR_GEN 253e66f31c5Sopenharmony_ci 254e66f31c5Sopenharmony_ci 255e66f31c5Sopenharmony_ciint uv_ip4_addr(const char* ip, int port, struct sockaddr_in* addr) { 256e66f31c5Sopenharmony_ci memset(addr, 0, sizeof(*addr)); 257e66f31c5Sopenharmony_ci addr->sin_family = AF_INET; 258e66f31c5Sopenharmony_ci addr->sin_port = htons(port); 259e66f31c5Sopenharmony_ci#ifdef SIN6_LEN 260e66f31c5Sopenharmony_ci addr->sin_len = sizeof(*addr); 261e66f31c5Sopenharmony_ci#endif 262e66f31c5Sopenharmony_ci return uv_inet_pton(AF_INET, ip, &(addr->sin_addr.s_addr)); 263e66f31c5Sopenharmony_ci} 264e66f31c5Sopenharmony_ci 265e66f31c5Sopenharmony_ci 266e66f31c5Sopenharmony_ciint uv_ip6_addr(const char* ip, int port, struct sockaddr_in6* addr) { 267e66f31c5Sopenharmony_ci char address_part[40]; 268e66f31c5Sopenharmony_ci size_t address_part_size; 269e66f31c5Sopenharmony_ci const char* zone_index; 270e66f31c5Sopenharmony_ci 271e66f31c5Sopenharmony_ci memset(addr, 0, sizeof(*addr)); 272e66f31c5Sopenharmony_ci addr->sin6_family = AF_INET6; 273e66f31c5Sopenharmony_ci addr->sin6_port = htons(port); 274e66f31c5Sopenharmony_ci#ifdef SIN6_LEN 275e66f31c5Sopenharmony_ci addr->sin6_len = sizeof(*addr); 276e66f31c5Sopenharmony_ci#endif 277e66f31c5Sopenharmony_ci 278e66f31c5Sopenharmony_ci zone_index = strchr(ip, '%'); 279e66f31c5Sopenharmony_ci if (zone_index != NULL) { 280e66f31c5Sopenharmony_ci address_part_size = zone_index - ip; 281e66f31c5Sopenharmony_ci if (address_part_size >= sizeof(address_part)) 282e66f31c5Sopenharmony_ci address_part_size = sizeof(address_part) - 1; 283e66f31c5Sopenharmony_ci 284e66f31c5Sopenharmony_ci memcpy(address_part, ip, address_part_size); 285e66f31c5Sopenharmony_ci address_part[address_part_size] = '\0'; 286e66f31c5Sopenharmony_ci ip = address_part; 287e66f31c5Sopenharmony_ci 288e66f31c5Sopenharmony_ci zone_index++; /* skip '%' */ 289e66f31c5Sopenharmony_ci /* NOTE: unknown interface (id=0) is silently ignored */ 290e66f31c5Sopenharmony_ci#ifdef _WIN32 291e66f31c5Sopenharmony_ci addr->sin6_scope_id = atoi(zone_index); 292e66f31c5Sopenharmony_ci#else 293e66f31c5Sopenharmony_ci addr->sin6_scope_id = if_nametoindex(zone_index); 294e66f31c5Sopenharmony_ci#endif 295e66f31c5Sopenharmony_ci } 296e66f31c5Sopenharmony_ci 297e66f31c5Sopenharmony_ci return uv_inet_pton(AF_INET6, ip, &addr->sin6_addr); 298e66f31c5Sopenharmony_ci} 299e66f31c5Sopenharmony_ci 300e66f31c5Sopenharmony_ci 301e66f31c5Sopenharmony_ciint uv_ip4_name(const struct sockaddr_in* src, char* dst, size_t size) { 302e66f31c5Sopenharmony_ci return uv_inet_ntop(AF_INET, &src->sin_addr, dst, size); 303e66f31c5Sopenharmony_ci} 304e66f31c5Sopenharmony_ci 305e66f31c5Sopenharmony_ci 306e66f31c5Sopenharmony_ciint uv_ip6_name(const struct sockaddr_in6* src, char* dst, size_t size) { 307e66f31c5Sopenharmony_ci return uv_inet_ntop(AF_INET6, &src->sin6_addr, dst, size); 308e66f31c5Sopenharmony_ci} 309e66f31c5Sopenharmony_ci 310e66f31c5Sopenharmony_ci 311e66f31c5Sopenharmony_ciint uv_ip_name(const struct sockaddr *src, char *dst, size_t size) { 312e66f31c5Sopenharmony_ci switch (src->sa_family) { 313e66f31c5Sopenharmony_ci case AF_INET: 314e66f31c5Sopenharmony_ci return uv_inet_ntop(AF_INET, &((struct sockaddr_in *)src)->sin_addr, 315e66f31c5Sopenharmony_ci dst, size); 316e66f31c5Sopenharmony_ci case AF_INET6: 317e66f31c5Sopenharmony_ci return uv_inet_ntop(AF_INET6, &((struct sockaddr_in6 *)src)->sin6_addr, 318e66f31c5Sopenharmony_ci dst, size); 319e66f31c5Sopenharmony_ci default: 320e66f31c5Sopenharmony_ci return UV_EAFNOSUPPORT; 321e66f31c5Sopenharmony_ci } 322e66f31c5Sopenharmony_ci} 323e66f31c5Sopenharmony_ci 324e66f31c5Sopenharmony_ci 325e66f31c5Sopenharmony_ciint uv_tcp_bind(uv_tcp_t* handle, 326e66f31c5Sopenharmony_ci const struct sockaddr* addr, 327e66f31c5Sopenharmony_ci unsigned int flags) { 328e66f31c5Sopenharmony_ci unsigned int addrlen; 329e66f31c5Sopenharmony_ci 330e66f31c5Sopenharmony_ci if (handle->type != UV_TCP) 331e66f31c5Sopenharmony_ci return UV_EINVAL; 332e66f31c5Sopenharmony_ci if (uv__is_closing(handle)) { 333e66f31c5Sopenharmony_ci return UV_EINVAL; 334e66f31c5Sopenharmony_ci } 335e66f31c5Sopenharmony_ci if (addr->sa_family == AF_INET) 336e66f31c5Sopenharmony_ci addrlen = sizeof(struct sockaddr_in); 337e66f31c5Sopenharmony_ci else if (addr->sa_family == AF_INET6) 338e66f31c5Sopenharmony_ci addrlen = sizeof(struct sockaddr_in6); 339e66f31c5Sopenharmony_ci else 340e66f31c5Sopenharmony_ci return UV_EINVAL; 341e66f31c5Sopenharmony_ci 342e66f31c5Sopenharmony_ci return uv__tcp_bind(handle, addr, addrlen, flags); 343e66f31c5Sopenharmony_ci} 344e66f31c5Sopenharmony_ci 345e66f31c5Sopenharmony_ci 346e66f31c5Sopenharmony_ciint uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned flags) { 347e66f31c5Sopenharmony_ci unsigned extra_flags; 348e66f31c5Sopenharmony_ci int domain; 349e66f31c5Sopenharmony_ci int rc; 350e66f31c5Sopenharmony_ci 351e66f31c5Sopenharmony_ci /* Use the lower 8 bits for the domain. */ 352e66f31c5Sopenharmony_ci domain = flags & 0xFF; 353e66f31c5Sopenharmony_ci if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC) 354e66f31c5Sopenharmony_ci return UV_EINVAL; 355e66f31c5Sopenharmony_ci 356e66f31c5Sopenharmony_ci /* Use the higher bits for extra flags. */ 357e66f31c5Sopenharmony_ci extra_flags = flags & ~0xFF; 358e66f31c5Sopenharmony_ci if (extra_flags & ~UV_UDP_RECVMMSG) 359e66f31c5Sopenharmony_ci return UV_EINVAL; 360e66f31c5Sopenharmony_ci 361e66f31c5Sopenharmony_ci rc = uv__udp_init_ex(loop, handle, flags, domain); 362e66f31c5Sopenharmony_ci 363e66f31c5Sopenharmony_ci if (rc == 0) 364e66f31c5Sopenharmony_ci if (extra_flags & UV_UDP_RECVMMSG) 365e66f31c5Sopenharmony_ci handle->flags |= UV_HANDLE_UDP_RECVMMSG; 366e66f31c5Sopenharmony_ci 367e66f31c5Sopenharmony_ci return rc; 368e66f31c5Sopenharmony_ci} 369e66f31c5Sopenharmony_ci 370e66f31c5Sopenharmony_ci 371e66f31c5Sopenharmony_ciint uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) { 372e66f31c5Sopenharmony_ci return uv_udp_init_ex(loop, handle, AF_UNSPEC); 373e66f31c5Sopenharmony_ci} 374e66f31c5Sopenharmony_ci 375e66f31c5Sopenharmony_ci 376e66f31c5Sopenharmony_ciint uv_udp_bind(uv_udp_t* handle, 377e66f31c5Sopenharmony_ci const struct sockaddr* addr, 378e66f31c5Sopenharmony_ci unsigned int flags) { 379e66f31c5Sopenharmony_ci unsigned int addrlen; 380e66f31c5Sopenharmony_ci 381e66f31c5Sopenharmony_ci if (handle->type != UV_UDP) 382e66f31c5Sopenharmony_ci return UV_EINVAL; 383e66f31c5Sopenharmony_ci 384e66f31c5Sopenharmony_ci if (addr->sa_family == AF_INET) 385e66f31c5Sopenharmony_ci addrlen = sizeof(struct sockaddr_in); 386e66f31c5Sopenharmony_ci else if (addr->sa_family == AF_INET6) 387e66f31c5Sopenharmony_ci addrlen = sizeof(struct sockaddr_in6); 388e66f31c5Sopenharmony_ci else 389e66f31c5Sopenharmony_ci return UV_EINVAL; 390e66f31c5Sopenharmony_ci 391e66f31c5Sopenharmony_ci return uv__udp_bind(handle, addr, addrlen, flags); 392e66f31c5Sopenharmony_ci} 393e66f31c5Sopenharmony_ci 394e66f31c5Sopenharmony_ci 395e66f31c5Sopenharmony_ciint uv_tcp_connect(uv_connect_t* req, 396e66f31c5Sopenharmony_ci uv_tcp_t* handle, 397e66f31c5Sopenharmony_ci const struct sockaddr* addr, 398e66f31c5Sopenharmony_ci uv_connect_cb cb) { 399e66f31c5Sopenharmony_ci unsigned int addrlen; 400e66f31c5Sopenharmony_ci 401e66f31c5Sopenharmony_ci if (handle->type != UV_TCP) 402e66f31c5Sopenharmony_ci return UV_EINVAL; 403e66f31c5Sopenharmony_ci 404e66f31c5Sopenharmony_ci if (addr->sa_family == AF_INET) 405e66f31c5Sopenharmony_ci addrlen = sizeof(struct sockaddr_in); 406e66f31c5Sopenharmony_ci else if (addr->sa_family == AF_INET6) 407e66f31c5Sopenharmony_ci addrlen = sizeof(struct sockaddr_in6); 408e66f31c5Sopenharmony_ci else 409e66f31c5Sopenharmony_ci return UV_EINVAL; 410e66f31c5Sopenharmony_ci 411e66f31c5Sopenharmony_ci return uv__tcp_connect(req, handle, addr, addrlen, cb); 412e66f31c5Sopenharmony_ci} 413e66f31c5Sopenharmony_ci 414e66f31c5Sopenharmony_ci 415e66f31c5Sopenharmony_ciint uv_udp_connect(uv_udp_t* handle, const struct sockaddr* addr) { 416e66f31c5Sopenharmony_ci unsigned int addrlen; 417e66f31c5Sopenharmony_ci 418e66f31c5Sopenharmony_ci if (handle->type != UV_UDP) 419e66f31c5Sopenharmony_ci return UV_EINVAL; 420e66f31c5Sopenharmony_ci 421e66f31c5Sopenharmony_ci /* Disconnect the handle */ 422e66f31c5Sopenharmony_ci if (addr == NULL) { 423e66f31c5Sopenharmony_ci if (!(handle->flags & UV_HANDLE_UDP_CONNECTED)) 424e66f31c5Sopenharmony_ci return UV_ENOTCONN; 425e66f31c5Sopenharmony_ci 426e66f31c5Sopenharmony_ci return uv__udp_disconnect(handle); 427e66f31c5Sopenharmony_ci } 428e66f31c5Sopenharmony_ci 429e66f31c5Sopenharmony_ci if (addr->sa_family == AF_INET) 430e66f31c5Sopenharmony_ci addrlen = sizeof(struct sockaddr_in); 431e66f31c5Sopenharmony_ci else if (addr->sa_family == AF_INET6) 432e66f31c5Sopenharmony_ci addrlen = sizeof(struct sockaddr_in6); 433e66f31c5Sopenharmony_ci else 434e66f31c5Sopenharmony_ci return UV_EINVAL; 435e66f31c5Sopenharmony_ci 436e66f31c5Sopenharmony_ci if (handle->flags & UV_HANDLE_UDP_CONNECTED) 437e66f31c5Sopenharmony_ci return UV_EISCONN; 438e66f31c5Sopenharmony_ci 439e66f31c5Sopenharmony_ci return uv__udp_connect(handle, addr, addrlen); 440e66f31c5Sopenharmony_ci} 441e66f31c5Sopenharmony_ci 442e66f31c5Sopenharmony_ci 443e66f31c5Sopenharmony_ciint uv__udp_is_connected(uv_udp_t* handle) { 444e66f31c5Sopenharmony_ci struct sockaddr_storage addr; 445e66f31c5Sopenharmony_ci int addrlen; 446e66f31c5Sopenharmony_ci if (handle->type != UV_UDP) 447e66f31c5Sopenharmony_ci return 0; 448e66f31c5Sopenharmony_ci 449e66f31c5Sopenharmony_ci addrlen = sizeof(addr); 450e66f31c5Sopenharmony_ci if (uv_udp_getpeername(handle, (struct sockaddr*) &addr, &addrlen) != 0) 451e66f31c5Sopenharmony_ci return 0; 452e66f31c5Sopenharmony_ci 453e66f31c5Sopenharmony_ci return addrlen > 0; 454e66f31c5Sopenharmony_ci} 455e66f31c5Sopenharmony_ci 456e66f31c5Sopenharmony_ci 457e66f31c5Sopenharmony_ciint uv__udp_check_before_send(uv_udp_t* handle, const struct sockaddr* addr) { 458e66f31c5Sopenharmony_ci unsigned int addrlen; 459e66f31c5Sopenharmony_ci 460e66f31c5Sopenharmony_ci if (handle->type != UV_UDP) 461e66f31c5Sopenharmony_ci return UV_EINVAL; 462e66f31c5Sopenharmony_ci 463e66f31c5Sopenharmony_ci if (addr != NULL && (handle->flags & UV_HANDLE_UDP_CONNECTED)) 464e66f31c5Sopenharmony_ci return UV_EISCONN; 465e66f31c5Sopenharmony_ci 466e66f31c5Sopenharmony_ci if (addr == NULL && !(handle->flags & UV_HANDLE_UDP_CONNECTED)) 467e66f31c5Sopenharmony_ci return UV_EDESTADDRREQ; 468e66f31c5Sopenharmony_ci 469e66f31c5Sopenharmony_ci if (addr != NULL) { 470e66f31c5Sopenharmony_ci if (addr->sa_family == AF_INET) 471e66f31c5Sopenharmony_ci addrlen = sizeof(struct sockaddr_in); 472e66f31c5Sopenharmony_ci else if (addr->sa_family == AF_INET6) 473e66f31c5Sopenharmony_ci addrlen = sizeof(struct sockaddr_in6); 474e66f31c5Sopenharmony_ci#if defined(AF_UNIX) && !defined(_WIN32) 475e66f31c5Sopenharmony_ci else if (addr->sa_family == AF_UNIX) 476e66f31c5Sopenharmony_ci addrlen = sizeof(struct sockaddr_un); 477e66f31c5Sopenharmony_ci#endif 478e66f31c5Sopenharmony_ci else 479e66f31c5Sopenharmony_ci return UV_EINVAL; 480e66f31c5Sopenharmony_ci } else { 481e66f31c5Sopenharmony_ci addrlen = 0; 482e66f31c5Sopenharmony_ci } 483e66f31c5Sopenharmony_ci 484e66f31c5Sopenharmony_ci return addrlen; 485e66f31c5Sopenharmony_ci} 486e66f31c5Sopenharmony_ci 487e66f31c5Sopenharmony_ci 488e66f31c5Sopenharmony_ciint uv_udp_send(uv_udp_send_t* req, 489e66f31c5Sopenharmony_ci uv_udp_t* handle, 490e66f31c5Sopenharmony_ci const uv_buf_t bufs[], 491e66f31c5Sopenharmony_ci unsigned int nbufs, 492e66f31c5Sopenharmony_ci const struct sockaddr* addr, 493e66f31c5Sopenharmony_ci uv_udp_send_cb send_cb) { 494e66f31c5Sopenharmony_ci int addrlen; 495e66f31c5Sopenharmony_ci 496e66f31c5Sopenharmony_ci addrlen = uv__udp_check_before_send(handle, addr); 497e66f31c5Sopenharmony_ci if (addrlen < 0) 498e66f31c5Sopenharmony_ci return addrlen; 499e66f31c5Sopenharmony_ci 500e66f31c5Sopenharmony_ci return uv__udp_send(req, handle, bufs, nbufs, addr, addrlen, send_cb); 501e66f31c5Sopenharmony_ci} 502e66f31c5Sopenharmony_ci 503e66f31c5Sopenharmony_ci 504e66f31c5Sopenharmony_ciint uv_udp_try_send(uv_udp_t* handle, 505e66f31c5Sopenharmony_ci const uv_buf_t bufs[], 506e66f31c5Sopenharmony_ci unsigned int nbufs, 507e66f31c5Sopenharmony_ci const struct sockaddr* addr) { 508e66f31c5Sopenharmony_ci int addrlen; 509e66f31c5Sopenharmony_ci 510e66f31c5Sopenharmony_ci addrlen = uv__udp_check_before_send(handle, addr); 511e66f31c5Sopenharmony_ci if (addrlen < 0) 512e66f31c5Sopenharmony_ci return addrlen; 513e66f31c5Sopenharmony_ci 514e66f31c5Sopenharmony_ci return uv__udp_try_send(handle, bufs, nbufs, addr, addrlen); 515e66f31c5Sopenharmony_ci} 516e66f31c5Sopenharmony_ci 517e66f31c5Sopenharmony_ci 518e66f31c5Sopenharmony_ciint uv_udp_recv_start(uv_udp_t* handle, 519e66f31c5Sopenharmony_ci uv_alloc_cb alloc_cb, 520e66f31c5Sopenharmony_ci uv_udp_recv_cb recv_cb) { 521e66f31c5Sopenharmony_ci if (handle->type != UV_UDP || alloc_cb == NULL || recv_cb == NULL) 522e66f31c5Sopenharmony_ci return UV_EINVAL; 523e66f31c5Sopenharmony_ci else 524e66f31c5Sopenharmony_ci return uv__udp_recv_start(handle, alloc_cb, recv_cb); 525e66f31c5Sopenharmony_ci} 526e66f31c5Sopenharmony_ci 527e66f31c5Sopenharmony_ci 528e66f31c5Sopenharmony_ciint uv_udp_recv_stop(uv_udp_t* handle) { 529e66f31c5Sopenharmony_ci if (handle->type != UV_UDP) 530e66f31c5Sopenharmony_ci return UV_EINVAL; 531e66f31c5Sopenharmony_ci else 532e66f31c5Sopenharmony_ci return uv__udp_recv_stop(handle); 533e66f31c5Sopenharmony_ci} 534e66f31c5Sopenharmony_ci 535e66f31c5Sopenharmony_ci 536e66f31c5Sopenharmony_civoid uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg) { 537e66f31c5Sopenharmony_ci struct uv__queue queue; 538e66f31c5Sopenharmony_ci struct uv__queue* q; 539e66f31c5Sopenharmony_ci uv_handle_t* h; 540e66f31c5Sopenharmony_ci 541e66f31c5Sopenharmony_ci uv__queue_move(&loop->handle_queue, &queue); 542e66f31c5Sopenharmony_ci while (!uv__queue_empty(&queue)) { 543e66f31c5Sopenharmony_ci q = uv__queue_head(&queue); 544e66f31c5Sopenharmony_ci h = uv__queue_data(q, uv_handle_t, handle_queue); 545e66f31c5Sopenharmony_ci 546e66f31c5Sopenharmony_ci uv__queue_remove(q); 547e66f31c5Sopenharmony_ci uv__queue_insert_tail(&loop->handle_queue, q); 548e66f31c5Sopenharmony_ci 549e66f31c5Sopenharmony_ci if (h->flags & UV_HANDLE_INTERNAL) continue; 550e66f31c5Sopenharmony_ci walk_cb(h, arg); 551e66f31c5Sopenharmony_ci } 552e66f31c5Sopenharmony_ci} 553e66f31c5Sopenharmony_ci 554e66f31c5Sopenharmony_ci 555e66f31c5Sopenharmony_cistatic void uv__print_handles(uv_loop_t* loop, int only_active, FILE* stream) { 556e66f31c5Sopenharmony_ci const char* type; 557e66f31c5Sopenharmony_ci struct uv__queue* q; 558e66f31c5Sopenharmony_ci uv_handle_t* h; 559e66f31c5Sopenharmony_ci 560e66f31c5Sopenharmony_ci if (loop == NULL) 561e66f31c5Sopenharmony_ci loop = uv_default_loop(); 562e66f31c5Sopenharmony_ci 563e66f31c5Sopenharmony_ci if (stream == NULL) 564e66f31c5Sopenharmony_ci stream = stderr; 565e66f31c5Sopenharmony_ci 566e66f31c5Sopenharmony_ci uv__queue_foreach(q, &loop->handle_queue) { 567e66f31c5Sopenharmony_ci h = uv__queue_data(q, uv_handle_t, handle_queue); 568e66f31c5Sopenharmony_ci 569e66f31c5Sopenharmony_ci if (only_active && !uv__is_active(h)) 570e66f31c5Sopenharmony_ci continue; 571e66f31c5Sopenharmony_ci 572e66f31c5Sopenharmony_ci switch (h->type) { 573e66f31c5Sopenharmony_ci#define X(uc, lc) case UV_##uc: type = #lc; break; 574e66f31c5Sopenharmony_ci UV_HANDLE_TYPE_MAP(X) 575e66f31c5Sopenharmony_ci#undef X 576e66f31c5Sopenharmony_ci default: type = "<unknown>"; 577e66f31c5Sopenharmony_ci } 578e66f31c5Sopenharmony_ci 579e66f31c5Sopenharmony_ci fprintf(stream, 580e66f31c5Sopenharmony_ci "[%c%c%c] %-8s %p\n", 581e66f31c5Sopenharmony_ci "R-"[!(h->flags & UV_HANDLE_REF)], 582e66f31c5Sopenharmony_ci "A-"[!(h->flags & UV_HANDLE_ACTIVE)], 583e66f31c5Sopenharmony_ci "I-"[!(h->flags & UV_HANDLE_INTERNAL)], 584e66f31c5Sopenharmony_ci type, 585e66f31c5Sopenharmony_ci (void*)h); 586e66f31c5Sopenharmony_ci } 587e66f31c5Sopenharmony_ci} 588e66f31c5Sopenharmony_ci 589e66f31c5Sopenharmony_ci 590e66f31c5Sopenharmony_civoid uv_print_all_handles(uv_loop_t* loop, FILE* stream) { 591e66f31c5Sopenharmony_ci uv__print_handles(loop, 0, stream); 592e66f31c5Sopenharmony_ci} 593e66f31c5Sopenharmony_ci 594e66f31c5Sopenharmony_ci 595e66f31c5Sopenharmony_civoid uv_print_active_handles(uv_loop_t* loop, FILE* stream) { 596e66f31c5Sopenharmony_ci uv__print_handles(loop, 1, stream); 597e66f31c5Sopenharmony_ci} 598e66f31c5Sopenharmony_ci 599e66f31c5Sopenharmony_ci 600e66f31c5Sopenharmony_civoid uv_ref(uv_handle_t* handle) { 601e66f31c5Sopenharmony_ci uv__handle_ref(handle); 602e66f31c5Sopenharmony_ci} 603e66f31c5Sopenharmony_ci 604e66f31c5Sopenharmony_ci 605e66f31c5Sopenharmony_civoid uv_unref(uv_handle_t* handle) { 606e66f31c5Sopenharmony_ci uv__handle_unref(handle); 607e66f31c5Sopenharmony_ci} 608e66f31c5Sopenharmony_ci 609e66f31c5Sopenharmony_ci 610e66f31c5Sopenharmony_ciint uv_has_ref(const uv_handle_t* handle) { 611e66f31c5Sopenharmony_ci return uv__has_ref(handle); 612e66f31c5Sopenharmony_ci} 613e66f31c5Sopenharmony_ci 614e66f31c5Sopenharmony_ci 615e66f31c5Sopenharmony_civoid uv_stop(uv_loop_t* loop) { 616e66f31c5Sopenharmony_ci loop->stop_flag = 1; 617e66f31c5Sopenharmony_ci} 618e66f31c5Sopenharmony_ci 619e66f31c5Sopenharmony_ci 620e66f31c5Sopenharmony_ciuint64_t uv_now(const uv_loop_t* loop) { 621e66f31c5Sopenharmony_ci return loop->time; 622e66f31c5Sopenharmony_ci} 623e66f31c5Sopenharmony_ci 624e66f31c5Sopenharmony_ci 625e66f31c5Sopenharmony_ci 626e66f31c5Sopenharmony_cisize_t uv__count_bufs(const uv_buf_t bufs[], unsigned int nbufs) { 627e66f31c5Sopenharmony_ci unsigned int i; 628e66f31c5Sopenharmony_ci size_t bytes; 629e66f31c5Sopenharmony_ci 630e66f31c5Sopenharmony_ci bytes = 0; 631e66f31c5Sopenharmony_ci for (i = 0; i < nbufs; i++) 632e66f31c5Sopenharmony_ci bytes += (size_t) bufs[i].len; 633e66f31c5Sopenharmony_ci 634e66f31c5Sopenharmony_ci return bytes; 635e66f31c5Sopenharmony_ci} 636e66f31c5Sopenharmony_ci 637e66f31c5Sopenharmony_ciint uv_recv_buffer_size(uv_handle_t* handle, int* value) { 638e66f31c5Sopenharmony_ci return uv__socket_sockopt(handle, SO_RCVBUF, value); 639e66f31c5Sopenharmony_ci} 640e66f31c5Sopenharmony_ci 641e66f31c5Sopenharmony_ciint uv_send_buffer_size(uv_handle_t* handle, int *value) { 642e66f31c5Sopenharmony_ci return uv__socket_sockopt(handle, SO_SNDBUF, value); 643e66f31c5Sopenharmony_ci} 644e66f31c5Sopenharmony_ci 645e66f31c5Sopenharmony_ciint uv_fs_event_getpath(uv_fs_event_t* handle, char* buffer, size_t* size) { 646e66f31c5Sopenharmony_ci size_t required_len; 647e66f31c5Sopenharmony_ci 648e66f31c5Sopenharmony_ci if (!uv__is_active(handle)) { 649e66f31c5Sopenharmony_ci *size = 0; 650e66f31c5Sopenharmony_ci return UV_EINVAL; 651e66f31c5Sopenharmony_ci } 652e66f31c5Sopenharmony_ci 653e66f31c5Sopenharmony_ci required_len = strlen(handle->path); 654e66f31c5Sopenharmony_ci if (required_len >= *size) { 655e66f31c5Sopenharmony_ci *size = required_len + 1; 656e66f31c5Sopenharmony_ci return UV_ENOBUFS; 657e66f31c5Sopenharmony_ci } 658e66f31c5Sopenharmony_ci 659e66f31c5Sopenharmony_ci memcpy(buffer, handle->path, required_len); 660e66f31c5Sopenharmony_ci *size = required_len; 661e66f31c5Sopenharmony_ci buffer[required_len] = '\0'; 662e66f31c5Sopenharmony_ci 663e66f31c5Sopenharmony_ci return 0; 664e66f31c5Sopenharmony_ci} 665e66f31c5Sopenharmony_ci 666e66f31c5Sopenharmony_ci/* The windows implementation does not have the same structure layout as 667e66f31c5Sopenharmony_ci * the unix implementation (nbufs is not directly inside req but is 668e66f31c5Sopenharmony_ci * contained in a nested union/struct) so this function locates it. 669e66f31c5Sopenharmony_ci*/ 670e66f31c5Sopenharmony_cistatic unsigned int* uv__get_nbufs(uv_fs_t* req) { 671e66f31c5Sopenharmony_ci#ifdef _WIN32 672e66f31c5Sopenharmony_ci return &req->fs.info.nbufs; 673e66f31c5Sopenharmony_ci#else 674e66f31c5Sopenharmony_ci return &req->nbufs; 675e66f31c5Sopenharmony_ci#endif 676e66f31c5Sopenharmony_ci} 677e66f31c5Sopenharmony_ci 678e66f31c5Sopenharmony_ci/* uv_fs_scandir() uses the system allocator to allocate memory on non-Windows 679e66f31c5Sopenharmony_ci * systems. So, the memory should be released using free(). On Windows, 680e66f31c5Sopenharmony_ci * uv__malloc() is used, so use uv__free() to free memory. 681e66f31c5Sopenharmony_ci*/ 682e66f31c5Sopenharmony_ci#ifdef _WIN32 683e66f31c5Sopenharmony_ci# define uv__fs_scandir_free uv__free 684e66f31c5Sopenharmony_ci#else 685e66f31c5Sopenharmony_ci# define uv__fs_scandir_free free 686e66f31c5Sopenharmony_ci#endif 687e66f31c5Sopenharmony_ci 688e66f31c5Sopenharmony_civoid uv__fs_scandir_cleanup(uv_fs_t* req) { 689e66f31c5Sopenharmony_ci uv__dirent_t** dents; 690e66f31c5Sopenharmony_ci unsigned int* nbufs; 691e66f31c5Sopenharmony_ci unsigned int i; 692e66f31c5Sopenharmony_ci unsigned int n; 693e66f31c5Sopenharmony_ci 694e66f31c5Sopenharmony_ci if (req->result >= 0) { 695e66f31c5Sopenharmony_ci dents = req->ptr; 696e66f31c5Sopenharmony_ci nbufs = uv__get_nbufs(req); 697e66f31c5Sopenharmony_ci 698e66f31c5Sopenharmony_ci i = 0; 699e66f31c5Sopenharmony_ci if (*nbufs > 0) 700e66f31c5Sopenharmony_ci i = *nbufs - 1; 701e66f31c5Sopenharmony_ci 702e66f31c5Sopenharmony_ci n = (unsigned int) req->result; 703e66f31c5Sopenharmony_ci for (; i < n; i++) 704e66f31c5Sopenharmony_ci uv__fs_scandir_free(dents[i]); 705e66f31c5Sopenharmony_ci } 706e66f31c5Sopenharmony_ci 707e66f31c5Sopenharmony_ci uv__fs_scandir_free(req->ptr); 708e66f31c5Sopenharmony_ci req->ptr = NULL; 709e66f31c5Sopenharmony_ci} 710e66f31c5Sopenharmony_ci 711e66f31c5Sopenharmony_ci 712e66f31c5Sopenharmony_ciint uv_fs_scandir_next(uv_fs_t* req, uv_dirent_t* ent) { 713e66f31c5Sopenharmony_ci uv__dirent_t** dents; 714e66f31c5Sopenharmony_ci uv__dirent_t* dent; 715e66f31c5Sopenharmony_ci unsigned int* nbufs; 716e66f31c5Sopenharmony_ci 717e66f31c5Sopenharmony_ci /* Check to see if req passed */ 718e66f31c5Sopenharmony_ci if (req->result < 0) 719e66f31c5Sopenharmony_ci return req->result; 720e66f31c5Sopenharmony_ci 721e66f31c5Sopenharmony_ci /* Ptr will be null if req was canceled or no files found */ 722e66f31c5Sopenharmony_ci if (!req->ptr) 723e66f31c5Sopenharmony_ci return UV_EOF; 724e66f31c5Sopenharmony_ci 725e66f31c5Sopenharmony_ci nbufs = uv__get_nbufs(req); 726e66f31c5Sopenharmony_ci assert(nbufs); 727e66f31c5Sopenharmony_ci 728e66f31c5Sopenharmony_ci dents = req->ptr; 729e66f31c5Sopenharmony_ci 730e66f31c5Sopenharmony_ci /* Free previous entity */ 731e66f31c5Sopenharmony_ci if (*nbufs > 0) 732e66f31c5Sopenharmony_ci uv__fs_scandir_free(dents[*nbufs - 1]); 733e66f31c5Sopenharmony_ci 734e66f31c5Sopenharmony_ci /* End was already reached */ 735e66f31c5Sopenharmony_ci if (*nbufs == (unsigned int) req->result) { 736e66f31c5Sopenharmony_ci uv__fs_scandir_free(dents); 737e66f31c5Sopenharmony_ci req->ptr = NULL; 738e66f31c5Sopenharmony_ci return UV_EOF; 739e66f31c5Sopenharmony_ci } 740e66f31c5Sopenharmony_ci 741e66f31c5Sopenharmony_ci dent = dents[(*nbufs)++]; 742e66f31c5Sopenharmony_ci 743e66f31c5Sopenharmony_ci ent->name = dent->d_name; 744e66f31c5Sopenharmony_ci ent->type = uv__fs_get_dirent_type(dent); 745e66f31c5Sopenharmony_ci 746e66f31c5Sopenharmony_ci return 0; 747e66f31c5Sopenharmony_ci} 748e66f31c5Sopenharmony_ci 749e66f31c5Sopenharmony_ciuv_dirent_type_t uv__fs_get_dirent_type(uv__dirent_t* dent) { 750e66f31c5Sopenharmony_ci uv_dirent_type_t type; 751e66f31c5Sopenharmony_ci 752e66f31c5Sopenharmony_ci#ifdef HAVE_DIRENT_TYPES 753e66f31c5Sopenharmony_ci switch (dent->d_type) { 754e66f31c5Sopenharmony_ci case UV__DT_DIR: 755e66f31c5Sopenharmony_ci type = UV_DIRENT_DIR; 756e66f31c5Sopenharmony_ci break; 757e66f31c5Sopenharmony_ci case UV__DT_FILE: 758e66f31c5Sopenharmony_ci type = UV_DIRENT_FILE; 759e66f31c5Sopenharmony_ci break; 760e66f31c5Sopenharmony_ci case UV__DT_LINK: 761e66f31c5Sopenharmony_ci type = UV_DIRENT_LINK; 762e66f31c5Sopenharmony_ci break; 763e66f31c5Sopenharmony_ci case UV__DT_FIFO: 764e66f31c5Sopenharmony_ci type = UV_DIRENT_FIFO; 765e66f31c5Sopenharmony_ci break; 766e66f31c5Sopenharmony_ci case UV__DT_SOCKET: 767e66f31c5Sopenharmony_ci type = UV_DIRENT_SOCKET; 768e66f31c5Sopenharmony_ci break; 769e66f31c5Sopenharmony_ci case UV__DT_CHAR: 770e66f31c5Sopenharmony_ci type = UV_DIRENT_CHAR; 771e66f31c5Sopenharmony_ci break; 772e66f31c5Sopenharmony_ci case UV__DT_BLOCK: 773e66f31c5Sopenharmony_ci type = UV_DIRENT_BLOCK; 774e66f31c5Sopenharmony_ci break; 775e66f31c5Sopenharmony_ci default: 776e66f31c5Sopenharmony_ci type = UV_DIRENT_UNKNOWN; 777e66f31c5Sopenharmony_ci } 778e66f31c5Sopenharmony_ci#else 779e66f31c5Sopenharmony_ci type = UV_DIRENT_UNKNOWN; 780e66f31c5Sopenharmony_ci#endif 781e66f31c5Sopenharmony_ci 782e66f31c5Sopenharmony_ci return type; 783e66f31c5Sopenharmony_ci} 784e66f31c5Sopenharmony_ci 785e66f31c5Sopenharmony_civoid uv__fs_readdir_cleanup(uv_fs_t* req) { 786e66f31c5Sopenharmony_ci uv_dir_t* dir; 787e66f31c5Sopenharmony_ci uv_dirent_t* dirents; 788e66f31c5Sopenharmony_ci int i; 789e66f31c5Sopenharmony_ci 790e66f31c5Sopenharmony_ci if (req->ptr == NULL) 791e66f31c5Sopenharmony_ci return; 792e66f31c5Sopenharmony_ci 793e66f31c5Sopenharmony_ci dir = req->ptr; 794e66f31c5Sopenharmony_ci dirents = dir->dirents; 795e66f31c5Sopenharmony_ci req->ptr = NULL; 796e66f31c5Sopenharmony_ci 797e66f31c5Sopenharmony_ci if (dirents == NULL) 798e66f31c5Sopenharmony_ci return; 799e66f31c5Sopenharmony_ci 800e66f31c5Sopenharmony_ci for (i = 0; i < req->result; ++i) { 801e66f31c5Sopenharmony_ci uv__free((char*) dirents[i].name); 802e66f31c5Sopenharmony_ci dirents[i].name = NULL; 803e66f31c5Sopenharmony_ci } 804e66f31c5Sopenharmony_ci} 805e66f31c5Sopenharmony_ci 806e66f31c5Sopenharmony_ci 807e66f31c5Sopenharmony_ciint uv_loop_configure(uv_loop_t* loop, uv_loop_option option, ...) { 808e66f31c5Sopenharmony_ci va_list ap; 809e66f31c5Sopenharmony_ci int err; 810e66f31c5Sopenharmony_ci 811e66f31c5Sopenharmony_ci va_start(ap, option); 812e66f31c5Sopenharmony_ci /* Any platform-agnostic options should be handled here. */ 813e66f31c5Sopenharmony_ci err = uv__loop_configure(loop, option, ap); 814e66f31c5Sopenharmony_ci va_end(ap); 815e66f31c5Sopenharmony_ci 816e66f31c5Sopenharmony_ci return err; 817e66f31c5Sopenharmony_ci} 818e66f31c5Sopenharmony_ci 819e66f31c5Sopenharmony_ci 820e66f31c5Sopenharmony_cistatic uv_loop_t default_loop_struct; 821e66f31c5Sopenharmony_cistatic uv_loop_t* default_loop_ptr; 822e66f31c5Sopenharmony_ci 823e66f31c5Sopenharmony_ci 824e66f31c5Sopenharmony_ciuv_loop_t* uv_default_loop(void) { 825e66f31c5Sopenharmony_ci if (default_loop_ptr != NULL) 826e66f31c5Sopenharmony_ci return default_loop_ptr; 827e66f31c5Sopenharmony_ci 828e66f31c5Sopenharmony_ci if (uv_loop_init(&default_loop_struct)) 829e66f31c5Sopenharmony_ci return NULL; 830e66f31c5Sopenharmony_ci 831e66f31c5Sopenharmony_ci default_loop_ptr = &default_loop_struct; 832e66f31c5Sopenharmony_ci return default_loop_ptr; 833e66f31c5Sopenharmony_ci} 834e66f31c5Sopenharmony_ci 835e66f31c5Sopenharmony_ci 836e66f31c5Sopenharmony_ciuv_loop_t* uv_loop_new(void) { 837e66f31c5Sopenharmony_ci uv_loop_t* loop; 838e66f31c5Sopenharmony_ci 839e66f31c5Sopenharmony_ci loop = uv__malloc(sizeof(*loop)); 840e66f31c5Sopenharmony_ci if (loop == NULL) 841e66f31c5Sopenharmony_ci return NULL; 842e66f31c5Sopenharmony_ci 843e66f31c5Sopenharmony_ci if (uv_loop_init(loop)) { 844e66f31c5Sopenharmony_ci uv__free(loop); 845e66f31c5Sopenharmony_ci return NULL; 846e66f31c5Sopenharmony_ci } 847e66f31c5Sopenharmony_ci 848e66f31c5Sopenharmony_ci return loop; 849e66f31c5Sopenharmony_ci} 850e66f31c5Sopenharmony_ci 851e66f31c5Sopenharmony_ci 852e66f31c5Sopenharmony_civoid on_uv_loop_close(uv_loop_t* loop); 853e66f31c5Sopenharmony_ciint uv_loop_close(uv_loop_t* loop) { 854e66f31c5Sopenharmony_ci struct uv__queue* q; 855e66f31c5Sopenharmony_ci uv_handle_t* h; 856e66f31c5Sopenharmony_ci#ifndef NDEBUG 857e66f31c5Sopenharmony_ci void* saved_data; 858e66f31c5Sopenharmony_ci#endif 859e66f31c5Sopenharmony_ci 860e66f31c5Sopenharmony_ci if (uv__has_active_reqs(loop)) { 861e66f31c5Sopenharmony_ci#ifdef USE_OHOS_DFX 862e66f31c5Sopenharmony_ci UV_LOGI("loop:%{public}zu, active reqs:%{public}u", (size_t)loop, loop->active_reqs.count); 863e66f31c5Sopenharmony_ci#endif 864e66f31c5Sopenharmony_ci return UV_EBUSY; 865e66f31c5Sopenharmony_ci } 866e66f31c5Sopenharmony_ci uv__queue_foreach(q, &loop->handle_queue) { 867e66f31c5Sopenharmony_ci h = uv__queue_data(q, uv_handle_t, handle_queue); 868e66f31c5Sopenharmony_ci if (!(h->flags & UV_HANDLE_INTERNAL)) { 869e66f31c5Sopenharmony_ci#ifdef USE_OHOS_DFX 870e66f31c5Sopenharmony_ci UV_LOGI("loop:%{public}zu, active handle:%{public}zu", (size_t)loop, (size_t)h); 871e66f31c5Sopenharmony_ci#endif 872e66f31c5Sopenharmony_ci return UV_EBUSY; 873e66f31c5Sopenharmony_ci } 874e66f31c5Sopenharmony_ci } 875e66f31c5Sopenharmony_ci 876e66f31c5Sopenharmony_ci on_uv_loop_close(loop); 877e66f31c5Sopenharmony_ci uv__loop_close(loop); 878e66f31c5Sopenharmony_ci 879e66f31c5Sopenharmony_ci#ifndef NDEBUG 880e66f31c5Sopenharmony_ci saved_data = loop->data; 881e66f31c5Sopenharmony_ci memset(loop, -1, sizeof(*loop)); 882e66f31c5Sopenharmony_ci loop->data = saved_data; 883e66f31c5Sopenharmony_ci#endif 884e66f31c5Sopenharmony_ci if (loop == default_loop_ptr) 885e66f31c5Sopenharmony_ci default_loop_ptr = NULL; 886e66f31c5Sopenharmony_ci 887e66f31c5Sopenharmony_ci return 0; 888e66f31c5Sopenharmony_ci} 889e66f31c5Sopenharmony_ci 890e66f31c5Sopenharmony_ci 891e66f31c5Sopenharmony_civoid uv_loop_delete(uv_loop_t* loop) { 892e66f31c5Sopenharmony_ci uv_loop_t* default_loop; 893e66f31c5Sopenharmony_ci int err; 894e66f31c5Sopenharmony_ci 895e66f31c5Sopenharmony_ci default_loop = default_loop_ptr; 896e66f31c5Sopenharmony_ci 897e66f31c5Sopenharmony_ci err = uv_loop_close(loop); 898e66f31c5Sopenharmony_ci (void) err; /* Squelch compiler warnings. */ 899e66f31c5Sopenharmony_ci assert(err == 0); 900e66f31c5Sopenharmony_ci#ifdef USE_OHOS_DFX 901e66f31c5Sopenharmony_ci if (err != 0) 902e66f31c5Sopenharmony_ci on_uv_loop_close(loop); 903e66f31c5Sopenharmony_ci#endif 904e66f31c5Sopenharmony_ci if (loop != default_loop) 905e66f31c5Sopenharmony_ci uv__free(loop); 906e66f31c5Sopenharmony_ci} 907e66f31c5Sopenharmony_ci 908e66f31c5Sopenharmony_ci 909e66f31c5Sopenharmony_ciint uv_read_start(uv_stream_t* stream, 910e66f31c5Sopenharmony_ci uv_alloc_cb alloc_cb, 911e66f31c5Sopenharmony_ci uv_read_cb read_cb) { 912e66f31c5Sopenharmony_ci if (stream == NULL || alloc_cb == NULL || read_cb == NULL) 913e66f31c5Sopenharmony_ci return UV_EINVAL; 914e66f31c5Sopenharmony_ci 915e66f31c5Sopenharmony_ci if (stream->flags & UV_HANDLE_CLOSING) 916e66f31c5Sopenharmony_ci return UV_EINVAL; 917e66f31c5Sopenharmony_ci 918e66f31c5Sopenharmony_ci if (stream->flags & UV_HANDLE_READING) 919e66f31c5Sopenharmony_ci return UV_EALREADY; 920e66f31c5Sopenharmony_ci 921e66f31c5Sopenharmony_ci if (!(stream->flags & UV_HANDLE_READABLE)) 922e66f31c5Sopenharmony_ci return UV_ENOTCONN; 923e66f31c5Sopenharmony_ci 924e66f31c5Sopenharmony_ci return uv__read_start(stream, alloc_cb, read_cb); 925e66f31c5Sopenharmony_ci} 926e66f31c5Sopenharmony_ci 927e66f31c5Sopenharmony_ci 928e66f31c5Sopenharmony_civoid uv_os_free_environ(uv_env_item_t* envitems, int count) { 929e66f31c5Sopenharmony_ci int i; 930e66f31c5Sopenharmony_ci 931e66f31c5Sopenharmony_ci for (i = 0; i < count; i++) { 932e66f31c5Sopenharmony_ci uv__free(envitems[i].name); 933e66f31c5Sopenharmony_ci } 934e66f31c5Sopenharmony_ci 935e66f31c5Sopenharmony_ci uv__free(envitems); 936e66f31c5Sopenharmony_ci} 937e66f31c5Sopenharmony_ci 938e66f31c5Sopenharmony_ci 939e66f31c5Sopenharmony_civoid uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { 940e66f31c5Sopenharmony_ci#ifdef __linux__ 941e66f31c5Sopenharmony_ci (void) &count; 942e66f31c5Sopenharmony_ci uv__free(cpu_infos); 943e66f31c5Sopenharmony_ci#else 944e66f31c5Sopenharmony_ci int i; 945e66f31c5Sopenharmony_ci 946e66f31c5Sopenharmony_ci for (i = 0; i < count; i++) 947e66f31c5Sopenharmony_ci uv__free(cpu_infos[i].model); 948e66f31c5Sopenharmony_ci 949e66f31c5Sopenharmony_ci uv__free(cpu_infos); 950e66f31c5Sopenharmony_ci#endif /* __linux__ */ 951e66f31c5Sopenharmony_ci} 952e66f31c5Sopenharmony_ci 953e66f31c5Sopenharmony_ci 954e66f31c5Sopenharmony_ci/* Also covers __clang__ and __INTEL_COMPILER. Disabled on Windows because 955e66f31c5Sopenharmony_ci * threads have already been forcibly terminated by the operating system 956e66f31c5Sopenharmony_ci * by the time destructors run, ergo, it's not safe to try to clean them up. 957e66f31c5Sopenharmony_ci */ 958e66f31c5Sopenharmony_ci#if defined(__GNUC__) && !defined(_WIN32) 959e66f31c5Sopenharmony_ci__attribute__((destructor)) 960e66f31c5Sopenharmony_ci#endif 961e66f31c5Sopenharmony_civoid uv_library_shutdown(void) { 962e66f31c5Sopenharmony_ci static int was_shutdown; 963e66f31c5Sopenharmony_ci 964e66f31c5Sopenharmony_ci if (uv__exchange_int_relaxed(&was_shutdown, 1)) 965e66f31c5Sopenharmony_ci return; 966e66f31c5Sopenharmony_ci 967e66f31c5Sopenharmony_ci uv__process_title_cleanup(); 968e66f31c5Sopenharmony_ci uv__signal_cleanup(); 969e66f31c5Sopenharmony_ci#ifdef __MVS__ 970e66f31c5Sopenharmony_ci /* TODO(itodorov) - zos: revisit when Woz compiler is available. */ 971e66f31c5Sopenharmony_ci uv__os390_cleanup(); 972e66f31c5Sopenharmony_ci#else 973e66f31c5Sopenharmony_ci uv__threadpool_cleanup(); 974e66f31c5Sopenharmony_ci#endif 975e66f31c5Sopenharmony_ci} 976e66f31c5Sopenharmony_ci 977e66f31c5Sopenharmony_ci 978e66f31c5Sopenharmony_civoid uv__metrics_update_idle_time(uv_loop_t* loop) { 979e66f31c5Sopenharmony_ci uv__loop_metrics_t* loop_metrics; 980e66f31c5Sopenharmony_ci uint64_t entry_time; 981e66f31c5Sopenharmony_ci uint64_t exit_time; 982e66f31c5Sopenharmony_ci 983e66f31c5Sopenharmony_ci if (!(uv__get_internal_fields(loop)->flags & UV_METRICS_IDLE_TIME)) 984e66f31c5Sopenharmony_ci return; 985e66f31c5Sopenharmony_ci 986e66f31c5Sopenharmony_ci loop_metrics = uv__get_loop_metrics(loop); 987e66f31c5Sopenharmony_ci 988e66f31c5Sopenharmony_ci /* The thread running uv__metrics_update_idle_time() is always the same 989e66f31c5Sopenharmony_ci * thread that sets provider_entry_time. So it's unnecessary to lock before 990e66f31c5Sopenharmony_ci * retrieving this value. 991e66f31c5Sopenharmony_ci */ 992e66f31c5Sopenharmony_ci if (loop_metrics->provider_entry_time == 0) 993e66f31c5Sopenharmony_ci return; 994e66f31c5Sopenharmony_ci 995e66f31c5Sopenharmony_ci exit_time = uv_hrtime(); 996e66f31c5Sopenharmony_ci 997e66f31c5Sopenharmony_ci uv_mutex_lock(&loop_metrics->lock); 998e66f31c5Sopenharmony_ci entry_time = loop_metrics->provider_entry_time; 999e66f31c5Sopenharmony_ci loop_metrics->provider_entry_time = 0; 1000e66f31c5Sopenharmony_ci loop_metrics->provider_idle_time += exit_time - entry_time; 1001e66f31c5Sopenharmony_ci uv_mutex_unlock(&loop_metrics->lock); 1002e66f31c5Sopenharmony_ci} 1003e66f31c5Sopenharmony_ci 1004e66f31c5Sopenharmony_ci 1005e66f31c5Sopenharmony_civoid uv__metrics_set_provider_entry_time(uv_loop_t* loop) { 1006e66f31c5Sopenharmony_ci uv__loop_metrics_t* loop_metrics; 1007e66f31c5Sopenharmony_ci uint64_t now; 1008e66f31c5Sopenharmony_ci 1009e66f31c5Sopenharmony_ci if (!(uv__get_internal_fields(loop)->flags & UV_METRICS_IDLE_TIME)) 1010e66f31c5Sopenharmony_ci return; 1011e66f31c5Sopenharmony_ci 1012e66f31c5Sopenharmony_ci now = uv_hrtime(); 1013e66f31c5Sopenharmony_ci loop_metrics = uv__get_loop_metrics(loop); 1014e66f31c5Sopenharmony_ci uv_mutex_lock(&loop_metrics->lock); 1015e66f31c5Sopenharmony_ci loop_metrics->provider_entry_time = now; 1016e66f31c5Sopenharmony_ci uv_mutex_unlock(&loop_metrics->lock); 1017e66f31c5Sopenharmony_ci} 1018e66f31c5Sopenharmony_ci 1019e66f31c5Sopenharmony_ci 1020e66f31c5Sopenharmony_ciint uv_metrics_info(uv_loop_t* loop, uv_metrics_t* metrics) { 1021e66f31c5Sopenharmony_ci memcpy(metrics, 1022e66f31c5Sopenharmony_ci &uv__get_loop_metrics(loop)->metrics, 1023e66f31c5Sopenharmony_ci sizeof(*metrics)); 1024e66f31c5Sopenharmony_ci 1025e66f31c5Sopenharmony_ci return 0; 1026e66f31c5Sopenharmony_ci} 1027e66f31c5Sopenharmony_ci 1028e66f31c5Sopenharmony_ci 1029e66f31c5Sopenharmony_ciuint64_t uv_metrics_idle_time(uv_loop_t* loop) { 1030e66f31c5Sopenharmony_ci uv__loop_metrics_t* loop_metrics; 1031e66f31c5Sopenharmony_ci uint64_t entry_time; 1032e66f31c5Sopenharmony_ci uint64_t idle_time; 1033e66f31c5Sopenharmony_ci 1034e66f31c5Sopenharmony_ci loop_metrics = uv__get_loop_metrics(loop); 1035e66f31c5Sopenharmony_ci uv_mutex_lock(&loop_metrics->lock); 1036e66f31c5Sopenharmony_ci idle_time = loop_metrics->provider_idle_time; 1037e66f31c5Sopenharmony_ci entry_time = loop_metrics->provider_entry_time; 1038e66f31c5Sopenharmony_ci uv_mutex_unlock(&loop_metrics->lock); 1039e66f31c5Sopenharmony_ci 1040e66f31c5Sopenharmony_ci if (entry_time > 0) 1041e66f31c5Sopenharmony_ci idle_time += uv_hrtime() - entry_time; 1042e66f31c5Sopenharmony_ci return idle_time; 1043e66f31c5Sopenharmony_ci} 1044e66f31c5Sopenharmony_ci 1045e66f31c5Sopenharmony_ci 1046e66f31c5Sopenharmony_ciuint64_t uv__get_addr_tag(void* addr) { 1047e66f31c5Sopenharmony_ci uint64_t tag = 0; 1048e66f31c5Sopenharmony_ci 1049e66f31c5Sopenharmony_ci#ifdef USE_OHOS_DFX 1050e66f31c5Sopenharmony_ci if (addr != NULL) { 1051e66f31c5Sopenharmony_ci tag = fdsan_create_owner_tag(FDSAN_OWNER_TYPE_FILE, (uint64_t)addr); 1052e66f31c5Sopenharmony_ci } 1053e66f31c5Sopenharmony_ci#endif 1054e66f31c5Sopenharmony_ci return tag; 1055e66f31c5Sopenharmony_ci}