1 1.1 christos /* $NetBSD: uv.c,v 1.3 2026/01/29 18:37:55 christos Exp $ */ 2 1.1 christos 3 1.1 christos /* 4 1.1 christos * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 1.1 christos * 6 1.1 christos * SPDX-License-Identifier: MPL-2.0 7 1.1 christos * 8 1.1 christos * This Source Code Form is subject to the terms of the Mozilla Public 9 1.1 christos * License, v. 2.0. If a copy of the MPL was not distributed with this 10 1.1 christos * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11 1.1 christos * 12 1.1 christos * See the COPYRIGHT file distributed with this work for additional 13 1.1 christos * information regarding copyright ownership. 14 1.1 christos */ 15 1.1 christos 16 1.1 christos #include <unistd.h> 17 1.1 christos 18 1.1 christos #include <isc/mem.h> 19 1.1 christos #include <isc/util.h> 20 1.1 christos #include <isc/uv.h> 21 1.1 christos 22 1.1 christos /*% 23 1.1 christos * Convert a libuv error value into an isc_result_t. The 24 1.1 christos * list of supported error values is not complete; new users 25 1.1 christos * of this function should add any expected errors that are 26 1.1 christos * not already there. 27 1.1 christos */ 28 1.1 christos isc_result_t 29 1.1 christos isc__uverr2result(int uverr, bool dolog, const char *file, unsigned int line, 30 1.1 christos const char *func) { 31 1.1 christos switch (uverr) { 32 1.1 christos case 0: 33 1.1 christos return ISC_R_SUCCESS; 34 1.1 christos case UV_ENOTDIR: 35 1.1 christos case UV_ELOOP: 36 1.1 christos case UV_EINVAL: /* XXX sometimes this is not for files */ 37 1.1 christos case UV_ENAMETOOLONG: 38 1.1 christos case UV_EBADF: 39 1.1 christos return ISC_R_INVALIDFILE; 40 1.1 christos case UV_ENOENT: 41 1.1 christos return ISC_R_FILENOTFOUND; 42 1.1 christos case UV_EAGAIN: 43 1.1 christos return ISC_R_NOCONN; 44 1.1 christos case UV_EACCES: 45 1.1 christos case UV_EPERM: 46 1.1 christos return ISC_R_NOPERM; 47 1.1 christos case UV_EEXIST: 48 1.1 christos return ISC_R_FILEEXISTS; 49 1.1 christos case UV_EIO: 50 1.1 christos return ISC_R_IOERROR; 51 1.1 christos case UV_ENOMEM: 52 1.1 christos return ISC_R_NOMEMORY; 53 1.1 christos case UV_ENFILE: 54 1.1 christos case UV_EMFILE: 55 1.1 christos return ISC_R_TOOMANYOPENFILES; 56 1.1 christos case UV_ENOSPC: 57 1.1 christos return ISC_R_DISCFULL; 58 1.1 christos case UV_EPIPE: 59 1.1 christos case UV_ECONNRESET: 60 1.1 christos case UV_ECONNABORTED: 61 1.1 christos return ISC_R_CONNECTIONRESET; 62 1.1 christos case UV_ENOTCONN: 63 1.1 christos return ISC_R_NOTCONNECTED; 64 1.1 christos case UV_ETIMEDOUT: 65 1.1 christos return ISC_R_TIMEDOUT; 66 1.1 christos case UV_ENOBUFS: 67 1.1 christos return ISC_R_NORESOURCES; 68 1.1 christos case UV_EAFNOSUPPORT: 69 1.1 christos return ISC_R_FAMILYNOSUPPORT; 70 1.1 christos case UV_ENETDOWN: 71 1.1 christos return ISC_R_NETDOWN; 72 1.1 christos case UV_EHOSTDOWN: 73 1.1 christos return ISC_R_HOSTDOWN; 74 1.1 christos case UV_ENETUNREACH: 75 1.1 christos return ISC_R_NETUNREACH; 76 1.1 christos case UV_EHOSTUNREACH: 77 1.1 christos return ISC_R_HOSTUNREACH; 78 1.1 christos case UV_EADDRINUSE: 79 1.1 christos return ISC_R_ADDRINUSE; 80 1.1 christos case UV_EADDRNOTAVAIL: 81 1.1 christos return ISC_R_ADDRNOTAVAIL; 82 1.1 christos case UV_ECONNREFUSED: 83 1.1 christos return ISC_R_CONNREFUSED; 84 1.1 christos case UV_ECANCELED: 85 1.1 christos return ISC_R_CANCELED; 86 1.1 christos case UV_EOF: 87 1.1 christos return ISC_R_EOF; 88 1.1 christos case UV_EMSGSIZE: 89 1.1 christos return ISC_R_MAXSIZE; 90 1.1 christos case UV_ENOTSUP: 91 1.1 christos return ISC_R_FAMILYNOSUPPORT; 92 1.1 christos case UV_ENOPROTOOPT: 93 1.1 christos case UV_EPROTONOSUPPORT: 94 1.1 christos return ISC_R_INVALIDPROTO; 95 1.1 christos default: 96 1.1 christos if (dolog) { 97 1.1 christos UNEXPECTED_ERROR("unable to convert libuv error code " 98 1.1 christos "in %s (%s:%d) to isc_result: %d: %s", 99 1.1 christos func, file, line, uverr, 100 1.1 christos uv_strerror(uverr)); 101 1.1 christos } 102 1.1 christos return ISC_R_UNEXPECTED; 103 1.1 christos } 104 1.1 christos } 105 1.1 christos 106 1.1 christos #if UV_VERSION_HEX >= UV_VERSION(1, 38, 0) 107 1.1 christos static isc_mem_t *isc__uv_mctx = NULL; 108 1.1 christos 109 1.1 christos static void * 110 1.1 christos isc__uv_malloc(size_t size) { 111 1.1 christos return isc_mem_allocate(isc__uv_mctx, size); 112 1.1 christos } 113 1.1 christos 114 1.1 christos static void * 115 1.1 christos isc__uv_realloc(void *ptr, size_t size) { 116 1.1 christos return isc_mem_reallocate(isc__uv_mctx, ptr, size); 117 1.1 christos } 118 1.1 christos 119 1.1 christos static void * 120 1.1 christos isc__uv_calloc(size_t count, size_t size) { 121 1.1 christos return isc_mem_callocate(isc__uv_mctx, count, size); 122 1.1 christos } 123 1.1 christos 124 1.1 christos static void 125 1.1 christos isc__uv_free(void *ptr) { 126 1.1 christos if (ptr == NULL) { 127 1.1 christos return; 128 1.1 christos } 129 1.1 christos isc_mem_free(isc__uv_mctx, ptr); 130 1.1 christos } 131 1.1 christos #endif /* UV_VERSION_HEX >= UV_VERSION(1, 38, 0) */ 132 1.1 christos 133 1.1 christos void 134 1.1 christos isc__uv_initialize(void) { 135 1.3 christos /* 136 1.3 christos * Ensure the first 3 file descriptors are open 137 1.3 christos * otherwise, libuv may use one and trigger abort 138 1.3 christos * when closing it. 139 1.3 christos * 140 1.3 christos * See https://github.com/libuv/libuv/pull/4559 141 1.3 christos */ 142 1.3 christos do { 143 1.3 christos int fd = open("/dev/null", O_RDWR, 0); 144 1.3 christos RUNTIME_CHECK(fd >= 0); 145 1.3 christos if (fd > STDERR_FILENO) { 146 1.3 christos close(fd); 147 1.3 christos break; 148 1.3 christos } 149 1.3 christos } while (true); 150 1.1 christos #if UV_VERSION_HEX >= UV_VERSION(1, 38, 0) 151 1.1 christos int r; 152 1.1 christos isc_mem_create(&isc__uv_mctx); 153 1.1 christos isc_mem_setname(isc__uv_mctx, "uv"); 154 1.1 christos isc_mem_setdestroycheck(isc__uv_mctx, false); 155 1.1 christos 156 1.1 christos r = uv_replace_allocator(isc__uv_malloc, isc__uv_realloc, 157 1.1 christos isc__uv_calloc, isc__uv_free); 158 1.1 christos UV_RUNTIME_CHECK(uv_replace_allocator, r); 159 1.1 christos #endif /* UV_VERSION_HEX >= UV_VERSION(1, 38, 0) */ 160 1.1 christos } 161 1.1 christos 162 1.1 christos void 163 1.1 christos isc__uv_shutdown(void) { 164 1.1 christos #if UV_VERSION_HEX >= UV_VERSION(1, 38, 0) 165 1.1 christos uv_library_shutdown(); 166 1.1 christos isc_mem_destroy(&isc__uv_mctx); 167 1.1 christos #endif /* UV_VERSION_HEX < UV_VERSION(1, 38, 0) */ 168 1.1 christos } 169 1.1 christos 170 1.1 christos void 171 1.1 christos isc__uv_setdestroycheck(bool check) { 172 1.1 christos #if UV_VERSION_HEX >= UV_VERSION(1, 38, 0) 173 1.1 christos isc_mem_setdestroycheck(isc__uv_mctx, check); 174 1.1 christos #else 175 1.1 christos UNUSED(check); 176 1.1 christos #endif /* UV_VERSION_HEX >= UV_VERSION(1, 6, 0) */ 177 1.1 christos } 178