1 /* $NetBSD: uv_wrap.h,v 1.3 2025/01/26 16:25:50 christos Exp $ */ 2 3 /* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * SPDX-License-Identifier: MPL-2.0 7 * 8 * This Source Code Form is subject to the terms of the Mozilla Public 9 * License, v. 2.0. If a copy of the MPL was not distributed with this 10 * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11 * 12 * See the COPYRIGHT file distributed with this work for additional 13 * information regarding copyright ownership. 14 */ 15 16 #pragma once 17 18 #if HAVE_CMOCKA 19 #include <inttypes.h> 20 #include <sched.h> /* IWYU pragma: keep */ 21 #include <setjmp.h> 22 #include <stdarg.h> 23 #include <stdbool.h> 24 #include <stddef.h> 25 #include <stdlib.h> 26 #include <time.h> 27 #include <unistd.h> 28 29 #include <isc/atomic.h> 30 #include <isc/util.h> 31 32 #define UNIT_TESTING 33 #include <cmocka.h> 34 35 #include <isc/uv.h> 36 37 /* uv_udp_t */ 38 39 int 40 __wrap_uv_udp_open(uv_udp_t *handle, uv_os_sock_t sock); 41 int 42 __wrap_uv_udp_bind(uv_udp_t *handle, const struct sockaddr *addr, 43 unsigned int flags); 44 int 45 __wrap_uv_udp_connect(uv_udp_t *handle, const struct sockaddr *addr); 46 int 47 __wrap_uv_udp_getpeername(const uv_udp_t *handle, struct sockaddr *name, 48 int *namelen); 49 int 50 __wrap_uv_udp_getsockname(const uv_udp_t *handle, struct sockaddr *name, 51 int *namelen); 52 int 53 __wrap_uv_udp_send(uv_udp_send_t *req, uv_udp_t *handle, const uv_buf_t bufs[], 54 unsigned int nbufs, const struct sockaddr *addr, 55 uv_udp_send_cb send_cb); 56 int 57 __wrap_uv_udp_recv_start(uv_udp_t *handle, uv_alloc_cb alloc_cb, 58 uv_udp_recv_cb recv_cb); 59 int 60 __wrap_uv_udp_recv_stop(uv_udp_t *handle); 61 62 /* uv_tcp_t */ 63 int 64 __wrap_uv_tcp_open(uv_tcp_t *handle, uv_os_sock_t sock); 65 int 66 __wrap_uv_tcp_bind(uv_tcp_t *handle, const struct sockaddr *addr, 67 unsigned int flags); 68 int 69 __wrap_uv_tcp_getsockname(const uv_tcp_t *handle, struct sockaddr *name, 70 int *namelen); 71 int 72 __wrap_uv_tcp_getpeername(const uv_tcp_t *handle, struct sockaddr *name, 73 int *namelen); 74 int 75 __wrap_uv_tcp_connect(uv_connect_t *req, uv_tcp_t *handle, 76 const struct sockaddr *addr, uv_connect_cb cb); 77 78 /* uv_stream_t */ 79 int 80 __wrap_uv_listen(uv_stream_t *stream, int backlog, uv_connection_cb cb); 81 int 82 __wrap_uv_accept(uv_stream_t *server, uv_stream_t *client); 83 84 /* uv_handle_t */ 85 int 86 __wrap_uv_send_buffer_size(uv_handle_t *handle, int *value); 87 int 88 __wrap_uv_recv_buffer_size(uv_handle_t *handle, int *value); 89 int 90 __wrap_uv_fileno(const uv_handle_t *handle, uv_os_fd_t *fd); 91 92 /* uv_timer_t */ 93 /* FIXME */ 94 /* 95 * uv_timer_init 96 * uv_timer_start 97 */ 98 99 static atomic_int __state_uv_udp_open = 0; 100 101 int 102 __wrap_uv_udp_open(uv_udp_t *handle, uv_os_sock_t sock) { 103 if (atomic_load(&__state_uv_udp_open) == 0) { 104 return uv_udp_open(handle, sock); 105 } 106 return atomic_load(&__state_uv_udp_open); 107 } 108 109 static atomic_int __state_uv_udp_bind = 0; 110 111 int 112 __wrap_uv_udp_bind(uv_udp_t *handle, const struct sockaddr *addr, 113 unsigned int flags) { 114 if (atomic_load(&__state_uv_udp_bind) == 0) { 115 return uv_udp_bind(handle, addr, flags); 116 } 117 return atomic_load(&__state_uv_udp_bind); 118 } 119 120 static atomic_int __state_uv_udp_connect ISC_ATTR_UNUSED = 0; 121 122 int 123 __wrap_uv_udp_connect(uv_udp_t *handle, const struct sockaddr *addr) { 124 if (atomic_load(&__state_uv_udp_connect) == 0) { 125 return uv_udp_connect(handle, addr); 126 } 127 return atomic_load(&__state_uv_udp_connect); 128 } 129 130 static atomic_int __state_uv_udp_getpeername ISC_ATTR_UNUSED = 0; 131 132 int 133 __wrap_uv_udp_getpeername(const uv_udp_t *handle, struct sockaddr *name, 134 int *namelen) { 135 if (atomic_load(&__state_uv_udp_getpeername) == 0) { 136 return uv_udp_getpeername(handle, name, namelen); 137 } 138 return atomic_load(&__state_uv_udp_getpeername); 139 } 140 141 static atomic_int __state_uv_udp_getsockname = 0; 142 int 143 __wrap_uv_udp_getsockname(const uv_udp_t *handle, struct sockaddr *name, 144 int *namelen) { 145 if (atomic_load(&__state_uv_udp_getsockname) == 0) { 146 return uv_udp_getsockname(handle, name, namelen); 147 } 148 return atomic_load(&__state_uv_udp_getsockname); 149 } 150 151 static atomic_int __state_uv_udp_send = 0; 152 int 153 __wrap_uv_udp_send(uv_udp_send_t *req, uv_udp_t *handle, const uv_buf_t bufs[], 154 unsigned int nbufs, const struct sockaddr *addr, 155 uv_udp_send_cb send_cb) { 156 if (atomic_load(&__state_uv_udp_send) == 0) { 157 return uv_udp_send(req, handle, bufs, nbufs, addr, send_cb); 158 } 159 return atomic_load(&__state_uv_udp_send); 160 } 161 162 static atomic_int __state_uv_udp_recv_start = 0; 163 int 164 __wrap_uv_udp_recv_start(uv_udp_t *handle, uv_alloc_cb alloc_cb, 165 uv_udp_recv_cb recv_cb) { 166 if (atomic_load(&__state_uv_udp_recv_start) == 0) { 167 return uv_udp_recv_start(handle, alloc_cb, recv_cb); 168 } 169 return atomic_load(&__state_uv_udp_recv_start); 170 } 171 172 static atomic_int __state_uv_udp_recv_stop = 0; 173 int 174 __wrap_uv_udp_recv_stop(uv_udp_t *handle) { 175 if (atomic_load(&__state_uv_udp_recv_stop) == 0) { 176 return uv_udp_recv_stop(handle); 177 } 178 return atomic_load(&__state_uv_udp_recv_stop); 179 } 180 181 static atomic_int __state_uv_tcp_open = 0; 182 int 183 __wrap_uv_tcp_open(uv_tcp_t *handle, uv_os_sock_t sock) { 184 if (atomic_load(&__state_uv_tcp_open) == 0) { 185 return uv_tcp_open(handle, sock); 186 } 187 return atomic_load(&__state_uv_tcp_open); 188 } 189 190 static atomic_int __state_uv_tcp_bind = 0; 191 int 192 __wrap_uv_tcp_bind(uv_tcp_t *handle, const struct sockaddr *addr, 193 unsigned int flags) { 194 if (atomic_load(&__state_uv_tcp_bind) == 0) { 195 return uv_tcp_bind(handle, addr, flags); 196 } 197 return atomic_load(&__state_uv_tcp_bind); 198 } 199 200 static atomic_int __state_uv_tcp_getsockname = 0; 201 int 202 __wrap_uv_tcp_getsockname(const uv_tcp_t *handle, struct sockaddr *name, 203 int *namelen) { 204 if (atomic_load(&__state_uv_tcp_getsockname) == 0) { 205 return uv_tcp_getsockname(handle, name, namelen); 206 } 207 return atomic_load(&__state_uv_tcp_getsockname); 208 } 209 210 static atomic_int __state_uv_tcp_getpeername = 0; 211 int 212 __wrap_uv_tcp_getpeername(const uv_tcp_t *handle, struct sockaddr *name, 213 int *namelen) { 214 if (atomic_load(&__state_uv_tcp_getpeername) == 0) { 215 return uv_tcp_getpeername(handle, name, namelen); 216 } 217 return atomic_load(&__state_uv_tcp_getpeername); 218 } 219 220 static atomic_int __state_uv_tcp_connect = 0; 221 int 222 __wrap_uv_tcp_connect(uv_connect_t *req, uv_tcp_t *handle, 223 const struct sockaddr *addr, uv_connect_cb cb) { 224 if (atomic_load(&__state_uv_tcp_connect) == 0) { 225 return uv_tcp_connect(req, handle, addr, cb); 226 } 227 return atomic_load(&__state_uv_tcp_connect); 228 } 229 230 static atomic_int __state_uv_listen = 0; 231 int 232 __wrap_uv_listen(uv_stream_t *stream, int backlog, uv_connection_cb cb) { 233 if (atomic_load(&__state_uv_listen) == 0) { 234 return uv_listen(stream, backlog, cb); 235 } 236 return atomic_load(&__state_uv_listen); 237 } 238 239 static atomic_int __state_uv_accept = 0; 240 int 241 __wrap_uv_accept(uv_stream_t *server, uv_stream_t *client) { 242 if (atomic_load(&__state_uv_accept) == 0) { 243 return uv_accept(server, client); 244 } 245 return atomic_load(&__state_uv_accept); 246 } 247 248 static atomic_int __state_uv_send_buffer_size = 0; 249 int 250 __wrap_uv_send_buffer_size(uv_handle_t *handle, int *value) { 251 if (atomic_load(&__state_uv_send_buffer_size) == 0) { 252 return uv_send_buffer_size(handle, value); 253 } 254 return atomic_load(&__state_uv_send_buffer_size); 255 } 256 257 static atomic_int __state_uv_recv_buffer_size = 0; 258 int 259 __wrap_uv_recv_buffer_size(uv_handle_t *handle, int *value) { 260 if (atomic_load(&__state_uv_recv_buffer_size) == 0) { 261 return uv_recv_buffer_size(handle, value); 262 } 263 return atomic_load(&__state_uv_recv_buffer_size); 264 } 265 266 static atomic_int __state_uv_fileno = 0; 267 int 268 __wrap_uv_fileno(const uv_handle_t *handle, uv_os_fd_t *fd) { 269 if (atomic_load(&__state_uv_fileno) == 0) { 270 return uv_fileno(handle, fd); 271 } 272 return atomic_load(&__state_uv_fileno); 273 } 274 275 #define uv_udp_open(...) __wrap_uv_udp_open(__VA_ARGS__) 276 #define uv_udp_bind(...) __wrap_uv_udp_bind(__VA_ARGS__) 277 #define uv_udp_connect(...) __wrap_uv_udp_connect(__VA_ARGS__) 278 #define uv_udp_getpeername(...) __wrap_uv_udp_getpeername(__VA_ARGS__) 279 #define uv_udp_getsockname(...) __wrap_uv_udp_getsockname(__VA_ARGS__) 280 #define uv_udp_send(...) __wrap_uv_udp_send(__VA_ARGS__) 281 #define uv_udp_recv_start(...) __wrap_uv_udp_recv_start(__VA_ARGS__) 282 #define uv_udp_recv_stop(...) __wrap_uv_udp_recv_stop(__VA_ARGS__) 283 284 #define uv_tcp_open(...) __wrap_uv_tcp_open(__VA_ARGS__) 285 #define uv_tcp_bind(...) __wrap_uv_tcp_bind(__VA_ARGS__) 286 #define uv_tcp_getsockname(...) __wrap_uv_tcp_getsockname(__VA_ARGS__) 287 #define uv_tcp_getpeername(...) __wrap_uv_tcp_getpeername(__VA_ARGS__) 288 #define uv_tcp_connect(...) __wrap_uv_tcp_connect(__VA_ARGS__) 289 290 #define uv_listen(...) __wrap_uv_listen(__VA_ARGS__) 291 #define uv_accept(...) __wrap_uv_accept(__VA_ARGS__) 292 293 #define uv_send_buffer_size(...) __wrap_uv_send_buffer_size(__VA_ARGS__) 294 #define uv_recv_buffer_size(...) __wrap_uv_recv_buffer_size(__VA_ARGS__) 295 #define uv_fileno(...) __wrap_uv_fileno(__VA_ARGS__) 296 297 #define RESET_RETURN \ 298 { \ 299 atomic_store(&__state_uv_udp_open, 0); \ 300 atomic_store(&__state_uv_udp_bind, 0); \ 301 atomic_store(&__state_uv_udp_connect, 0); \ 302 atomic_store(&__state_uv_udp_getpeername, 0); \ 303 atomic_store(&__state_uv_udp_getsockname, 0); \ 304 atomic_store(&__state_uv_udp_send, 0); \ 305 atomic_store(&__state_uv_udp_recv_start, 0); \ 306 atomic_store(&__state_uv_udp_recv_stop, 0); \ 307 atomic_store(&__state_uv_tcp_open, 0); \ 308 atomic_store(&__state_uv_tcp_bind, 0); \ 309 atomic_store(&__state_uv_tcp_getpeername, 0); \ 310 atomic_store(&__state_uv_tcp_getsockname, 0); \ 311 atomic_store(&__state_uv_tcp_connect, 0); \ 312 atomic_store(&__state_uv_listen, 0); \ 313 atomic_store(&__state_uv_accept, 0); \ 314 atomic_store(&__state_uv_send_buffer_size, 0); \ 315 atomic_store(&__state_uv_recv_buffer_size, 0); \ 316 atomic_store(&__state_uv_fileno, 0); \ 317 } 318 319 #define WILL_RETURN(func, value) atomic_store(&__state_##func, value) 320 321 #endif /* HAVE_CMOCKA */ 322