1/*	$NetBSD: uv-compat.h,v 1.6 2024/02/21 22:52:32 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#include <uv.h>
18
19/*
20 * These functions were introduced in newer libuv, but we still
21 * want BIND9 compile on older ones so we emulate them.
22 * They're inline to avoid conflicts when running with a newer
23 * library version.
24 */
25
26#define UV_VERSION(major, minor, patch) ((major << 16) | (minor << 8) | (patch))
27
28/*
29 * Copied verbatim from libuv/src/version.c
30 */
31
32#define UV_STRINGIFY(v)	       UV_STRINGIFY_HELPER(v)
33#define UV_STRINGIFY_HELPER(v) #v
34
35#define UV_VERSION_STRING_BASE         \
36	UV_STRINGIFY(UV_VERSION_MAJOR) \
37	"." UV_STRINGIFY(UV_VERSION_MINOR) "." UV_STRINGIFY(UV_VERSION_PATCH)
38
39#if UV_VERSION_IS_RELEASE
40#define UV_VERSION_STRING UV_VERSION_STRING_BASE
41#else
42#define UV_VERSION_STRING UV_VERSION_STRING_BASE "-" UV_VERSION_SUFFIX
43#endif
44
45#if !defined(UV__ERR)
46#define UV__ERR(x) (-(x))
47#endif
48
49#if UV_VERSION_HEX < UV_VERSION(1, 19, 0)
50static inline void *
51uv_handle_get_data(const uv_handle_t *handle) {
52	return (handle->data);
53}
54
55static inline void
56uv_handle_set_data(uv_handle_t *handle, void *data) {
57	handle->data = data;
58}
59
60static inline void *
61uv_req_get_data(const uv_req_t *req) {
62	return (req->data);
63}
64
65static inline void
66uv_req_set_data(uv_req_t *req, void *data) {
67	req->data = data;
68}
69#endif /* UV_VERSION_HEX < UV_VERSION(1, 19, 0) */
70
71#if UV_VERSION_HEX < UV_VERSION(1, 32, 0)
72int
73uv_tcp_close_reset(uv_tcp_t *handle, uv_close_cb close_cb);
74#endif
75
76#if UV_VERSION_HEX < UV_VERSION(1, 34, 0)
77#define uv_sleep(msec) usleep((msec) * 1000)
78#endif /* UV_VERSION_HEX < UV_VERSION(1, 34, 0) */
79
80#if UV_VERSION_HEX < UV_VERSION(1, 27, 0)
81int
82isc_uv_udp_connect(uv_udp_t *handle, const struct sockaddr *addr);
83/*%<
84 * Associate the UDP handle to a remote address and port, so every message sent
85 * by this handle is automatically sent to that destination.
86 *
87 * NOTE: This is just a limited shim for uv_udp_connect() as it requires the
88 * handle to be bound.
89 */
90#else /* UV_VERSION_HEX < UV_VERSION(1, 27, 0) */
91#define isc_uv_udp_connect uv_udp_connect
92#endif /* UV_VERSION_HEX < UV_VERSION(1, 27, 0) */
93
94#if UV_VERSION_HEX < UV_VERSION(1, 12, 0)
95#include <stdlib.h>
96#include <string.h>
97
98static inline int
99uv_os_getenv(const char *name, char *buffer, size_t *size) {
100	size_t len;
101	char *buf = getenv(name);
102
103	if (buf == NULL) {
104		return (UV_ENOENT);
105	}
106
107	len = strlen(buf) + 1;
108	if (len > *size) {
109		*size = len;
110		return (UV_ENOBUFS);
111	}
112
113	*size = len;
114	memmove(buffer, buf, len);
115
116	return (0);
117}
118
119#define uv_os_setenv(name, value) setenv(name, value, 0)
120#endif /* UV_VERSION_HEX < UV_VERSION(1, 12, 0) */
121
122int
123isc_uv_udp_freebind(uv_udp_t *handle, const struct sockaddr *addr,
124		    unsigned int flags);
125
126int
127isc_uv_tcp_freebind(uv_tcp_t *handle, const struct sockaddr *addr,
128		    unsigned int flags);
129