Coverage Report

Created: 2025-11-11 07:03

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