Blame


1 3bb9eb8b 2024-01-18 thomas /* $OpenBSD: imsg-buffer.c,v 1.18 2023/12/12 15:47:41 claudio Exp $ */
2 dd038bc6 2021-09-21 thomas.ad
3 dd038bc6 2021-09-21 thomas.ad /*
4 3bb9eb8b 2024-01-18 thomas * Copyright (c) 2023 Claudio Jeker <claudio@openbsd.org>
5 dd038bc6 2021-09-21 thomas.ad * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
6 dd038bc6 2021-09-21 thomas.ad *
7 dd038bc6 2021-09-21 thomas.ad * Permission to use, copy, modify, and distribute this software for any
8 dd038bc6 2021-09-21 thomas.ad * purpose with or without fee is hereby granted, provided that the above
9 dd038bc6 2021-09-21 thomas.ad * copyright notice and this permission notice appear in all copies.
10 dd038bc6 2021-09-21 thomas.ad *
11 dd038bc6 2021-09-21 thomas.ad * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 dd038bc6 2021-09-21 thomas.ad * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 dd038bc6 2021-09-21 thomas.ad * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 dd038bc6 2021-09-21 thomas.ad * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 dd038bc6 2021-09-21 thomas.ad * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 dd038bc6 2021-09-21 thomas.ad * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 dd038bc6 2021-09-21 thomas.ad * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 dd038bc6 2021-09-21 thomas.ad */
19 dd038bc6 2021-09-21 thomas.ad
20 dd038bc6 2021-09-21 thomas.ad #include <sys/types.h>
21 dd038bc6 2021-09-21 thomas.ad #include <sys/socket.h>
22 dd038bc6 2021-09-21 thomas.ad #include <sys/uio.h>
23 3bb9eb8b 2024-01-18 thomas #include <arpa/inet.h>
24 dd038bc6 2021-09-21 thomas.ad
25 dd038bc6 2021-09-21 thomas.ad #include <limits.h>
26 dd038bc6 2021-09-21 thomas.ad #include <errno.h>
27 3bb9eb8b 2024-01-18 thomas #include <stdint.h>
28 dd038bc6 2021-09-21 thomas.ad #include <stdlib.h>
29 dd038bc6 2021-09-21 thomas.ad #include <string.h>
30 dd038bc6 2021-09-21 thomas.ad #include <unistd.h>
31 dd038bc6 2021-09-21 thomas.ad
32 dd038bc6 2021-09-21 thomas.ad #include "got_compat.h"
33 4fccd2fe 2023-03-08 thomas #include "imsg.h"
34 dd038bc6 2021-09-21 thomas.ad
35 dd038bc6 2021-09-21 thomas.ad static int ibuf_realloc(struct ibuf *, size_t);
36 dd038bc6 2021-09-21 thomas.ad static void ibuf_enqueue(struct msgbuf *, struct ibuf *);
37 dd038bc6 2021-09-21 thomas.ad static void ibuf_dequeue(struct msgbuf *, struct ibuf *);
38 3ef3f36a 2023-07-05 op static void msgbuf_drain(struct msgbuf *, size_t);
39 dd038bc6 2021-09-21 thomas.ad
40 dd038bc6 2021-09-21 thomas.ad struct ibuf *
41 dd038bc6 2021-09-21 thomas.ad ibuf_open(size_t len)
42 dd038bc6 2021-09-21 thomas.ad {
43 dd038bc6 2021-09-21 thomas.ad struct ibuf *buf;
44 dd038bc6 2021-09-21 thomas.ad
45 3ef3f36a 2023-07-05 op if (len == 0) {
46 3ef3f36a 2023-07-05 op errno = EINVAL;
47 3ef3f36a 2023-07-05 op return (NULL);
48 3ef3f36a 2023-07-05 op }
49 dd038bc6 2021-09-21 thomas.ad if ((buf = calloc(1, sizeof(struct ibuf))) == NULL)
50 dd038bc6 2021-09-21 thomas.ad return (NULL);
51 3ef3f36a 2023-07-05 op if ((buf->buf = calloc(len, 1)) == NULL) {
52 dd038bc6 2021-09-21 thomas.ad free(buf);
53 dd038bc6 2021-09-21 thomas.ad return (NULL);
54 dd038bc6 2021-09-21 thomas.ad }
55 dd038bc6 2021-09-21 thomas.ad buf->size = buf->max = len;
56 dd038bc6 2021-09-21 thomas.ad buf->fd = -1;
57 dd038bc6 2021-09-21 thomas.ad
58 dd038bc6 2021-09-21 thomas.ad return (buf);
59 dd038bc6 2021-09-21 thomas.ad }
60 dd038bc6 2021-09-21 thomas.ad
61 dd038bc6 2021-09-21 thomas.ad struct ibuf *
62 dd038bc6 2021-09-21 thomas.ad ibuf_dynamic(size_t len, size_t max)
63 dd038bc6 2021-09-21 thomas.ad {
64 dd038bc6 2021-09-21 thomas.ad struct ibuf *buf;
65 dd038bc6 2021-09-21 thomas.ad
66 3bb9eb8b 2024-01-18 thomas if (max == 0 || max < len) {
67 3ef3f36a 2023-07-05 op errno = EINVAL;
68 dd038bc6 2021-09-21 thomas.ad return (NULL);
69 3ef3f36a 2023-07-05 op }
70 dd038bc6 2021-09-21 thomas.ad
71 3ef3f36a 2023-07-05 op if ((buf = calloc(1, sizeof(struct ibuf))) == NULL)
72 dd038bc6 2021-09-21 thomas.ad return (NULL);
73 3ef3f36a 2023-07-05 op if (len > 0) {
74 3ef3f36a 2023-07-05 op if ((buf->buf = calloc(len, 1)) == NULL) {
75 3ef3f36a 2023-07-05 op free(buf);
76 3ef3f36a 2023-07-05 op return (NULL);
77 3ef3f36a 2023-07-05 op }
78 3ef3f36a 2023-07-05 op }
79 3ef3f36a 2023-07-05 op buf->size = len;
80 3ef3f36a 2023-07-05 op buf->max = max;
81 3ef3f36a 2023-07-05 op buf->fd = -1;
82 dd038bc6 2021-09-21 thomas.ad
83 dd038bc6 2021-09-21 thomas.ad return (buf);
84 dd038bc6 2021-09-21 thomas.ad }
85 dd038bc6 2021-09-21 thomas.ad
86 dd038bc6 2021-09-21 thomas.ad static int
87 dd038bc6 2021-09-21 thomas.ad ibuf_realloc(struct ibuf *buf, size_t len)
88 dd038bc6 2021-09-21 thomas.ad {
89 3ef3f36a 2023-07-05 op unsigned char *b;
90 dd038bc6 2021-09-21 thomas.ad
91 dd038bc6 2021-09-21 thomas.ad /* on static buffers max is eq size and so the following fails */
92 3ef3f36a 2023-07-05 op if (len > SIZE_MAX - buf->wpos || buf->wpos + len > buf->max) {
93 dd038bc6 2021-09-21 thomas.ad errno = ERANGE;
94 dd038bc6 2021-09-21 thomas.ad return (-1);
95 dd038bc6 2021-09-21 thomas.ad }
96 dd038bc6 2021-09-21 thomas.ad
97 c0faa645 2021-09-21 thomas.ad b = recallocarray(buf->buf, buf->size, buf->wpos + len, 1);
98 dd038bc6 2021-09-21 thomas.ad if (b == NULL)
99 dd038bc6 2021-09-21 thomas.ad return (-1);
100 dd038bc6 2021-09-21 thomas.ad buf->buf = b;
101 dd038bc6 2021-09-21 thomas.ad buf->size = buf->wpos + len;
102 dd038bc6 2021-09-21 thomas.ad
103 dd038bc6 2021-09-21 thomas.ad return (0);
104 dd038bc6 2021-09-21 thomas.ad }
105 dd038bc6 2021-09-21 thomas.ad
106 dd038bc6 2021-09-21 thomas.ad void *
107 dd038bc6 2021-09-21 thomas.ad ibuf_reserve(struct ibuf *buf, size_t len)
108 dd038bc6 2021-09-21 thomas.ad {
109 dd038bc6 2021-09-21 thomas.ad void *b;
110 dd038bc6 2021-09-21 thomas.ad
111 3bb9eb8b 2024-01-18 thomas if (len > SIZE_MAX - buf->wpos || buf->max == 0) {
112 3ef3f36a 2023-07-05 op errno = ERANGE;
113 3ef3f36a 2023-07-05 op return (NULL);
114 3ef3f36a 2023-07-05 op }
115 3ef3f36a 2023-07-05 op
116 dd038bc6 2021-09-21 thomas.ad if (buf->wpos + len > buf->size)
117 dd038bc6 2021-09-21 thomas.ad if (ibuf_realloc(buf, len) == -1)
118 dd038bc6 2021-09-21 thomas.ad return (NULL);
119 dd038bc6 2021-09-21 thomas.ad
120 dd038bc6 2021-09-21 thomas.ad b = buf->buf + buf->wpos;
121 dd038bc6 2021-09-21 thomas.ad buf->wpos += len;
122 dd038bc6 2021-09-21 thomas.ad return (b);
123 dd038bc6 2021-09-21 thomas.ad }
124 dd038bc6 2021-09-21 thomas.ad
125 3ef3f36a 2023-07-05 op int
126 3ef3f36a 2023-07-05 op ibuf_add(struct ibuf *buf, const void *data, size_t len)
127 3ef3f36a 2023-07-05 op {
128 3ef3f36a 2023-07-05 op void *b;
129 3ef3f36a 2023-07-05 op
130 3ef3f36a 2023-07-05 op if ((b = ibuf_reserve(buf, len)) == NULL)
131 3ef3f36a 2023-07-05 op return (-1);
132 3ef3f36a 2023-07-05 op
133 3ef3f36a 2023-07-05 op memcpy(b, data, len);
134 3ef3f36a 2023-07-05 op return (0);
135 3ef3f36a 2023-07-05 op }
136 3ef3f36a 2023-07-05 op
137 3ef3f36a 2023-07-05 op int
138 3bb9eb8b 2024-01-18 thomas ibuf_add_ibuf(struct ibuf *buf, const struct ibuf *from)
139 3bb9eb8b 2024-01-18 thomas {
140 3bb9eb8b 2024-01-18 thomas return ibuf_add(buf, ibuf_data(from), ibuf_size(from));
141 3bb9eb8b 2024-01-18 thomas }
142 3bb9eb8b 2024-01-18 thomas
143 3bb9eb8b 2024-01-18 thomas /* remove after tree is converted */
144 3bb9eb8b 2024-01-18 thomas int
145 3ef3f36a 2023-07-05 op ibuf_add_buf(struct ibuf *buf, const struct ibuf *from)
146 3ef3f36a 2023-07-05 op {
147 3bb9eb8b 2024-01-18 thomas return ibuf_add_ibuf(buf, from);
148 3ef3f36a 2023-07-05 op }
149 3ef3f36a 2023-07-05 op
150 3ef3f36a 2023-07-05 op int
151 3ef3f36a 2023-07-05 op ibuf_add_n8(struct ibuf *buf, uint64_t value)
152 3ef3f36a 2023-07-05 op {
153 3ef3f36a 2023-07-05 op uint8_t v;
154 3ef3f36a 2023-07-05 op
155 3ef3f36a 2023-07-05 op if (value > UINT8_MAX) {
156 3ef3f36a 2023-07-05 op errno = EINVAL;
157 3ef3f36a 2023-07-05 op return (-1);
158 3ef3f36a 2023-07-05 op }
159 3ef3f36a 2023-07-05 op v = value;
160 3ef3f36a 2023-07-05 op return ibuf_add(buf, &v, sizeof(v));
161 3ef3f36a 2023-07-05 op }
162 3ef3f36a 2023-07-05 op
163 3ef3f36a 2023-07-05 op int
164 3ef3f36a 2023-07-05 op ibuf_add_n16(struct ibuf *buf, uint64_t value)
165 3ef3f36a 2023-07-05 op {
166 3ef3f36a 2023-07-05 op uint16_t v;
167 3ef3f36a 2023-07-05 op
168 3ef3f36a 2023-07-05 op if (value > UINT16_MAX) {
169 3ef3f36a 2023-07-05 op errno = EINVAL;
170 3ef3f36a 2023-07-05 op return (-1);
171 3ef3f36a 2023-07-05 op }
172 3ef3f36a 2023-07-05 op v = htobe16(value);
173 3ef3f36a 2023-07-05 op return ibuf_add(buf, &v, sizeof(v));
174 3ef3f36a 2023-07-05 op }
175 3ef3f36a 2023-07-05 op
176 3ef3f36a 2023-07-05 op int
177 3ef3f36a 2023-07-05 op ibuf_add_n32(struct ibuf *buf, uint64_t value)
178 3ef3f36a 2023-07-05 op {
179 3ef3f36a 2023-07-05 op uint32_t v;
180 3ef3f36a 2023-07-05 op
181 3ef3f36a 2023-07-05 op if (value > UINT32_MAX) {
182 3ef3f36a 2023-07-05 op errno = EINVAL;
183 3ef3f36a 2023-07-05 op return (-1);
184 3ef3f36a 2023-07-05 op }
185 3ef3f36a 2023-07-05 op v = htobe32(value);
186 3ef3f36a 2023-07-05 op return ibuf_add(buf, &v, sizeof(v));
187 3ef3f36a 2023-07-05 op }
188 3ef3f36a 2023-07-05 op
189 3ef3f36a 2023-07-05 op int
190 3ef3f36a 2023-07-05 op ibuf_add_n64(struct ibuf *buf, uint64_t value)
191 3ef3f36a 2023-07-05 op {
192 3ef3f36a 2023-07-05 op value = htobe64(value);
193 3bb9eb8b 2024-01-18 thomas return ibuf_add(buf, &value, sizeof(value));
194 3bb9eb8b 2024-01-18 thomas }
195 3bb9eb8b 2024-01-18 thomas
196 3bb9eb8b 2024-01-18 thomas int
197 3bb9eb8b 2024-01-18 thomas ibuf_add_h16(struct ibuf *buf, uint64_t value)
198 3bb9eb8b 2024-01-18 thomas {
199 3bb9eb8b 2024-01-18 thomas uint16_t v;
200 3bb9eb8b 2024-01-18 thomas
201 3bb9eb8b 2024-01-18 thomas if (value > UINT16_MAX) {
202 3bb9eb8b 2024-01-18 thomas errno = EINVAL;
203 3bb9eb8b 2024-01-18 thomas return (-1);
204 3bb9eb8b 2024-01-18 thomas }
205 3bb9eb8b 2024-01-18 thomas v = value;
206 3bb9eb8b 2024-01-18 thomas return ibuf_add(buf, &v, sizeof(v));
207 3bb9eb8b 2024-01-18 thomas }
208 3bb9eb8b 2024-01-18 thomas
209 3bb9eb8b 2024-01-18 thomas int
210 3bb9eb8b 2024-01-18 thomas ibuf_add_h32(struct ibuf *buf, uint64_t value)
211 3bb9eb8b 2024-01-18 thomas {
212 3bb9eb8b 2024-01-18 thomas uint32_t v;
213 3bb9eb8b 2024-01-18 thomas
214 3bb9eb8b 2024-01-18 thomas if (value > UINT32_MAX) {
215 3bb9eb8b 2024-01-18 thomas errno = EINVAL;
216 3bb9eb8b 2024-01-18 thomas return (-1);
217 3bb9eb8b 2024-01-18 thomas }
218 3bb9eb8b 2024-01-18 thomas v = value;
219 3bb9eb8b 2024-01-18 thomas return ibuf_add(buf, &v, sizeof(v));
220 3bb9eb8b 2024-01-18 thomas }
221 3bb9eb8b 2024-01-18 thomas
222 3bb9eb8b 2024-01-18 thomas int
223 3bb9eb8b 2024-01-18 thomas ibuf_add_h64(struct ibuf *buf, uint64_t value)
224 3bb9eb8b 2024-01-18 thomas {
225 3ef3f36a 2023-07-05 op return ibuf_add(buf, &value, sizeof(value));
226 3ef3f36a 2023-07-05 op }
227 3ef3f36a 2023-07-05 op
228 3ef3f36a 2023-07-05 op int
229 3ef3f36a 2023-07-05 op ibuf_add_zero(struct ibuf *buf, size_t len)
230 3ef3f36a 2023-07-05 op {
231 3ef3f36a 2023-07-05 op void *b;
232 3ef3f36a 2023-07-05 op
233 3ef3f36a 2023-07-05 op if ((b = ibuf_reserve(buf, len)) == NULL)
234 3ef3f36a 2023-07-05 op return (-1);
235 3bb9eb8b 2024-01-18 thomas memset(b, 0, len);
236 3ef3f36a 2023-07-05 op return (0);
237 3ef3f36a 2023-07-05 op }
238 3ef3f36a 2023-07-05 op
239 dd038bc6 2021-09-21 thomas.ad void *
240 dd038bc6 2021-09-21 thomas.ad ibuf_seek(struct ibuf *buf, size_t pos, size_t len)
241 dd038bc6 2021-09-21 thomas.ad {
242 3bb9eb8b 2024-01-18 thomas /* only allow seeking between rpos and wpos */
243 3bb9eb8b 2024-01-18 thomas if (ibuf_size(buf) < pos || SIZE_MAX - pos < len ||
244 3bb9eb8b 2024-01-18 thomas ibuf_size(buf) < pos + len) {
245 3ef3f36a 2023-07-05 op errno = ERANGE;
246 dd038bc6 2021-09-21 thomas.ad return (NULL);
247 3ef3f36a 2023-07-05 op }
248 dd038bc6 2021-09-21 thomas.ad
249 3bb9eb8b 2024-01-18 thomas return (buf->buf + buf->rpos + pos);
250 dd038bc6 2021-09-21 thomas.ad }
251 dd038bc6 2021-09-21 thomas.ad
252 3ef3f36a 2023-07-05 op int
253 3ef3f36a 2023-07-05 op ibuf_set(struct ibuf *buf, size_t pos, const void *data, size_t len)
254 3ef3f36a 2023-07-05 op {
255 3ef3f36a 2023-07-05 op void *b;
256 3ef3f36a 2023-07-05 op
257 3ef3f36a 2023-07-05 op if ((b = ibuf_seek(buf, pos, len)) == NULL)
258 3ef3f36a 2023-07-05 op return (-1);
259 3ef3f36a 2023-07-05 op
260 3ef3f36a 2023-07-05 op memcpy(b, data, len);
261 3ef3f36a 2023-07-05 op return (0);
262 3ef3f36a 2023-07-05 op }
263 3ef3f36a 2023-07-05 op
264 3ef3f36a 2023-07-05 op int
265 3ef3f36a 2023-07-05 op ibuf_set_n8(struct ibuf *buf, size_t pos, uint64_t value)
266 3ef3f36a 2023-07-05 op {
267 3ef3f36a 2023-07-05 op uint8_t v;
268 3ef3f36a 2023-07-05 op
269 3ef3f36a 2023-07-05 op if (value > UINT8_MAX) {
270 3ef3f36a 2023-07-05 op errno = EINVAL;
271 3ef3f36a 2023-07-05 op return (-1);
272 3ef3f36a 2023-07-05 op }
273 3ef3f36a 2023-07-05 op v = value;
274 3ef3f36a 2023-07-05 op return (ibuf_set(buf, pos, &v, sizeof(v)));
275 3ef3f36a 2023-07-05 op }
276 3ef3f36a 2023-07-05 op
277 3ef3f36a 2023-07-05 op int
278 3ef3f36a 2023-07-05 op ibuf_set_n16(struct ibuf *buf, size_t pos, uint64_t value)
279 3ef3f36a 2023-07-05 op {
280 3ef3f36a 2023-07-05 op uint16_t v;
281 3ef3f36a 2023-07-05 op
282 3ef3f36a 2023-07-05 op if (value > UINT16_MAX) {
283 3ef3f36a 2023-07-05 op errno = EINVAL;
284 3ef3f36a 2023-07-05 op return (-1);
285 3ef3f36a 2023-07-05 op }
286 3ef3f36a 2023-07-05 op v = htobe16(value);
287 3ef3f36a 2023-07-05 op return (ibuf_set(buf, pos, &v, sizeof(v)));
288 3ef3f36a 2023-07-05 op }
289 3ef3f36a 2023-07-05 op
290 3ef3f36a 2023-07-05 op int
291 3ef3f36a 2023-07-05 op ibuf_set_n32(struct ibuf *buf, size_t pos, uint64_t value)
292 3ef3f36a 2023-07-05 op {
293 3ef3f36a 2023-07-05 op uint32_t v;
294 3ef3f36a 2023-07-05 op
295 3ef3f36a 2023-07-05 op if (value > UINT32_MAX) {
296 3ef3f36a 2023-07-05 op errno = EINVAL;
297 3ef3f36a 2023-07-05 op return (-1);
298 3ef3f36a 2023-07-05 op }
299 3ef3f36a 2023-07-05 op v = htobe32(value);
300 3ef3f36a 2023-07-05 op return (ibuf_set(buf, pos, &v, sizeof(v)));
301 3ef3f36a 2023-07-05 op }
302 3ef3f36a 2023-07-05 op
303 3ef3f36a 2023-07-05 op int
304 3ef3f36a 2023-07-05 op ibuf_set_n64(struct ibuf *buf, size_t pos, uint64_t value)
305 3ef3f36a 2023-07-05 op {
306 3ef3f36a 2023-07-05 op value = htobe64(value);
307 3ef3f36a 2023-07-05 op return (ibuf_set(buf, pos, &value, sizeof(value)));
308 3ef3f36a 2023-07-05 op }
309 3ef3f36a 2023-07-05 op
310 3bb9eb8b 2024-01-18 thomas int
311 3bb9eb8b 2024-01-18 thomas ibuf_set_h16(struct ibuf *buf, size_t pos, uint64_t value)
312 3ef3f36a 2023-07-05 op {
313 3bb9eb8b 2024-01-18 thomas uint16_t v;
314 3ef3f36a 2023-07-05 op
315 3bb9eb8b 2024-01-18 thomas if (value > UINT16_MAX) {
316 3bb9eb8b 2024-01-18 thomas errno = EINVAL;
317 3bb9eb8b 2024-01-18 thomas return (-1);
318 3bb9eb8b 2024-01-18 thomas }
319 3bb9eb8b 2024-01-18 thomas v = value;
320 3bb9eb8b 2024-01-18 thomas return (ibuf_set(buf, pos, &v, sizeof(v)));
321 dd038bc6 2021-09-21 thomas.ad }
322 dd038bc6 2021-09-21 thomas.ad
323 3bb9eb8b 2024-01-18 thomas int
324 3bb9eb8b 2024-01-18 thomas ibuf_set_h32(struct ibuf *buf, size_t pos, uint64_t value)
325 3bb9eb8b 2024-01-18 thomas {
326 3bb9eb8b 2024-01-18 thomas uint32_t v;
327 3bb9eb8b 2024-01-18 thomas
328 3bb9eb8b 2024-01-18 thomas if (value > UINT32_MAX) {
329 3bb9eb8b 2024-01-18 thomas errno = EINVAL;
330 3bb9eb8b 2024-01-18 thomas return (-1);
331 3bb9eb8b 2024-01-18 thomas }
332 3bb9eb8b 2024-01-18 thomas v = value;
333 3bb9eb8b 2024-01-18 thomas return (ibuf_set(buf, pos, &v, sizeof(v)));
334 3bb9eb8b 2024-01-18 thomas }
335 3bb9eb8b 2024-01-18 thomas
336 3bb9eb8b 2024-01-18 thomas int
337 3bb9eb8b 2024-01-18 thomas ibuf_set_h64(struct ibuf *buf, size_t pos, uint64_t value)
338 3bb9eb8b 2024-01-18 thomas {
339 3bb9eb8b 2024-01-18 thomas return (ibuf_set(buf, pos, &value, sizeof(value)));
340 3bb9eb8b 2024-01-18 thomas }
341 3bb9eb8b 2024-01-18 thomas
342 3bb9eb8b 2024-01-18 thomas void *
343 3bb9eb8b 2024-01-18 thomas ibuf_data(const struct ibuf *buf)
344 3bb9eb8b 2024-01-18 thomas {
345 3bb9eb8b 2024-01-18 thomas return (buf->buf + buf->rpos);
346 3bb9eb8b 2024-01-18 thomas }
347 3bb9eb8b 2024-01-18 thomas
348 dd038bc6 2021-09-21 thomas.ad size_t
349 3bb9eb8b 2024-01-18 thomas ibuf_size(const struct ibuf *buf)
350 dd038bc6 2021-09-21 thomas.ad {
351 3bb9eb8b 2024-01-18 thomas return (buf->wpos - buf->rpos);
352 3bb9eb8b 2024-01-18 thomas }
353 3bb9eb8b 2024-01-18 thomas
354 3bb9eb8b 2024-01-18 thomas size_t
355 3bb9eb8b 2024-01-18 thomas ibuf_left(const struct ibuf *buf)
356 3bb9eb8b 2024-01-18 thomas {
357 3bb9eb8b 2024-01-18 thomas if (buf->max == 0)
358 3bb9eb8b 2024-01-18 thomas return (0);
359 dd038bc6 2021-09-21 thomas.ad return (buf->max - buf->wpos);
360 dd038bc6 2021-09-21 thomas.ad }
361 dd038bc6 2021-09-21 thomas.ad
362 3bb9eb8b 2024-01-18 thomas int
363 3bb9eb8b 2024-01-18 thomas ibuf_truncate(struct ibuf *buf, size_t len)
364 3bb9eb8b 2024-01-18 thomas {
365 3bb9eb8b 2024-01-18 thomas if (ibuf_size(buf) >= len) {
366 3bb9eb8b 2024-01-18 thomas buf->wpos = buf->rpos + len;
367 3bb9eb8b 2024-01-18 thomas return (0);
368 3bb9eb8b 2024-01-18 thomas }
369 3bb9eb8b 2024-01-18 thomas if (buf->max == 0) {
370 3bb9eb8b 2024-01-18 thomas /* only allow to truncate down */
371 3bb9eb8b 2024-01-18 thomas errno = ERANGE;
372 3bb9eb8b 2024-01-18 thomas return (-1);
373 3bb9eb8b 2024-01-18 thomas }
374 3bb9eb8b 2024-01-18 thomas return ibuf_add_zero(buf, len - ibuf_size(buf));
375 3bb9eb8b 2024-01-18 thomas }
376 3bb9eb8b 2024-01-18 thomas
377 dd038bc6 2021-09-21 thomas.ad void
378 3bb9eb8b 2024-01-18 thomas ibuf_rewind(struct ibuf *buf)
379 3bb9eb8b 2024-01-18 thomas {
380 3bb9eb8b 2024-01-18 thomas buf->rpos = 0;
381 3bb9eb8b 2024-01-18 thomas }
382 3bb9eb8b 2024-01-18 thomas
383 3bb9eb8b 2024-01-18 thomas void
384 dd038bc6 2021-09-21 thomas.ad ibuf_close(struct msgbuf *msgbuf, struct ibuf *buf)
385 dd038bc6 2021-09-21 thomas.ad {
386 dd038bc6 2021-09-21 thomas.ad ibuf_enqueue(msgbuf, buf);
387 3bb9eb8b 2024-01-18 thomas }
388 3bb9eb8b 2024-01-18 thomas
389 3bb9eb8b 2024-01-18 thomas void
390 3bb9eb8b 2024-01-18 thomas ibuf_from_buffer(struct ibuf *buf, void *data, size_t len)
391 3bb9eb8b 2024-01-18 thomas {
392 3bb9eb8b 2024-01-18 thomas memset(buf, 0, sizeof(*buf));
393 3bb9eb8b 2024-01-18 thomas buf->buf = data;
394 3bb9eb8b 2024-01-18 thomas buf->size = buf->wpos = len;
395 3bb9eb8b 2024-01-18 thomas buf->fd = -1;
396 dd038bc6 2021-09-21 thomas.ad }
397 dd038bc6 2021-09-21 thomas.ad
398 3ef3f36a 2023-07-05 op void
399 3bb9eb8b 2024-01-18 thomas ibuf_from_ibuf(struct ibuf *buf, const struct ibuf *from)
400 3bb9eb8b 2024-01-18 thomas {
401 3bb9eb8b 2024-01-18 thomas ibuf_from_buffer(buf, ibuf_data(from), ibuf_size(from));
402 3bb9eb8b 2024-01-18 thomas }
403 3bb9eb8b 2024-01-18 thomas
404 3bb9eb8b 2024-01-18 thomas int
405 3bb9eb8b 2024-01-18 thomas ibuf_get(struct ibuf *buf, void *data, size_t len)
406 3bb9eb8b 2024-01-18 thomas {
407 3bb9eb8b 2024-01-18 thomas if (ibuf_size(buf) < len) {
408 3bb9eb8b 2024-01-18 thomas errno = EBADMSG;
409 3bb9eb8b 2024-01-18 thomas return (-1);
410 3bb9eb8b 2024-01-18 thomas }
411 3bb9eb8b 2024-01-18 thomas
412 3bb9eb8b 2024-01-18 thomas memcpy(data, ibuf_data(buf), len);
413 3bb9eb8b 2024-01-18 thomas buf->rpos += len;
414 3bb9eb8b 2024-01-18 thomas return (0);
415 3bb9eb8b 2024-01-18 thomas }
416 3bb9eb8b 2024-01-18 thomas
417 3bb9eb8b 2024-01-18 thomas int
418 3bb9eb8b 2024-01-18 thomas ibuf_get_ibuf(struct ibuf *buf, size_t len, struct ibuf *new)
419 3bb9eb8b 2024-01-18 thomas {
420 3bb9eb8b 2024-01-18 thomas if (ibuf_size(buf) < len) {
421 3bb9eb8b 2024-01-18 thomas errno = EBADMSG;
422 3bb9eb8b 2024-01-18 thomas return (-1);
423 3bb9eb8b 2024-01-18 thomas }
424 3bb9eb8b 2024-01-18 thomas
425 3bb9eb8b 2024-01-18 thomas ibuf_from_buffer(new, ibuf_data(buf), len);
426 3bb9eb8b 2024-01-18 thomas buf->rpos += len;
427 3bb9eb8b 2024-01-18 thomas return (0);
428 3bb9eb8b 2024-01-18 thomas }
429 3bb9eb8b 2024-01-18 thomas
430 3bb9eb8b 2024-01-18 thomas int
431 3bb9eb8b 2024-01-18 thomas ibuf_get_n8(struct ibuf *buf, uint8_t *value)
432 3bb9eb8b 2024-01-18 thomas {
433 3bb9eb8b 2024-01-18 thomas return ibuf_get(buf, value, sizeof(*value));
434 3bb9eb8b 2024-01-18 thomas }
435 3bb9eb8b 2024-01-18 thomas
436 3bb9eb8b 2024-01-18 thomas int
437 3bb9eb8b 2024-01-18 thomas ibuf_get_n16(struct ibuf *buf, uint16_t *value)
438 3bb9eb8b 2024-01-18 thomas {
439 3bb9eb8b 2024-01-18 thomas int rv;
440 3bb9eb8b 2024-01-18 thomas
441 3bb9eb8b 2024-01-18 thomas rv = ibuf_get(buf, value, sizeof(*value));
442 3bb9eb8b 2024-01-18 thomas *value = be16toh(*value);
443 3bb9eb8b 2024-01-18 thomas return (rv);
444 3bb9eb8b 2024-01-18 thomas }
445 3bb9eb8b 2024-01-18 thomas
446 3bb9eb8b 2024-01-18 thomas int
447 3bb9eb8b 2024-01-18 thomas ibuf_get_n32(struct ibuf *buf, uint32_t *value)
448 3bb9eb8b 2024-01-18 thomas {
449 3bb9eb8b 2024-01-18 thomas int rv;
450 3bb9eb8b 2024-01-18 thomas
451 3bb9eb8b 2024-01-18 thomas rv = ibuf_get(buf, value, sizeof(*value));
452 3bb9eb8b 2024-01-18 thomas *value = be32toh(*value);
453 3bb9eb8b 2024-01-18 thomas return (rv);
454 3bb9eb8b 2024-01-18 thomas }
455 3bb9eb8b 2024-01-18 thomas
456 3bb9eb8b 2024-01-18 thomas int
457 3bb9eb8b 2024-01-18 thomas ibuf_get_n64(struct ibuf *buf, uint64_t *value)
458 3bb9eb8b 2024-01-18 thomas {
459 3bb9eb8b 2024-01-18 thomas int rv;
460 3bb9eb8b 2024-01-18 thomas
461 3bb9eb8b 2024-01-18 thomas rv = ibuf_get(buf, value, sizeof(*value));
462 3bb9eb8b 2024-01-18 thomas *value = be64toh(*value);
463 3bb9eb8b 2024-01-18 thomas return (rv);
464 3bb9eb8b 2024-01-18 thomas }
465 3bb9eb8b 2024-01-18 thomas
466 3bb9eb8b 2024-01-18 thomas int
467 3bb9eb8b 2024-01-18 thomas ibuf_get_h16(struct ibuf *buf, uint16_t *value)
468 3bb9eb8b 2024-01-18 thomas {
469 3bb9eb8b 2024-01-18 thomas return ibuf_get(buf, value, sizeof(*value));
470 3bb9eb8b 2024-01-18 thomas }
471 3bb9eb8b 2024-01-18 thomas
472 3bb9eb8b 2024-01-18 thomas int
473 3bb9eb8b 2024-01-18 thomas ibuf_get_h32(struct ibuf *buf, uint32_t *value)
474 3bb9eb8b 2024-01-18 thomas {
475 3bb9eb8b 2024-01-18 thomas return ibuf_get(buf, value, sizeof(*value));
476 3bb9eb8b 2024-01-18 thomas }
477 3bb9eb8b 2024-01-18 thomas
478 3bb9eb8b 2024-01-18 thomas int
479 3bb9eb8b 2024-01-18 thomas ibuf_get_h64(struct ibuf *buf, uint64_t *value)
480 3bb9eb8b 2024-01-18 thomas {
481 3bb9eb8b 2024-01-18 thomas return ibuf_get(buf, value, sizeof(*value));
482 3bb9eb8b 2024-01-18 thomas }
483 3bb9eb8b 2024-01-18 thomas
484 3bb9eb8b 2024-01-18 thomas int
485 3bb9eb8b 2024-01-18 thomas ibuf_skip(struct ibuf *buf, size_t len)
486 3bb9eb8b 2024-01-18 thomas {
487 3bb9eb8b 2024-01-18 thomas if (ibuf_size(buf) < len) {
488 3bb9eb8b 2024-01-18 thomas errno = EBADMSG;
489 3bb9eb8b 2024-01-18 thomas return (-1);
490 3bb9eb8b 2024-01-18 thomas }
491 3bb9eb8b 2024-01-18 thomas
492 3bb9eb8b 2024-01-18 thomas buf->rpos += len;
493 3bb9eb8b 2024-01-18 thomas return (0);
494 3bb9eb8b 2024-01-18 thomas }
495 3bb9eb8b 2024-01-18 thomas
496 3bb9eb8b 2024-01-18 thomas void
497 3ef3f36a 2023-07-05 op ibuf_free(struct ibuf *buf)
498 3ef3f36a 2023-07-05 op {
499 3ef3f36a 2023-07-05 op if (buf == NULL)
500 3ef3f36a 2023-07-05 op return;
501 3bb9eb8b 2024-01-18 thomas if (buf->max == 0) /* if buf lives on the stack */
502 3bb9eb8b 2024-01-18 thomas abort(); /* abort before causing more harm */
503 3ef3f36a 2023-07-05 op if (buf->fd != -1)
504 3ef3f36a 2023-07-05 op close(buf->fd);
505 3ef3f36a 2023-07-05 op freezero(buf->buf, buf->size);
506 3ef3f36a 2023-07-05 op free(buf);
507 3ef3f36a 2023-07-05 op }
508 3ef3f36a 2023-07-05 op
509 dd038bc6 2021-09-21 thomas.ad int
510 3ef3f36a 2023-07-05 op ibuf_fd_avail(struct ibuf *buf)
511 3ef3f36a 2023-07-05 op {
512 3ef3f36a 2023-07-05 op return (buf->fd != -1);
513 3ef3f36a 2023-07-05 op }
514 3ef3f36a 2023-07-05 op
515 3ef3f36a 2023-07-05 op int
516 3ef3f36a 2023-07-05 op ibuf_fd_get(struct ibuf *buf)
517 3ef3f36a 2023-07-05 op {
518 3ef3f36a 2023-07-05 op int fd;
519 3ef3f36a 2023-07-05 op
520 3ef3f36a 2023-07-05 op fd = buf->fd;
521 3ef3f36a 2023-07-05 op buf->fd = -1;
522 3ef3f36a 2023-07-05 op return (fd);
523 3ef3f36a 2023-07-05 op }
524 3ef3f36a 2023-07-05 op
525 3ef3f36a 2023-07-05 op void
526 3ef3f36a 2023-07-05 op ibuf_fd_set(struct ibuf *buf, int fd)
527 3ef3f36a 2023-07-05 op {
528 3bb9eb8b 2024-01-18 thomas if (buf->max == 0) /* if buf lives on the stack */
529 3bb9eb8b 2024-01-18 thomas abort(); /* abort before causing more harm */
530 3ef3f36a 2023-07-05 op if (buf->fd != -1)
531 3ef3f36a 2023-07-05 op close(buf->fd);
532 3ef3f36a 2023-07-05 op buf->fd = fd;
533 3ef3f36a 2023-07-05 op }
534 3ef3f36a 2023-07-05 op
535 3ef3f36a 2023-07-05 op int
536 dd038bc6 2021-09-21 thomas.ad ibuf_write(struct msgbuf *msgbuf)
537 dd038bc6 2021-09-21 thomas.ad {
538 dd038bc6 2021-09-21 thomas.ad struct iovec iov[IOV_MAX];
539 dd038bc6 2021-09-21 thomas.ad struct ibuf *buf;
540 dd038bc6 2021-09-21 thomas.ad unsigned int i = 0;
541 dd038bc6 2021-09-21 thomas.ad ssize_t n;
542 dd038bc6 2021-09-21 thomas.ad
543 dd038bc6 2021-09-21 thomas.ad memset(&iov, 0, sizeof(iov));
544 dd038bc6 2021-09-21 thomas.ad TAILQ_FOREACH(buf, &msgbuf->bufs, entry) {
545 dd038bc6 2021-09-21 thomas.ad if (i >= IOV_MAX)
546 dd038bc6 2021-09-21 thomas.ad break;
547 3bb9eb8b 2024-01-18 thomas iov[i].iov_base = ibuf_data(buf);
548 3bb9eb8b 2024-01-18 thomas iov[i].iov_len = ibuf_size(buf);
549 dd038bc6 2021-09-21 thomas.ad i++;
550 dd038bc6 2021-09-21 thomas.ad }
551 dd038bc6 2021-09-21 thomas.ad
552 dd038bc6 2021-09-21 thomas.ad again:
553 dd038bc6 2021-09-21 thomas.ad if ((n = writev(msgbuf->fd, iov, i)) == -1) {
554 dd038bc6 2021-09-21 thomas.ad if (errno == EINTR)
555 dd038bc6 2021-09-21 thomas.ad goto again;
556 dd038bc6 2021-09-21 thomas.ad if (errno == ENOBUFS)
557 dd038bc6 2021-09-21 thomas.ad errno = EAGAIN;
558 dd038bc6 2021-09-21 thomas.ad return (-1);
559 dd038bc6 2021-09-21 thomas.ad }
560 dd038bc6 2021-09-21 thomas.ad
561 dd038bc6 2021-09-21 thomas.ad if (n == 0) { /* connection closed */
562 dd038bc6 2021-09-21 thomas.ad errno = 0;
563 dd038bc6 2021-09-21 thomas.ad return (0);
564 dd038bc6 2021-09-21 thomas.ad }
565 dd038bc6 2021-09-21 thomas.ad
566 dd038bc6 2021-09-21 thomas.ad msgbuf_drain(msgbuf, n);
567 dd038bc6 2021-09-21 thomas.ad
568 dd038bc6 2021-09-21 thomas.ad return (1);
569 dd038bc6 2021-09-21 thomas.ad }
570 dd038bc6 2021-09-21 thomas.ad
571 dd038bc6 2021-09-21 thomas.ad void
572 dd038bc6 2021-09-21 thomas.ad msgbuf_init(struct msgbuf *msgbuf)
573 dd038bc6 2021-09-21 thomas.ad {
574 dd038bc6 2021-09-21 thomas.ad msgbuf->queued = 0;
575 dd038bc6 2021-09-21 thomas.ad msgbuf->fd = -1;
576 dd038bc6 2021-09-21 thomas.ad TAILQ_INIT(&msgbuf->bufs);
577 dd038bc6 2021-09-21 thomas.ad }
578 dd038bc6 2021-09-21 thomas.ad
579 3ef3f36a 2023-07-05 op static void
580 dd038bc6 2021-09-21 thomas.ad msgbuf_drain(struct msgbuf *msgbuf, size_t n)
581 dd038bc6 2021-09-21 thomas.ad {
582 dd038bc6 2021-09-21 thomas.ad struct ibuf *buf, *next;
583 dd038bc6 2021-09-21 thomas.ad
584 dd038bc6 2021-09-21 thomas.ad for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0;
585 dd038bc6 2021-09-21 thomas.ad buf = next) {
586 dd038bc6 2021-09-21 thomas.ad next = TAILQ_NEXT(buf, entry);
587 3bb9eb8b 2024-01-18 thomas if (n >= ibuf_size(buf)) {
588 3bb9eb8b 2024-01-18 thomas n -= ibuf_size(buf);
589 dd038bc6 2021-09-21 thomas.ad ibuf_dequeue(msgbuf, buf);
590 dd038bc6 2021-09-21 thomas.ad } else {
591 dd038bc6 2021-09-21 thomas.ad buf->rpos += n;
592 dd038bc6 2021-09-21 thomas.ad n = 0;
593 dd038bc6 2021-09-21 thomas.ad }
594 dd038bc6 2021-09-21 thomas.ad }
595 dd038bc6 2021-09-21 thomas.ad }
596 dd038bc6 2021-09-21 thomas.ad
597 dd038bc6 2021-09-21 thomas.ad void
598 dd038bc6 2021-09-21 thomas.ad msgbuf_clear(struct msgbuf *msgbuf)
599 dd038bc6 2021-09-21 thomas.ad {
600 dd038bc6 2021-09-21 thomas.ad struct ibuf *buf;
601 dd038bc6 2021-09-21 thomas.ad
602 dd038bc6 2021-09-21 thomas.ad while ((buf = TAILQ_FIRST(&msgbuf->bufs)) != NULL)
603 dd038bc6 2021-09-21 thomas.ad ibuf_dequeue(msgbuf, buf);
604 dd038bc6 2021-09-21 thomas.ad }
605 dd038bc6 2021-09-21 thomas.ad
606 dd038bc6 2021-09-21 thomas.ad int
607 dd038bc6 2021-09-21 thomas.ad msgbuf_write(struct msgbuf *msgbuf)
608 dd038bc6 2021-09-21 thomas.ad {
609 dd038bc6 2021-09-21 thomas.ad struct iovec iov[IOV_MAX];
610 3ef3f36a 2023-07-05 op struct ibuf *buf, *buf0 = NULL;
611 dd038bc6 2021-09-21 thomas.ad unsigned int i = 0;
612 dd038bc6 2021-09-21 thomas.ad ssize_t n;
613 dd038bc6 2021-09-21 thomas.ad struct msghdr msg;
614 dd038bc6 2021-09-21 thomas.ad struct cmsghdr *cmsg;
615 dd038bc6 2021-09-21 thomas.ad union {
616 dd038bc6 2021-09-21 thomas.ad struct cmsghdr hdr;
617 dd038bc6 2021-09-21 thomas.ad char buf[CMSG_SPACE(sizeof(int))];
618 dd038bc6 2021-09-21 thomas.ad } cmsgbuf;
619 dd038bc6 2021-09-21 thomas.ad
620 dd038bc6 2021-09-21 thomas.ad memset(&iov, 0, sizeof(iov));
621 dd038bc6 2021-09-21 thomas.ad memset(&msg, 0, sizeof(msg));
622 dd038bc6 2021-09-21 thomas.ad memset(&cmsgbuf, 0, sizeof(cmsgbuf));
623 dd038bc6 2021-09-21 thomas.ad TAILQ_FOREACH(buf, &msgbuf->bufs, entry) {
624 dd038bc6 2021-09-21 thomas.ad if (i >= IOV_MAX)
625 dd038bc6 2021-09-21 thomas.ad break;
626 3ef3f36a 2023-07-05 op if (i > 0 && buf->fd != -1)
627 3ef3f36a 2023-07-05 op break;
628 3bb9eb8b 2024-01-18 thomas iov[i].iov_base = ibuf_data(buf);
629 3bb9eb8b 2024-01-18 thomas iov[i].iov_len = ibuf_size(buf);
630 dd038bc6 2021-09-21 thomas.ad i++;
631 dd038bc6 2021-09-21 thomas.ad if (buf->fd != -1)
632 3ef3f36a 2023-07-05 op buf0 = buf;
633 dd038bc6 2021-09-21 thomas.ad }
634 dd038bc6 2021-09-21 thomas.ad
635 dd038bc6 2021-09-21 thomas.ad msg.msg_iov = iov;
636 dd038bc6 2021-09-21 thomas.ad msg.msg_iovlen = i;
637 dd038bc6 2021-09-21 thomas.ad
638 3ef3f36a 2023-07-05 op if (buf0 != NULL) {
639 dd038bc6 2021-09-21 thomas.ad msg.msg_control = (caddr_t)&cmsgbuf.buf;
640 dd038bc6 2021-09-21 thomas.ad msg.msg_controllen = sizeof(cmsgbuf.buf);
641 dd038bc6 2021-09-21 thomas.ad cmsg = CMSG_FIRSTHDR(&msg);
642 dd038bc6 2021-09-21 thomas.ad cmsg->cmsg_len = CMSG_LEN(sizeof(int));
643 dd038bc6 2021-09-21 thomas.ad cmsg->cmsg_level = SOL_SOCKET;
644 dd038bc6 2021-09-21 thomas.ad cmsg->cmsg_type = SCM_RIGHTS;
645 3ef3f36a 2023-07-05 op *(int *)CMSG_DATA(cmsg) = buf0->fd;
646 dd038bc6 2021-09-21 thomas.ad }
647 dd038bc6 2021-09-21 thomas.ad
648 dd038bc6 2021-09-21 thomas.ad again:
649 dd038bc6 2021-09-21 thomas.ad if ((n = sendmsg(msgbuf->fd, &msg, 0)) == -1) {
650 dd038bc6 2021-09-21 thomas.ad if (errno == EINTR)
651 dd038bc6 2021-09-21 thomas.ad goto again;
652 dd038bc6 2021-09-21 thomas.ad if (errno == ENOBUFS)
653 dd038bc6 2021-09-21 thomas.ad errno = EAGAIN;
654 dd038bc6 2021-09-21 thomas.ad return (-1);
655 dd038bc6 2021-09-21 thomas.ad }
656 dd038bc6 2021-09-21 thomas.ad
657 dd038bc6 2021-09-21 thomas.ad if (n == 0) { /* connection closed */
658 dd038bc6 2021-09-21 thomas.ad errno = 0;
659 dd038bc6 2021-09-21 thomas.ad return (0);
660 dd038bc6 2021-09-21 thomas.ad }
661 dd038bc6 2021-09-21 thomas.ad
662 dd038bc6 2021-09-21 thomas.ad /*
663 dd038bc6 2021-09-21 thomas.ad * assumption: fd got sent if sendmsg sent anything
664 dd038bc6 2021-09-21 thomas.ad * this works because fds are passed one at a time
665 dd038bc6 2021-09-21 thomas.ad */
666 3ef3f36a 2023-07-05 op if (buf0 != NULL) {
667 3ef3f36a 2023-07-05 op close(buf0->fd);
668 3ef3f36a 2023-07-05 op buf0->fd = -1;
669 dd038bc6 2021-09-21 thomas.ad }
670 dd038bc6 2021-09-21 thomas.ad
671 dd038bc6 2021-09-21 thomas.ad msgbuf_drain(msgbuf, n);
672 dd038bc6 2021-09-21 thomas.ad
673 dd038bc6 2021-09-21 thomas.ad return (1);
674 dd038bc6 2021-09-21 thomas.ad }
675 dd038bc6 2021-09-21 thomas.ad
676 3bb9eb8b 2024-01-18 thomas uint32_t
677 3bb9eb8b 2024-01-18 thomas msgbuf_queuelen(struct msgbuf *msgbuf)
678 3bb9eb8b 2024-01-18 thomas {
679 3bb9eb8b 2024-01-18 thomas return (msgbuf->queued);
680 3bb9eb8b 2024-01-18 thomas }
681 3bb9eb8b 2024-01-18 thomas
682 dd038bc6 2021-09-21 thomas.ad static void
683 dd038bc6 2021-09-21 thomas.ad ibuf_enqueue(struct msgbuf *msgbuf, struct ibuf *buf)
684 dd038bc6 2021-09-21 thomas.ad {
685 3bb9eb8b 2024-01-18 thomas if (buf->max == 0) /* if buf lives on the stack */
686 3bb9eb8b 2024-01-18 thomas abort(); /* abort before causing more harm */
687 dd038bc6 2021-09-21 thomas.ad TAILQ_INSERT_TAIL(&msgbuf->bufs, buf, entry);
688 dd038bc6 2021-09-21 thomas.ad msgbuf->queued++;
689 dd038bc6 2021-09-21 thomas.ad }
690 dd038bc6 2021-09-21 thomas.ad
691 dd038bc6 2021-09-21 thomas.ad static void
692 dd038bc6 2021-09-21 thomas.ad ibuf_dequeue(struct msgbuf *msgbuf, struct ibuf *buf)
693 dd038bc6 2021-09-21 thomas.ad {
694 dd038bc6 2021-09-21 thomas.ad TAILQ_REMOVE(&msgbuf->bufs, buf, entry);
695 dd038bc6 2021-09-21 thomas.ad msgbuf->queued--;
696 dd038bc6 2021-09-21 thomas.ad ibuf_free(buf);
697 dd038bc6 2021-09-21 thomas.ad }