1
0

uv-common.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871
  1. /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
  2. *
  3. * Permission is hereby granted, free of charge, to any person obtaining a copy
  4. * of this software and associated documentation files (the "Software"), to
  5. * deal in the Software without restriction, including without limitation the
  6. * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  7. * sell copies of the Software, and to permit persons to whom the Software is
  8. * furnished to do so, subject to the following conditions:
  9. *
  10. * The above copyright notice and this permission notice shall be included in
  11. * all copies or substantial portions of the Software.
  12. *
  13. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  18. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  19. * IN THE SOFTWARE.
  20. */
  21. #include "uv.h"
  22. #include "uv-common.h"
  23. #include <assert.h>
  24. #include <errno.h>
  25. #include <stdarg.h>
  26. #include <stddef.h> /* NULL */
  27. #include <stdio.h>
  28. #include <stdlib.h> /* malloc */
  29. #include <string.h> /* memset */
  30. #if defined(_WIN32)
  31. # include <malloc.h> /* malloc */
  32. #else
  33. # include <net/if.h> /* if_nametoindex */
  34. # include <sys/un.h> /* AF_UNIX, sockaddr_un */
  35. #endif
  36. typedef struct {
  37. uv_malloc_func local_malloc;
  38. uv_realloc_func local_realloc;
  39. uv_calloc_func local_calloc;
  40. uv_free_func local_free;
  41. } uv__allocator_t;
  42. static uv__allocator_t uv__allocator = {
  43. malloc,
  44. realloc,
  45. calloc,
  46. free,
  47. };
  48. char* uv__strdup(const char* s) {
  49. size_t len = strlen(s) + 1;
  50. char* m = uv__malloc(len);
  51. if (m == NULL)
  52. return NULL;
  53. return memcpy(m, s, len);
  54. }
  55. char* uv__strndup(const char* s, size_t n) {
  56. char* m;
  57. size_t len = strlen(s);
  58. if (n < len)
  59. len = n;
  60. m = uv__malloc(len + 1);
  61. if (m == NULL)
  62. return NULL;
  63. m[len] = '\0';
  64. return memcpy(m, s, len);
  65. }
  66. void* uv__malloc(size_t size) {
  67. if (size > 0)
  68. return uv__allocator.local_malloc(size);
  69. return NULL;
  70. }
  71. void uv__free(void* ptr) {
  72. int saved_errno;
  73. /* Libuv expects that free() does not clobber errno. The system allocator
  74. * honors that assumption but custom allocators may not be so careful.
  75. */
  76. saved_errno = errno;
  77. uv__allocator.local_free(ptr);
  78. errno = saved_errno;
  79. }
  80. void* uv__calloc(size_t count, size_t size) {
  81. return uv__allocator.local_calloc(count, size);
  82. }
  83. void* uv__realloc(void* ptr, size_t size) {
  84. if (size > 0)
  85. return uv__allocator.local_realloc(ptr, size);
  86. uv__free(ptr);
  87. return NULL;
  88. }
  89. void* uv__reallocf(void* ptr, size_t size) {
  90. void* newptr;
  91. newptr = uv__realloc(ptr, size);
  92. if (newptr == NULL)
  93. if (size > 0)
  94. uv__free(ptr);
  95. return newptr;
  96. }
  97. int uv_replace_allocator(uv_malloc_func malloc_func,
  98. uv_realloc_func realloc_func,
  99. uv_calloc_func calloc_func,
  100. uv_free_func free_func) {
  101. if (malloc_func == NULL || realloc_func == NULL ||
  102. calloc_func == NULL || free_func == NULL) {
  103. return UV_EINVAL;
  104. }
  105. uv__allocator.local_malloc = malloc_func;
  106. uv__allocator.local_realloc = realloc_func;
  107. uv__allocator.local_calloc = calloc_func;
  108. uv__allocator.local_free = free_func;
  109. return 0;
  110. }
  111. #define XX(uc, lc) case UV_##uc: return sizeof(uv_##lc##_t);
  112. size_t uv_handle_size(uv_handle_type type) {
  113. switch (type) {
  114. UV_HANDLE_TYPE_MAP(XX)
  115. default:
  116. return -1;
  117. }
  118. }
  119. size_t uv_req_size(uv_req_type type) {
  120. switch(type) {
  121. UV_REQ_TYPE_MAP(XX)
  122. default:
  123. return -1;
  124. }
  125. }
  126. #undef XX
  127. size_t uv_loop_size(void) {
  128. return sizeof(uv_loop_t);
  129. }
  130. uv_buf_t uv_buf_init(char* base, unsigned int len) {
  131. uv_buf_t buf;
  132. buf.base = base;
  133. buf.len = len;
  134. return buf;
  135. }
  136. static const char* uv__unknown_err_code(int err) {
  137. char buf[32];
  138. char* copy;
  139. snprintf(buf, sizeof(buf), "Unknown system error %d", err);
  140. copy = uv__strdup(buf);
  141. return copy != NULL ? copy : "Unknown system error";
  142. }
  143. #define UV_ERR_NAME_GEN_R(name, _) \
  144. case UV_## name: \
  145. uv__strscpy(buf, #name, buflen); break;
  146. char* uv_err_name_r(int err, char* buf, size_t buflen) {
  147. switch (err) {
  148. UV_ERRNO_MAP(UV_ERR_NAME_GEN_R)
  149. default: snprintf(buf, buflen, "Unknown system error %d", err);
  150. }
  151. return buf;
  152. }
  153. #undef UV_ERR_NAME_GEN_R
  154. #define UV_ERR_NAME_GEN(name, _) case UV_ ## name: return #name;
  155. const char* uv_err_name(int err) {
  156. switch (err) {
  157. UV_ERRNO_MAP(UV_ERR_NAME_GEN)
  158. }
  159. return uv__unknown_err_code(err);
  160. }
  161. #undef UV_ERR_NAME_GEN
  162. #define UV_STRERROR_GEN_R(name, msg) \
  163. case UV_ ## name: \
  164. snprintf(buf, buflen, "%s", msg); break;
  165. char* uv_strerror_r(int err, char* buf, size_t buflen) {
  166. switch (err) {
  167. UV_ERRNO_MAP(UV_STRERROR_GEN_R)
  168. default: snprintf(buf, buflen, "Unknown system error %d", err);
  169. }
  170. return buf;
  171. }
  172. #undef UV_STRERROR_GEN_R
  173. #define UV_STRERROR_GEN(name, msg) case UV_ ## name: return msg;
  174. const char* uv_strerror(int err) {
  175. switch (err) {
  176. UV_ERRNO_MAP(UV_STRERROR_GEN)
  177. }
  178. return uv__unknown_err_code(err);
  179. }
  180. #undef UV_STRERROR_GEN
  181. #if !defined(CMAKE_BOOTSTRAP) || defined(_WIN32)
  182. int uv_ip4_addr(const char* ip, int port, struct sockaddr_in* addr) {
  183. memset(addr, 0, sizeof(*addr));
  184. addr->sin_family = AF_INET;
  185. addr->sin_port = htons(port);
  186. #ifdef SIN6_LEN
  187. addr->sin_len = sizeof(*addr);
  188. #endif
  189. return uv_inet_pton(AF_INET, ip, &(addr->sin_addr.s_addr));
  190. }
  191. int uv_ip6_addr(const char* ip, int port, struct sockaddr_in6* addr) {
  192. char address_part[40];
  193. size_t address_part_size;
  194. const char* zone_index;
  195. memset(addr, 0, sizeof(*addr));
  196. addr->sin6_family = AF_INET6;
  197. addr->sin6_port = htons(port);
  198. #ifdef SIN6_LEN
  199. addr->sin6_len = sizeof(*addr);
  200. #endif
  201. zone_index = strchr(ip, '%');
  202. if (zone_index != NULL) {
  203. address_part_size = zone_index - ip;
  204. if (address_part_size >= sizeof(address_part))
  205. address_part_size = sizeof(address_part) - 1;
  206. memcpy(address_part, ip, address_part_size);
  207. address_part[address_part_size] = '\0';
  208. ip = address_part;
  209. zone_index++; /* skip '%' */
  210. /* NOTE: unknown interface (id=0) is silently ignored */
  211. #ifdef _WIN32
  212. addr->sin6_scope_id = atoi(zone_index);
  213. #else
  214. addr->sin6_scope_id = if_nametoindex(zone_index);
  215. #endif
  216. }
  217. return uv_inet_pton(AF_INET6, ip, &addr->sin6_addr);
  218. }
  219. int uv_ip4_name(const struct sockaddr_in* src, char* dst, size_t size) {
  220. return uv_inet_ntop(AF_INET, &src->sin_addr, dst, size);
  221. }
  222. int uv_ip6_name(const struct sockaddr_in6* src, char* dst, size_t size) {
  223. return uv_inet_ntop(AF_INET6, &src->sin6_addr, dst, size);
  224. }
  225. int uv_tcp_bind(uv_tcp_t* handle,
  226. const struct sockaddr* addr,
  227. unsigned int flags) {
  228. unsigned int addrlen;
  229. if (handle->type != UV_TCP)
  230. return UV_EINVAL;
  231. if (addr->sa_family == AF_INET)
  232. addrlen = sizeof(struct sockaddr_in);
  233. else if (addr->sa_family == AF_INET6)
  234. addrlen = sizeof(struct sockaddr_in6);
  235. else
  236. return UV_EINVAL;
  237. return uv__tcp_bind(handle, addr, addrlen, flags);
  238. }
  239. int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned flags) {
  240. unsigned extra_flags;
  241. int domain;
  242. int rc;
  243. /* Use the lower 8 bits for the domain. */
  244. domain = flags & 0xFF;
  245. if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC)
  246. return UV_EINVAL;
  247. /* Use the higher bits for extra flags. */
  248. extra_flags = flags & ~0xFF;
  249. if (extra_flags & ~UV_UDP_RECVMMSG)
  250. return UV_EINVAL;
  251. rc = uv__udp_init_ex(loop, handle, flags, domain);
  252. if (rc == 0)
  253. if (extra_flags & UV_UDP_RECVMMSG)
  254. handle->flags |= UV_HANDLE_UDP_RECVMMSG;
  255. return rc;
  256. }
  257. int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) {
  258. return uv_udp_init_ex(loop, handle, AF_UNSPEC);
  259. }
  260. int uv_udp_bind(uv_udp_t* handle,
  261. const struct sockaddr* addr,
  262. unsigned int flags) {
  263. unsigned int addrlen;
  264. if (handle->type != UV_UDP)
  265. return UV_EINVAL;
  266. if (addr->sa_family == AF_INET)
  267. addrlen = sizeof(struct sockaddr_in);
  268. else if (addr->sa_family == AF_INET6)
  269. addrlen = sizeof(struct sockaddr_in6);
  270. else
  271. return UV_EINVAL;
  272. return uv__udp_bind(handle, addr, addrlen, flags);
  273. }
  274. int uv_tcp_connect(uv_connect_t* req,
  275. uv_tcp_t* handle,
  276. const struct sockaddr* addr,
  277. uv_connect_cb cb) {
  278. unsigned int addrlen;
  279. if (handle->type != UV_TCP)
  280. return UV_EINVAL;
  281. if (addr->sa_family == AF_INET)
  282. addrlen = sizeof(struct sockaddr_in);
  283. else if (addr->sa_family == AF_INET6)
  284. addrlen = sizeof(struct sockaddr_in6);
  285. else
  286. return UV_EINVAL;
  287. return uv__tcp_connect(req, handle, addr, addrlen, cb);
  288. }
  289. int uv_udp_connect(uv_udp_t* handle, const struct sockaddr* addr) {
  290. unsigned int addrlen;
  291. if (handle->type != UV_UDP)
  292. return UV_EINVAL;
  293. /* Disconnect the handle */
  294. if (addr == NULL) {
  295. if (!(handle->flags & UV_HANDLE_UDP_CONNECTED))
  296. return UV_ENOTCONN;
  297. return uv__udp_disconnect(handle);
  298. }
  299. if (addr->sa_family == AF_INET)
  300. addrlen = sizeof(struct sockaddr_in);
  301. else if (addr->sa_family == AF_INET6)
  302. addrlen = sizeof(struct sockaddr_in6);
  303. else
  304. return UV_EINVAL;
  305. if (handle->flags & UV_HANDLE_UDP_CONNECTED)
  306. return UV_EISCONN;
  307. return uv__udp_connect(handle, addr, addrlen);
  308. }
  309. int uv__udp_is_connected(uv_udp_t* handle) {
  310. struct sockaddr_storage addr;
  311. int addrlen;
  312. if (handle->type != UV_UDP)
  313. return 0;
  314. addrlen = sizeof(addr);
  315. if (uv_udp_getpeername(handle, (struct sockaddr*) &addr, &addrlen) != 0)
  316. return 0;
  317. return addrlen > 0;
  318. }
  319. int uv__udp_check_before_send(uv_udp_t* handle, const struct sockaddr* addr) {
  320. unsigned int addrlen;
  321. if (handle->type != UV_UDP)
  322. return UV_EINVAL;
  323. if (addr != NULL && (handle->flags & UV_HANDLE_UDP_CONNECTED))
  324. return UV_EISCONN;
  325. if (addr == NULL && !(handle->flags & UV_HANDLE_UDP_CONNECTED))
  326. return UV_EDESTADDRREQ;
  327. if (addr != NULL) {
  328. if (addr->sa_family == AF_INET)
  329. addrlen = sizeof(struct sockaddr_in);
  330. else if (addr->sa_family == AF_INET6)
  331. addrlen = sizeof(struct sockaddr_in6);
  332. #if defined(AF_UNIX) && !defined(_WIN32)
  333. else if (addr->sa_family == AF_UNIX)
  334. addrlen = sizeof(struct sockaddr_un);
  335. #endif
  336. else
  337. return UV_EINVAL;
  338. } else {
  339. addrlen = 0;
  340. }
  341. return addrlen;
  342. }
  343. int uv_udp_send(uv_udp_send_t* req,
  344. uv_udp_t* handle,
  345. const uv_buf_t bufs[],
  346. unsigned int nbufs,
  347. const struct sockaddr* addr,
  348. uv_udp_send_cb send_cb) {
  349. int addrlen;
  350. addrlen = uv__udp_check_before_send(handle, addr);
  351. if (addrlen < 0)
  352. return addrlen;
  353. return uv__udp_send(req, handle, bufs, nbufs, addr, addrlen, send_cb);
  354. }
  355. int uv_udp_try_send(uv_udp_t* handle,
  356. const uv_buf_t bufs[],
  357. unsigned int nbufs,
  358. const struct sockaddr* addr) {
  359. int addrlen;
  360. addrlen = uv__udp_check_before_send(handle, addr);
  361. if (addrlen < 0)
  362. return addrlen;
  363. return uv__udp_try_send(handle, bufs, nbufs, addr, addrlen);
  364. }
  365. int uv_udp_recv_start(uv_udp_t* handle,
  366. uv_alloc_cb alloc_cb,
  367. uv_udp_recv_cb recv_cb) {
  368. if (handle->type != UV_UDP || alloc_cb == NULL || recv_cb == NULL)
  369. return UV_EINVAL;
  370. else
  371. return uv__udp_recv_start(handle, alloc_cb, recv_cb);
  372. }
  373. int uv_udp_recv_stop(uv_udp_t* handle) {
  374. if (handle->type != UV_UDP)
  375. return UV_EINVAL;
  376. else
  377. return uv__udp_recv_stop(handle);
  378. }
  379. #endif
  380. void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg) {
  381. QUEUE queue;
  382. QUEUE* q;
  383. uv_handle_t* h;
  384. QUEUE_MOVE(&loop->handle_queue, &queue);
  385. while (!QUEUE_EMPTY(&queue)) {
  386. q = QUEUE_HEAD(&queue);
  387. h = QUEUE_DATA(q, uv_handle_t, handle_queue);
  388. QUEUE_REMOVE(q);
  389. QUEUE_INSERT_TAIL(&loop->handle_queue, q);
  390. if (h->flags & UV_HANDLE_INTERNAL) continue;
  391. walk_cb(h, arg);
  392. }
  393. }
  394. static void uv__print_handles(uv_loop_t* loop, int only_active, FILE* stream) {
  395. const char* type;
  396. QUEUE* q;
  397. uv_handle_t* h;
  398. if (loop == NULL)
  399. loop = uv_default_loop();
  400. QUEUE_FOREACH(q, &loop->handle_queue) {
  401. h = QUEUE_DATA(q, uv_handle_t, handle_queue);
  402. if (only_active && !uv__is_active(h))
  403. continue;
  404. switch (h->type) {
  405. #define X(uc, lc) case UV_##uc: type = #lc; break;
  406. UV_HANDLE_TYPE_MAP(X)
  407. #undef X
  408. default: type = "<unknown>";
  409. }
  410. fprintf(stream,
  411. "[%c%c%c] %-8s %p\n",
  412. "R-"[!(h->flags & UV_HANDLE_REF)],
  413. "A-"[!(h->flags & UV_HANDLE_ACTIVE)],
  414. "I-"[!(h->flags & UV_HANDLE_INTERNAL)],
  415. type,
  416. (void*)h);
  417. }
  418. }
  419. void uv_print_all_handles(uv_loop_t* loop, FILE* stream) {
  420. uv__print_handles(loop, 0, stream);
  421. }
  422. void uv_print_active_handles(uv_loop_t* loop, FILE* stream) {
  423. uv__print_handles(loop, 1, stream);
  424. }
  425. void uv_ref(uv_handle_t* handle) {
  426. uv__handle_ref(handle);
  427. }
  428. void uv_unref(uv_handle_t* handle) {
  429. uv__handle_unref(handle);
  430. }
  431. int uv_has_ref(const uv_handle_t* handle) {
  432. return uv__has_ref(handle);
  433. }
  434. void uv_stop(uv_loop_t* loop) {
  435. loop->stop_flag = 1;
  436. }
  437. uint64_t uv_now(const uv_loop_t* loop) {
  438. return loop->time;
  439. }
  440. size_t uv__count_bufs(const uv_buf_t bufs[], unsigned int nbufs) {
  441. unsigned int i;
  442. size_t bytes;
  443. bytes = 0;
  444. for (i = 0; i < nbufs; i++)
  445. bytes += (size_t) bufs[i].len;
  446. return bytes;
  447. }
  448. int uv_recv_buffer_size(uv_handle_t* handle, int* value) {
  449. return uv__socket_sockopt(handle, SO_RCVBUF, value);
  450. }
  451. int uv_send_buffer_size(uv_handle_t* handle, int *value) {
  452. return uv__socket_sockopt(handle, SO_SNDBUF, value);
  453. }
  454. int uv_fs_event_getpath(uv_fs_event_t* handle, char* buffer, size_t* size) {
  455. size_t required_len;
  456. if (!uv__is_active(handle)) {
  457. *size = 0;
  458. return UV_EINVAL;
  459. }
  460. required_len = strlen(handle->path);
  461. if (required_len >= *size) {
  462. *size = required_len + 1;
  463. return UV_ENOBUFS;
  464. }
  465. memcpy(buffer, handle->path, required_len);
  466. *size = required_len;
  467. buffer[required_len] = '\0';
  468. return 0;
  469. }
  470. /* The windows implementation does not have the same structure layout as
  471. * the unix implementation (nbufs is not directly inside req but is
  472. * contained in a nested union/struct) so this function locates it.
  473. */
  474. static unsigned int* uv__get_nbufs(uv_fs_t* req) {
  475. #ifdef _WIN32
  476. return &req->fs.info.nbufs;
  477. #else
  478. return &req->nbufs;
  479. #endif
  480. }
  481. /* uv_fs_scandir() uses the system allocator to allocate memory on non-Windows
  482. * systems. So, the memory should be released using free(). On Windows,
  483. * uv__malloc() is used, so use uv__free() to free memory.
  484. */
  485. #ifdef _WIN32
  486. # define uv__fs_scandir_free uv__free
  487. #else
  488. # define uv__fs_scandir_free free
  489. #endif
  490. void uv__fs_scandir_cleanup(uv_fs_t* req) {
  491. uv__dirent_t** dents;
  492. unsigned int* nbufs = uv__get_nbufs(req);
  493. dents = req->ptr;
  494. if (*nbufs > 0 && *nbufs != (unsigned int) req->result)
  495. (*nbufs)--;
  496. for (; *nbufs < (unsigned int) req->result; (*nbufs)++)
  497. uv__fs_scandir_free(dents[*nbufs]);
  498. uv__fs_scandir_free(req->ptr);
  499. req->ptr = NULL;
  500. }
  501. int uv_fs_scandir_next(uv_fs_t* req, uv_dirent_t* ent) {
  502. uv__dirent_t** dents;
  503. uv__dirent_t* dent;
  504. unsigned int* nbufs;
  505. /* Check to see if req passed */
  506. if (req->result < 0)
  507. return req->result;
  508. /* Ptr will be null if req was canceled or no files found */
  509. if (!req->ptr)
  510. return UV_EOF;
  511. nbufs = uv__get_nbufs(req);
  512. assert(nbufs);
  513. dents = req->ptr;
  514. /* Free previous entity */
  515. if (*nbufs > 0)
  516. uv__fs_scandir_free(dents[*nbufs - 1]);
  517. /* End was already reached */
  518. if (*nbufs == (unsigned int) req->result) {
  519. uv__fs_scandir_free(dents);
  520. req->ptr = NULL;
  521. return UV_EOF;
  522. }
  523. dent = dents[(*nbufs)++];
  524. ent->name = dent->d_name;
  525. ent->type = uv__fs_get_dirent_type(dent);
  526. return 0;
  527. }
  528. uv_dirent_type_t uv__fs_get_dirent_type(uv__dirent_t* dent) {
  529. uv_dirent_type_t type;
  530. #ifdef HAVE_DIRENT_TYPES
  531. switch (dent->d_type) {
  532. case UV__DT_DIR:
  533. type = UV_DIRENT_DIR;
  534. break;
  535. case UV__DT_FILE:
  536. type = UV_DIRENT_FILE;
  537. break;
  538. case UV__DT_LINK:
  539. type = UV_DIRENT_LINK;
  540. break;
  541. case UV__DT_FIFO:
  542. type = UV_DIRENT_FIFO;
  543. break;
  544. case UV__DT_SOCKET:
  545. type = UV_DIRENT_SOCKET;
  546. break;
  547. case UV__DT_CHAR:
  548. type = UV_DIRENT_CHAR;
  549. break;
  550. case UV__DT_BLOCK:
  551. type = UV_DIRENT_BLOCK;
  552. break;
  553. default:
  554. type = UV_DIRENT_UNKNOWN;
  555. }
  556. #else
  557. type = UV_DIRENT_UNKNOWN;
  558. #endif
  559. return type;
  560. }
  561. void uv__fs_readdir_cleanup(uv_fs_t* req) {
  562. uv_dir_t* dir;
  563. uv_dirent_t* dirents;
  564. int i;
  565. if (req->ptr == NULL)
  566. return;
  567. dir = req->ptr;
  568. dirents = dir->dirents;
  569. req->ptr = NULL;
  570. if (dirents == NULL)
  571. return;
  572. for (i = 0; i < req->result; ++i) {
  573. uv__free((char*) dirents[i].name);
  574. dirents[i].name = NULL;
  575. }
  576. }
  577. int uv_loop_configure(uv_loop_t* loop, uv_loop_option option, ...) {
  578. va_list ap;
  579. int err;
  580. va_start(ap, option);
  581. /* Any platform-agnostic options should be handled here. */
  582. err = uv__loop_configure(loop, option, ap);
  583. va_end(ap);
  584. return err;
  585. }
  586. static uv_loop_t default_loop_struct;
  587. static uv_loop_t* default_loop_ptr;
  588. uv_loop_t* uv_default_loop(void) {
  589. if (default_loop_ptr != NULL)
  590. return default_loop_ptr;
  591. if (uv_loop_init(&default_loop_struct))
  592. return NULL;
  593. default_loop_ptr = &default_loop_struct;
  594. return default_loop_ptr;
  595. }
  596. uv_loop_t* uv_loop_new(void) {
  597. uv_loop_t* loop;
  598. loop = uv__malloc(sizeof(*loop));
  599. if (loop == NULL)
  600. return NULL;
  601. if (uv_loop_init(loop)) {
  602. uv__free(loop);
  603. return NULL;
  604. }
  605. return loop;
  606. }
  607. int uv_loop_close(uv_loop_t* loop) {
  608. QUEUE* q;
  609. uv_handle_t* h;
  610. #ifndef NDEBUG
  611. void* saved_data;
  612. #endif
  613. if (uv__has_active_reqs(loop))
  614. return UV_EBUSY;
  615. QUEUE_FOREACH(q, &loop->handle_queue) {
  616. h = QUEUE_DATA(q, uv_handle_t, handle_queue);
  617. if (!(h->flags & UV_HANDLE_INTERNAL))
  618. return UV_EBUSY;
  619. }
  620. uv__loop_close(loop);
  621. #ifndef NDEBUG
  622. saved_data = loop->data;
  623. memset(loop, -1, sizeof(*loop));
  624. loop->data = saved_data;
  625. #endif
  626. if (loop == default_loop_ptr)
  627. default_loop_ptr = NULL;
  628. return 0;
  629. }
  630. void uv_loop_delete(uv_loop_t* loop) {
  631. uv_loop_t* default_loop;
  632. int err;
  633. default_loop = default_loop_ptr;
  634. err = uv_loop_close(loop);
  635. (void) err; /* Squelch compiler warnings. */
  636. assert(err == 0);
  637. if (loop != default_loop)
  638. uv__free(loop);
  639. }
  640. void uv_os_free_environ(uv_env_item_t* envitems, int count) {
  641. int i;
  642. for (i = 0; i < count; i++) {
  643. uv__free(envitems[i].name);
  644. }
  645. uv__free(envitems);
  646. }
  647. void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
  648. int i;
  649. for (i = 0; i < count; i++)
  650. uv__free(cpu_infos[i].model);
  651. uv__free(cpu_infos);
  652. }
  653. #ifdef __GNUC__ /* Also covers __clang__ and __INTEL_COMPILER. */
  654. __attribute__((destructor))
  655. #endif
  656. void uv_library_shutdown(void) {
  657. static int was_shutdown;
  658. if (was_shutdown)
  659. return;
  660. uv__process_title_cleanup();
  661. uv__signal_cleanup();
  662. uv__threadpool_cleanup();
  663. was_shutdown = 1;
  664. }