1 /*-
2 * Copyright (c) 2013 The FreeBSD Foundation
3 *
4 * This software was developed by Pawel Jakub Dawidek under sponsorship from
5 * the FreeBSD Foundation.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29 #include <sys/param.h>
30 #include <sys/socket.h>
31 #include <sys/sysctl.h>
32 #include <sys/wait.h>
33 #include <sys/nv.h>
34
35 #include <stdlib.h>
36 #include <err.h>
37 #include <errno.h>
38 #include <fcntl.h>
39 #include <paths.h>
40 #include <stdio.h>
41 #include <string.h>
42 #include <unistd.h>
43
44 #include <atf-c.h>
45
46 #define ALPHABET "abcdefghijklmnopqrstuvwxyz"
47 #define fd_is_valid(fd) (fcntl((fd), F_GETFL) != -1 || errno != EBADF)
48
49 static void
send_nvlist_child(int sock)50 send_nvlist_child(int sock)
51 {
52 nvlist_t *nvl;
53 nvlist_t *empty;
54 int pfd[2];
55
56 nvl = nvlist_create(0);
57 empty = nvlist_create(0);
58
59 nvlist_add_bool(nvl, "nvlist/bool/true", true);
60 nvlist_add_bool(nvl, "nvlist/bool/false", false);
61 nvlist_add_number(nvl, "nvlist/number/0", 0);
62 nvlist_add_number(nvl, "nvlist/number/1", 1);
63 nvlist_add_number(nvl, "nvlist/number/-1", -1);
64 nvlist_add_number(nvl, "nvlist/number/UINT64_MAX", UINT64_MAX);
65 nvlist_add_number(nvl, "nvlist/number/INT64_MIN", INT64_MIN);
66 nvlist_add_number(nvl, "nvlist/number/INT64_MAX", INT64_MAX);
67 nvlist_add_string(nvl, "nvlist/string/", "");
68 nvlist_add_string(nvl, "nvlist/string/x", "x");
69 nvlist_add_string(nvl, "nvlist/string/" ALPHABET, ALPHABET);
70
71 nvlist_add_descriptor(nvl, "nvlist/descriptor/STDERR_FILENO",
72 STDERR_FILENO);
73 if (pipe(pfd) == -1)
74 err(EXIT_FAILURE, "pipe");
75 if (write(pfd[1], "test", 4) != 4)
76 err(EXIT_FAILURE, "write");
77 close(pfd[1]);
78 nvlist_add_descriptor(nvl, "nvlist/descriptor/pipe_rd", pfd[0]);
79 close(pfd[0]);
80
81 nvlist_add_binary(nvl, "nvlist/binary/x", "x", 1);
82 nvlist_add_binary(nvl, "nvlist/binary/" ALPHABET, ALPHABET,
83 sizeof(ALPHABET));
84 nvlist_move_nvlist(nvl, "nvlist/nvlist/empty", empty);
85 nvlist_add_nvlist(nvl, "nvlist/nvlist", nvl);
86
87 nvlist_send(sock, nvl);
88
89 nvlist_destroy(nvl);
90 }
91
92 static void
send_nvlist_parent(int sock)93 send_nvlist_parent(int sock)
94 {
95 nvlist_t *nvl;
96 const nvlist_t *cnvl, *empty;
97 const char *name, *cname;
98 void *cookie, *ccookie;
99 int type, ctype, fd;
100 size_t size;
101 char buf[4];
102
103 nvl = nvlist_recv(sock, 0);
104 ATF_REQUIRE(nvlist_error(nvl) == 0);
105 if (nvlist_error(nvl) != 0)
106 err(1, "nvlist_recv() failed");
107
108 cookie = NULL;
109
110 name = nvlist_next(nvl, &type, &cookie);
111 ATF_REQUIRE(name != NULL);
112 ATF_REQUIRE(type == NV_TYPE_BOOL);
113 ATF_REQUIRE(strcmp(name, "nvlist/bool/true") == 0);
114 ATF_REQUIRE(nvlist_get_bool(nvl, name) == true);
115
116 name = nvlist_next(nvl, &type, &cookie);
117 ATF_REQUIRE(name != NULL);
118 ATF_REQUIRE(type == NV_TYPE_BOOL);
119 ATF_REQUIRE(strcmp(name, "nvlist/bool/false") == 0);
120 ATF_REQUIRE(nvlist_get_bool(nvl, name) == false);
121
122 name = nvlist_next(nvl, &type, &cookie);
123 ATF_REQUIRE(name != NULL);
124 ATF_REQUIRE(type == NV_TYPE_NUMBER);
125 ATF_REQUIRE(strcmp(name, "nvlist/number/0") == 0);
126 ATF_REQUIRE(nvlist_get_number(nvl, name) == 0);
127
128 name = nvlist_next(nvl, &type, &cookie);
129 ATF_REQUIRE(name != NULL);
130 ATF_REQUIRE(type == NV_TYPE_NUMBER);
131 ATF_REQUIRE(strcmp(name, "nvlist/number/1") == 0);
132 ATF_REQUIRE(nvlist_get_number(nvl, name) == 1);
133
134 name = nvlist_next(nvl, &type, &cookie);
135 ATF_REQUIRE(name != NULL);
136 ATF_REQUIRE(type == NV_TYPE_NUMBER);
137 ATF_REQUIRE(strcmp(name, "nvlist/number/-1") == 0);
138 ATF_REQUIRE((int)nvlist_get_number(nvl, name) == -1);
139
140 name = nvlist_next(nvl, &type, &cookie);
141 ATF_REQUIRE(name != NULL);
142 ATF_REQUIRE(type == NV_TYPE_NUMBER);
143 ATF_REQUIRE(strcmp(name, "nvlist/number/UINT64_MAX") == 0);
144 ATF_REQUIRE(nvlist_get_number(nvl, name) == UINT64_MAX);
145
146 name = nvlist_next(nvl, &type, &cookie);
147 ATF_REQUIRE(name != NULL);
148 ATF_REQUIRE(type == NV_TYPE_NUMBER);
149 ATF_REQUIRE(strcmp(name, "nvlist/number/INT64_MIN") == 0);
150 ATF_REQUIRE((int64_t)nvlist_get_number(nvl, name) == INT64_MIN);
151
152 name = nvlist_next(nvl, &type, &cookie);
153 ATF_REQUIRE(name != NULL);
154 ATF_REQUIRE(type == NV_TYPE_NUMBER);
155 ATF_REQUIRE(strcmp(name, "nvlist/number/INT64_MAX") == 0);
156 ATF_REQUIRE((int64_t)nvlist_get_number(nvl, name) == INT64_MAX);
157
158 name = nvlist_next(nvl, &type, &cookie);
159 ATF_REQUIRE(name != NULL);
160 ATF_REQUIRE(type == NV_TYPE_STRING);
161 ATF_REQUIRE(strcmp(name, "nvlist/string/") == 0);
162 ATF_REQUIRE(strcmp(nvlist_get_string(nvl, name), "") == 0);
163
164 name = nvlist_next(nvl, &type, &cookie);
165 ATF_REQUIRE(name != NULL);
166 ATF_REQUIRE(type == NV_TYPE_STRING);
167 ATF_REQUIRE(strcmp(name, "nvlist/string/x") == 0);
168 ATF_REQUIRE(strcmp(nvlist_get_string(nvl, name), "x") == 0);
169
170 name = nvlist_next(nvl, &type, &cookie);
171 ATF_REQUIRE(name != NULL);
172 ATF_REQUIRE(type == NV_TYPE_STRING);
173 ATF_REQUIRE(strcmp(name, "nvlist/string/" ALPHABET) == 0);
174 ATF_REQUIRE(strcmp(nvlist_get_string(nvl, name), ALPHABET) == 0);
175
176 name = nvlist_next(nvl, &type, &cookie);
177 ATF_REQUIRE(name != NULL);
178 ATF_REQUIRE(type == NV_TYPE_DESCRIPTOR);
179 ATF_REQUIRE(strcmp(name, "nvlist/descriptor/STDERR_FILENO") == 0);
180 ATF_REQUIRE(fd_is_valid(nvlist_get_descriptor(nvl, name)));
181
182 name = nvlist_next(nvl, &type, &cookie);
183 ATF_REQUIRE(name != NULL);
184 ATF_REQUIRE(type == NV_TYPE_DESCRIPTOR);
185 ATF_REQUIRE(strcmp(name, "nvlist/descriptor/pipe_rd") == 0);
186 fd = nvlist_get_descriptor(nvl, name);
187 ATF_REQUIRE(fd_is_valid(fd));
188 ATF_REQUIRE(read(fd, buf, sizeof(buf)) == 4);
189 ATF_REQUIRE(strncmp(buf, "test", sizeof(buf)) == 0);
190
191 name = nvlist_next(nvl, &type, &cookie);
192 ATF_REQUIRE(name != NULL);
193 ATF_REQUIRE(type == NV_TYPE_BINARY);
194 ATF_REQUIRE(strcmp(name, "nvlist/binary/x") == 0);
195 ATF_REQUIRE(memcmp(nvlist_get_binary(nvl, name, NULL), "x", 1) == 0);
196 ATF_REQUIRE(memcmp(nvlist_get_binary(nvl, name, &size), "x", 1) == 0);
197 ATF_REQUIRE(size == 1);
198
199 name = nvlist_next(nvl, &type, &cookie);
200 ATF_REQUIRE(name != NULL);
201 ATF_REQUIRE(type == NV_TYPE_BINARY);
202 ATF_REQUIRE(strcmp(name, "nvlist/binary/" ALPHABET) == 0);
203 ATF_REQUIRE(memcmp(nvlist_get_binary(nvl, name, NULL), ALPHABET,
204 sizeof(ALPHABET)) == 0);
205 ATF_REQUIRE(memcmp(nvlist_get_binary(nvl, name, &size), ALPHABET,
206 sizeof(ALPHABET)) == 0);
207 ATF_REQUIRE(size == sizeof(ALPHABET));
208
209 name = nvlist_next(nvl, &type, &cookie);
210 ATF_REQUIRE(name != NULL);
211 ATF_REQUIRE(type == NV_TYPE_NVLIST);
212 ATF_REQUIRE(strcmp(name, "nvlist/nvlist/empty") == 0);
213 cnvl = nvlist_get_nvlist(nvl, name);
214 ATF_REQUIRE(nvlist_empty(cnvl));
215
216 name = nvlist_next(nvl, &type, &cookie);
217 ATF_REQUIRE(name != NULL);
218 ATF_REQUIRE(type == NV_TYPE_NVLIST);
219 ATF_REQUIRE(strcmp(name, "nvlist/nvlist") == 0);
220 cnvl = nvlist_get_nvlist(nvl, name);
221
222 ccookie = NULL;
223
224 cname = nvlist_next(cnvl, &ctype, &ccookie);
225 ATF_REQUIRE(cname != NULL);
226 ATF_REQUIRE(ctype == NV_TYPE_BOOL);
227 ATF_REQUIRE(strcmp(cname, "nvlist/bool/true") == 0);
228 ATF_REQUIRE(nvlist_get_bool(cnvl, cname) == true);
229
230 cname = nvlist_next(cnvl, &ctype, &ccookie);
231 ATF_REQUIRE(cname != NULL);
232 ATF_REQUIRE(ctype == NV_TYPE_BOOL);
233 ATF_REQUIRE(strcmp(cname, "nvlist/bool/false") == 0);
234 ATF_REQUIRE(nvlist_get_bool(cnvl, cname) == false);
235
236 cname = nvlist_next(cnvl, &ctype, &ccookie);
237 ATF_REQUIRE(cname != NULL);
238 ATF_REQUIRE(ctype == NV_TYPE_NUMBER);
239 ATF_REQUIRE(strcmp(cname, "nvlist/number/0") == 0);
240 ATF_REQUIRE(nvlist_get_number(cnvl, cname) == 0);
241
242 cname = nvlist_next(cnvl, &ctype, &ccookie);
243 ATF_REQUIRE(cname != NULL);
244 ATF_REQUIRE(ctype == NV_TYPE_NUMBER);
245 ATF_REQUIRE(strcmp(cname, "nvlist/number/1") == 0);
246 ATF_REQUIRE(nvlist_get_number(cnvl, cname) == 1);
247
248 cname = nvlist_next(cnvl, &ctype, &ccookie);
249 ATF_REQUIRE(cname != NULL);
250 ATF_REQUIRE(ctype == NV_TYPE_NUMBER);
251 ATF_REQUIRE(strcmp(cname, "nvlist/number/-1") == 0);
252 ATF_REQUIRE((int)nvlist_get_number(cnvl, cname) == -1);
253
254 cname = nvlist_next(cnvl, &ctype, &ccookie);
255 ATF_REQUIRE(cname != NULL);
256 ATF_REQUIRE(ctype == NV_TYPE_NUMBER);
257 ATF_REQUIRE(strcmp(cname, "nvlist/number/UINT64_MAX") == 0);
258 ATF_REQUIRE(nvlist_get_number(cnvl, cname) == UINT64_MAX);
259
260 cname = nvlist_next(cnvl, &ctype, &ccookie);
261 ATF_REQUIRE(cname != NULL);
262 ATF_REQUIRE(ctype == NV_TYPE_NUMBER);
263 ATF_REQUIRE(strcmp(cname, "nvlist/number/INT64_MIN") == 0);
264 ATF_REQUIRE((int64_t)nvlist_get_number(cnvl, cname) == INT64_MIN);
265
266 cname = nvlist_next(cnvl, &ctype, &ccookie);
267 ATF_REQUIRE(cname != NULL);
268 ATF_REQUIRE(ctype == NV_TYPE_NUMBER);
269 ATF_REQUIRE(strcmp(cname, "nvlist/number/INT64_MAX") == 0);
270 ATF_REQUIRE((int64_t)nvlist_get_number(cnvl, cname) == INT64_MAX);
271
272 cname = nvlist_next(cnvl, &ctype, &ccookie);
273 ATF_REQUIRE(cname != NULL);
274 ATF_REQUIRE(ctype == NV_TYPE_STRING);
275 ATF_REQUIRE(strcmp(cname, "nvlist/string/") == 0);
276 ATF_REQUIRE(strcmp(nvlist_get_string(cnvl, cname), "") == 0);
277
278 cname = nvlist_next(cnvl, &ctype, &ccookie);
279 ATF_REQUIRE(cname != NULL);
280 ATF_REQUIRE(ctype == NV_TYPE_STRING);
281 ATF_REQUIRE(strcmp(cname, "nvlist/string/x") == 0);
282 ATF_REQUIRE(strcmp(nvlist_get_string(cnvl, cname), "x") == 0);
283
284 cname = nvlist_next(cnvl, &ctype, &ccookie);
285 ATF_REQUIRE(cname != NULL);
286 ATF_REQUIRE(ctype == NV_TYPE_STRING);
287 ATF_REQUIRE(strcmp(cname, "nvlist/string/" ALPHABET) == 0);
288 ATF_REQUIRE(strcmp(nvlist_get_string(cnvl, cname), ALPHABET) == 0);
289
290 cname = nvlist_next(cnvl, &ctype, &ccookie);
291 ATF_REQUIRE(cname != NULL);
292 ATF_REQUIRE(ctype == NV_TYPE_DESCRIPTOR);
293 ATF_REQUIRE(strcmp(cname, "nvlist/descriptor/STDERR_FILENO") == 0);
294 ATF_REQUIRE(fd_is_valid(nvlist_get_descriptor(cnvl, cname)));
295
296 cname = nvlist_next(cnvl, &ctype, &ccookie);
297 ATF_REQUIRE(cname != NULL);
298 ATF_REQUIRE(ctype == NV_TYPE_DESCRIPTOR);
299 ATF_REQUIRE(strcmp(cname, "nvlist/descriptor/pipe_rd") == 0);
300 ATF_REQUIRE(fd_is_valid(nvlist_get_descriptor(cnvl, cname)));
301
302 cname = nvlist_next(cnvl, &ctype, &ccookie);
303 ATF_REQUIRE(cname != NULL);
304 ATF_REQUIRE(ctype == NV_TYPE_BINARY);
305 ATF_REQUIRE(strcmp(cname, "nvlist/binary/x") == 0);
306 ATF_REQUIRE(memcmp(nvlist_get_binary(cnvl, cname, NULL), "x", 1) == 0);
307 ATF_REQUIRE(memcmp(nvlist_get_binary(cnvl, cname, &size), "x", 1) == 0);
308 ATF_REQUIRE(size == 1);
309
310 cname = nvlist_next(cnvl, &ctype, &ccookie);
311 ATF_REQUIRE(cname != NULL);
312 ATF_REQUIRE(ctype == NV_TYPE_BINARY);
313 ATF_REQUIRE(strcmp(cname, "nvlist/binary/" ALPHABET) == 0);
314 ATF_REQUIRE(memcmp(nvlist_get_binary(cnvl, cname, NULL), ALPHABET,
315 sizeof(ALPHABET)) == 0);
316 ATF_REQUIRE(memcmp(nvlist_get_binary(cnvl, cname, &size), ALPHABET,
317 sizeof(ALPHABET)) == 0);
318 ATF_REQUIRE(size == sizeof(ALPHABET));
319
320 cname = nvlist_next(cnvl, &ctype, &ccookie);
321 ATF_REQUIRE(cname != NULL);
322 ATF_REQUIRE(ctype == NV_TYPE_NVLIST);
323 ATF_REQUIRE(strcmp(cname, "nvlist/nvlist/empty") == 0);
324 empty = nvlist_get_nvlist(cnvl, cname);
325 ATF_REQUIRE(nvlist_empty(empty));
326
327 cname = nvlist_next(cnvl, &ctype, &ccookie);
328 ATF_REQUIRE(cname == NULL);
329
330 name = nvlist_next(nvl, &type, &cookie);
331 ATF_REQUIRE(name == NULL);
332
333 nvlist_destroy(nvl);
334 }
335
336 static void
nvlist_send_recv__send_nvlist(short sotype)337 nvlist_send_recv__send_nvlist(short sotype)
338 {
339 int socks[2], status;
340 pid_t pid;
341
342 ATF_REQUIRE(socketpair(PF_UNIX, sotype, 0, socks) == 0);
343
344 pid = fork();
345 ATF_REQUIRE(pid >= 0);
346 if (pid == 0) {
347 /* Child. */
348 (void)close(socks[0]);
349 send_nvlist_child(socks[1]);
350 _exit(0);
351 }
352
353 (void)close(socks[1]);
354 send_nvlist_parent(socks[0]);
355
356 ATF_REQUIRE(waitpid(pid, &status, 0) == pid);
357 ATF_REQUIRE(status == 0);
358 }
359
360 static void
nvlist_send_recv__send_closed_fd(short sotype)361 nvlist_send_recv__send_closed_fd(short sotype)
362 {
363 nvlist_t *nvl;
364 int socks[2];
365
366 ATF_REQUIRE(socketpair(PF_UNIX, sotype, 0, socks) == 0);
367
368 nvl = nvlist_create(0);
369 ATF_REQUIRE(nvl != NULL);
370 nvlist_add_descriptor(nvl, "fd", 12345);
371 ATF_REQUIRE(nvlist_error(nvl) == EBADF);
372
373 ATF_REQUIRE_ERRNO(EBADF, nvlist_send(socks[1], nvl) != 0);
374 }
375
376 static int
nopenfds(void)377 nopenfds(void)
378 {
379 size_t len;
380 int error, mib[4], n;
381
382 mib[0] = CTL_KERN;
383 mib[1] = KERN_PROC;
384 mib[2] = KERN_PROC_NFDS;
385 mib[3] = 0;
386
387 len = sizeof(n);
388 error = sysctl(mib, nitems(mib), &n, &len, NULL, 0);
389 if (error != 0)
390 return (-1);
391 return (n);
392 }
393
394 #define NFDS 512
395
396 static void
send_many_fds_child(int sock)397 send_many_fds_child(int sock)
398 {
399 char name[16];
400 nvlist_t *nvl;
401 int anfds, bnfds, fd, i, j;
402
403 fd = open(_PATH_DEVNULL, O_RDONLY);
404 ATF_REQUIRE(fd >= 0);
405
406 for (i = 1; i < NFDS; i++) {
407 nvl = nvlist_create(0);
408 bnfds = nopenfds();
409 if (bnfds == -1)
410 err(EXIT_FAILURE, "sysctl");
411
412 for (j = 0; j < i; j++) {
413 snprintf(name, sizeof(name), "fd%d", j);
414 nvlist_add_descriptor(nvl, name, fd);
415 }
416 nvlist_send(sock, nvl);
417 nvlist_destroy(nvl);
418
419 anfds = nopenfds();
420 if (anfds == -1)
421 err(EXIT_FAILURE, "sysctl");
422 if (anfds != bnfds)
423 errx(EXIT_FAILURE, "fd count mismatch");
424 }
425 }
426
427 static void
nvlist_send_recv__send_many_fds(short sotype)428 nvlist_send_recv__send_many_fds(short sotype)
429 {
430 char name[16];
431 nvlist_t *nvl;
432 int anfds, bnfds, fd, i, j, socks[2], status;
433 pid_t pid;
434
435 ATF_REQUIRE(socketpair(PF_UNIX, sotype, 0, socks) == 0);
436
437 pid = fork();
438 ATF_REQUIRE(pid >= 0);
439 if (pid == 0) {
440 /* Child. */
441 (void)close(socks[0]);
442 send_many_fds_child(socks[1]);
443 _exit(0);
444 }
445
446 (void)close(socks[1]);
447
448 for (i = 1; i < NFDS; i++) {
449 bnfds = nopenfds();
450 ATF_REQUIRE(bnfds != -1);
451
452 nvl = nvlist_recv(socks[0], 0);
453 ATF_REQUIRE(nvl != NULL);
454 for (j = 0; j < i; j++) {
455 snprintf(name, sizeof(name), "fd%d", j);
456 fd = nvlist_take_descriptor(nvl, name);
457 ATF_REQUIRE(close(fd) == 0);
458 }
459 nvlist_destroy(nvl);
460
461 anfds = nopenfds();
462 ATF_REQUIRE(anfds != -1);
463 ATF_REQUIRE(anfds == bnfds);
464 }
465
466 ATF_REQUIRE(waitpid(pid, &status, 0) == pid);
467 ATF_REQUIRE(status == 0);
468 }
469
470 /*
471 * This test needs to tune the following sysctl's:
472 * net.local.dgram.maxdgram
473 * net.local.dgram.recvspace
474 */
475 ATF_TC_WITHOUT_HEAD(nvlist_send_recv__send_many_fds__dgram);
ATF_TC_BODY(nvlist_send_recv__send_many_fds__dgram,tc)476 ATF_TC_BODY(nvlist_send_recv__send_many_fds__dgram, tc)
477 {
478 u_long maxdgram, recvspace, temp_maxdgram, temp_recvspace;
479 size_t len;
480 int error;
481
482 atf_tc_skip("https://bugs.freebsd.org/260891");
483
484 /* size of the largest datagram to send */
485 temp_maxdgram = 16772;
486 len = sizeof(maxdgram);
487 error = sysctlbyname("net.local.dgram.maxdgram", &maxdgram,
488 &len, &temp_maxdgram, sizeof(temp_maxdgram));
489 if (error != 0)
490 atf_tc_skip("cannot set net.local.dgram.maxdgram: %s", strerror(errno));
491
492 /*
493 * The receive queue fills up quicker than it's being emptied,
494 * bump it to a sufficiently large enough value, 1M.
495 */
496 temp_recvspace = 1048576;
497 len = sizeof(recvspace);
498 error = sysctlbyname("net.local.dgram.recvspace", &recvspace,
499 &len, &temp_recvspace, sizeof(temp_recvspace));
500 if (error != 0)
501 atf_tc_skip("cannot set net.local.dgram.recvspace: %s", strerror(errno));
502
503 nvlist_send_recv__send_many_fds(SOCK_DGRAM);
504
505 /* restore original values */
506 error = sysctlbyname("net.local.dgram.maxdgram", NULL, NULL, &maxdgram, sizeof(maxdgram));
507 if (error != 0)
508 warn("failed to restore net.local.dgram.maxdgram");
509
510 error = sysctlbyname("net.local.dgram.recvspace", NULL, NULL, &recvspace, sizeof(recvspace));
511 if (error != 0)
512 warn("failed to restore net.local.dgram.recvspace");
513 }
514
515 ATF_TC_WITHOUT_HEAD(nvlist_send_recv__send_many_fds__stream);
ATF_TC_BODY(nvlist_send_recv__send_many_fds__stream,tc)516 ATF_TC_BODY(nvlist_send_recv__send_many_fds__stream, tc)
517 {
518 nvlist_send_recv__send_many_fds(SOCK_STREAM);
519 }
520
521 ATF_TC_WITHOUT_HEAD(nvlist_send_recv__send_nvlist__dgram);
ATF_TC_BODY(nvlist_send_recv__send_nvlist__dgram,tc)522 ATF_TC_BODY(nvlist_send_recv__send_nvlist__dgram, tc)
523 {
524 nvlist_send_recv__send_nvlist(SOCK_DGRAM);
525 }
526
527 ATF_TC_WITHOUT_HEAD(nvlist_send_recv__send_nvlist__stream);
ATF_TC_BODY(nvlist_send_recv__send_nvlist__stream,tc)528 ATF_TC_BODY(nvlist_send_recv__send_nvlist__stream, tc)
529 {
530 nvlist_send_recv__send_nvlist(SOCK_STREAM);
531 }
532
533 ATF_TC_WITHOUT_HEAD(nvlist_send_recv__send_closed_fd__dgram);
ATF_TC_BODY(nvlist_send_recv__send_closed_fd__dgram,tc)534 ATF_TC_BODY(nvlist_send_recv__send_closed_fd__dgram, tc)
535 {
536 nvlist_send_recv__send_closed_fd(SOCK_DGRAM);
537 }
538
539 ATF_TC_WITHOUT_HEAD(nvlist_send_recv__send_closed_fd__stream);
ATF_TC_BODY(nvlist_send_recv__send_closed_fd__stream,tc)540 ATF_TC_BODY(nvlist_send_recv__send_closed_fd__stream, tc)
541 {
542 nvlist_send_recv__send_closed_fd(SOCK_STREAM);
543 }
544
ATF_TP_ADD_TCS(tp)545 ATF_TP_ADD_TCS(tp)
546 {
547
548 ATF_TP_ADD_TC(tp, nvlist_send_recv__send_nvlist__dgram);
549 ATF_TP_ADD_TC(tp, nvlist_send_recv__send_nvlist__stream);
550 ATF_TP_ADD_TC(tp, nvlist_send_recv__send_closed_fd__dgram);
551 ATF_TP_ADD_TC(tp, nvlist_send_recv__send_closed_fd__stream);
552 ATF_TP_ADD_TC(tp, nvlist_send_recv__send_many_fds__dgram);
553 ATF_TP_ADD_TC(tp, nvlist_send_recv__send_many_fds__stream);
554
555 return (atf_no_error());
556 }
557