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}