Home | History | Annotate | Line # | Download | only in isc
      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