1b236bcf1SEnji Cooper /*-
2b236bcf1SEnji Cooper * Copyright (c) 2013 The FreeBSD Foundation
3b236bcf1SEnji Cooper *
4b236bcf1SEnji Cooper * This software was developed by Pawel Jakub Dawidek under sponsorship from
5b236bcf1SEnji Cooper * the FreeBSD Foundation.
6b236bcf1SEnji Cooper *
7b236bcf1SEnji Cooper * Redistribution and use in source and binary forms, with or without
8b236bcf1SEnji Cooper * modification, are permitted provided that the following conditions
9b236bcf1SEnji Cooper * are met:
10b236bcf1SEnji Cooper * 1. Redistributions of source code must retain the above copyright
11b236bcf1SEnji Cooper * notice, this list of conditions and the following disclaimer.
12b236bcf1SEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright
13b236bcf1SEnji Cooper * notice, this list of conditions and the following disclaimer in the
14b236bcf1SEnji Cooper * documentation and/or other materials provided with the distribution.
15b236bcf1SEnji Cooper *
16b236bcf1SEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
17b236bcf1SEnji Cooper * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18b236bcf1SEnji Cooper * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19b236bcf1SEnji Cooper * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
20b236bcf1SEnji Cooper * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21b236bcf1SEnji Cooper * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22b236bcf1SEnji Cooper * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23b236bcf1SEnji Cooper * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24b236bcf1SEnji Cooper * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25b236bcf1SEnji Cooper * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26b236bcf1SEnji Cooper * SUCH DAMAGE.
27b236bcf1SEnji Cooper */
28b236bcf1SEnji Cooper
29dd8bacfdSMark Johnston #include <sys/param.h>
30b236bcf1SEnji Cooper #include <sys/socket.h>
31dd8bacfdSMark Johnston #include <sys/sysctl.h>
32b236bcf1SEnji Cooper #include <sys/wait.h>
33c36e54bbSMariusz Zaborski #include <sys/nv.h>
34b236bcf1SEnji Cooper
35908d1eefSMariusz Zaborski #include <stdlib.h>
36b236bcf1SEnji Cooper #include <err.h>
37b236bcf1SEnji Cooper #include <errno.h>
38b236bcf1SEnji Cooper #include <fcntl.h>
39dd8bacfdSMark Johnston #include <paths.h>
40b236bcf1SEnji Cooper #include <stdio.h>
41b236bcf1SEnji Cooper #include <string.h>
42b236bcf1SEnji Cooper #include <unistd.h>
43b236bcf1SEnji Cooper
44ccf7f846SMark Johnston #include <atf-c.h>
45b236bcf1SEnji Cooper
46*241a7dddSMariusz Zaborski #include <nv_impl.h>
47*241a7dddSMariusz Zaborski #include <msgio.h>
48*241a7dddSMariusz Zaborski
49ccf7f846SMark Johnston #define ALPHABET "abcdefghijklmnopqrstuvwxyz"
50b236bcf1SEnji Cooper #define fd_is_valid(fd) (fcntl((fd), F_GETFL) != -1 || errno != EBADF)
51b236bcf1SEnji Cooper
52b236bcf1SEnji Cooper static void
send_nvlist_child(int sock)53ccf7f846SMark Johnston send_nvlist_child(int sock)
54b236bcf1SEnji Cooper {
55b236bcf1SEnji Cooper nvlist_t *nvl;
562dfd9979SRyan Stone nvlist_t *empty;
57908d1eefSMariusz Zaborski int pfd[2];
58b236bcf1SEnji Cooper
59b236bcf1SEnji Cooper nvl = nvlist_create(0);
602dfd9979SRyan Stone empty = nvlist_create(0);
61b236bcf1SEnji Cooper
62b236bcf1SEnji Cooper nvlist_add_bool(nvl, "nvlist/bool/true", true);
63b236bcf1SEnji Cooper nvlist_add_bool(nvl, "nvlist/bool/false", false);
64b236bcf1SEnji Cooper nvlist_add_number(nvl, "nvlist/number/0", 0);
65b236bcf1SEnji Cooper nvlist_add_number(nvl, "nvlist/number/1", 1);
66b236bcf1SEnji Cooper nvlist_add_number(nvl, "nvlist/number/-1", -1);
67b236bcf1SEnji Cooper nvlist_add_number(nvl, "nvlist/number/UINT64_MAX", UINT64_MAX);
68b236bcf1SEnji Cooper nvlist_add_number(nvl, "nvlist/number/INT64_MIN", INT64_MIN);
69b236bcf1SEnji Cooper nvlist_add_number(nvl, "nvlist/number/INT64_MAX", INT64_MAX);
70b236bcf1SEnji Cooper nvlist_add_string(nvl, "nvlist/string/", "");
71b236bcf1SEnji Cooper nvlist_add_string(nvl, "nvlist/string/x", "x");
72ccf7f846SMark Johnston nvlist_add_string(nvl, "nvlist/string/" ALPHABET, ALPHABET);
73908d1eefSMariusz Zaborski
74ccf7f846SMark Johnston nvlist_add_descriptor(nvl, "nvlist/descriptor/STDERR_FILENO",
75ccf7f846SMark Johnston STDERR_FILENO);
76908d1eefSMariusz Zaborski if (pipe(pfd) == -1)
77908d1eefSMariusz Zaborski err(EXIT_FAILURE, "pipe");
78908d1eefSMariusz Zaborski if (write(pfd[1], "test", 4) != 4)
79908d1eefSMariusz Zaborski err(EXIT_FAILURE, "write");
80908d1eefSMariusz Zaborski close(pfd[1]);
81908d1eefSMariusz Zaborski nvlist_add_descriptor(nvl, "nvlist/descriptor/pipe_rd", pfd[0]);
82908d1eefSMariusz Zaborski close(pfd[0]);
83908d1eefSMariusz Zaborski
84b236bcf1SEnji Cooper nvlist_add_binary(nvl, "nvlist/binary/x", "x", 1);
85ccf7f846SMark Johnston nvlist_add_binary(nvl, "nvlist/binary/" ALPHABET, ALPHABET,
86ccf7f846SMark Johnston sizeof(ALPHABET));
872dfd9979SRyan Stone nvlist_move_nvlist(nvl, "nvlist/nvlist/empty", empty);
88b236bcf1SEnji Cooper nvlist_add_nvlist(nvl, "nvlist/nvlist", nvl);
89b236bcf1SEnji Cooper
90b236bcf1SEnji Cooper nvlist_send(sock, nvl);
91b236bcf1SEnji Cooper
92b236bcf1SEnji Cooper nvlist_destroy(nvl);
93b236bcf1SEnji Cooper }
94b236bcf1SEnji Cooper
95b236bcf1SEnji Cooper static void
send_nvlist_parent(int sock)96ccf7f846SMark Johnston send_nvlist_parent(int sock)
97b236bcf1SEnji Cooper {
98b236bcf1SEnji Cooper nvlist_t *nvl;
992dfd9979SRyan Stone const nvlist_t *cnvl, *empty;
100b236bcf1SEnji Cooper const char *name, *cname;
101b236bcf1SEnji Cooper void *cookie, *ccookie;
102908d1eefSMariusz Zaborski int type, ctype, fd;
103b236bcf1SEnji Cooper size_t size;
104908d1eefSMariusz Zaborski char buf[4];
105b236bcf1SEnji Cooper
106bd1da0a0SMariusz Zaborski nvl = nvlist_recv(sock, 0);
107ccf7f846SMark Johnston ATF_REQUIRE(nvlist_error(nvl) == 0);
108b236bcf1SEnji Cooper if (nvlist_error(nvl) != 0)
109b236bcf1SEnji Cooper err(1, "nvlist_recv() failed");
110b236bcf1SEnji Cooper
111b236bcf1SEnji Cooper cookie = NULL;
112b236bcf1SEnji Cooper
113b236bcf1SEnji Cooper name = nvlist_next(nvl, &type, &cookie);
114ccf7f846SMark Johnston ATF_REQUIRE(name != NULL);
115ccf7f846SMark Johnston ATF_REQUIRE(type == NV_TYPE_BOOL);
116ccf7f846SMark Johnston ATF_REQUIRE(strcmp(name, "nvlist/bool/true") == 0);
117ccf7f846SMark Johnston ATF_REQUIRE(nvlist_get_bool(nvl, name) == true);
118b236bcf1SEnji Cooper
119b236bcf1SEnji Cooper name = nvlist_next(nvl, &type, &cookie);
120ccf7f846SMark Johnston ATF_REQUIRE(name != NULL);
121ccf7f846SMark Johnston ATF_REQUIRE(type == NV_TYPE_BOOL);
122ccf7f846SMark Johnston ATF_REQUIRE(strcmp(name, "nvlist/bool/false") == 0);
123ccf7f846SMark Johnston ATF_REQUIRE(nvlist_get_bool(nvl, name) == false);
124b236bcf1SEnji Cooper
125b236bcf1SEnji Cooper name = nvlist_next(nvl, &type, &cookie);
126ccf7f846SMark Johnston ATF_REQUIRE(name != NULL);
127ccf7f846SMark Johnston ATF_REQUIRE(type == NV_TYPE_NUMBER);
128ccf7f846SMark Johnston ATF_REQUIRE(strcmp(name, "nvlist/number/0") == 0);
129ccf7f846SMark Johnston ATF_REQUIRE(nvlist_get_number(nvl, name) == 0);
130b236bcf1SEnji Cooper
131b236bcf1SEnji Cooper name = nvlist_next(nvl, &type, &cookie);
132ccf7f846SMark Johnston ATF_REQUIRE(name != NULL);
133ccf7f846SMark Johnston ATF_REQUIRE(type == NV_TYPE_NUMBER);
134ccf7f846SMark Johnston ATF_REQUIRE(strcmp(name, "nvlist/number/1") == 0);
135ccf7f846SMark Johnston ATF_REQUIRE(nvlist_get_number(nvl, name) == 1);
136b236bcf1SEnji Cooper
137b236bcf1SEnji Cooper name = nvlist_next(nvl, &type, &cookie);
138ccf7f846SMark Johnston ATF_REQUIRE(name != NULL);
139ccf7f846SMark Johnston ATF_REQUIRE(type == NV_TYPE_NUMBER);
140ccf7f846SMark Johnston ATF_REQUIRE(strcmp(name, "nvlist/number/-1") == 0);
141ccf7f846SMark Johnston ATF_REQUIRE((int)nvlist_get_number(nvl, name) == -1);
142b236bcf1SEnji Cooper
143b236bcf1SEnji Cooper name = nvlist_next(nvl, &type, &cookie);
144ccf7f846SMark Johnston ATF_REQUIRE(name != NULL);
145ccf7f846SMark Johnston ATF_REQUIRE(type == NV_TYPE_NUMBER);
146ccf7f846SMark Johnston ATF_REQUIRE(strcmp(name, "nvlist/number/UINT64_MAX") == 0);
147ccf7f846SMark Johnston ATF_REQUIRE(nvlist_get_number(nvl, name) == UINT64_MAX);
148b236bcf1SEnji Cooper
149b236bcf1SEnji Cooper name = nvlist_next(nvl, &type, &cookie);
150ccf7f846SMark Johnston ATF_REQUIRE(name != NULL);
151ccf7f846SMark Johnston ATF_REQUIRE(type == NV_TYPE_NUMBER);
152ccf7f846SMark Johnston ATF_REQUIRE(strcmp(name, "nvlist/number/INT64_MIN") == 0);
153ccf7f846SMark Johnston ATF_REQUIRE((int64_t)nvlist_get_number(nvl, name) == INT64_MIN);
154b236bcf1SEnji Cooper
155b236bcf1SEnji Cooper name = nvlist_next(nvl, &type, &cookie);
156ccf7f846SMark Johnston ATF_REQUIRE(name != NULL);
157ccf7f846SMark Johnston ATF_REQUIRE(type == NV_TYPE_NUMBER);
158ccf7f846SMark Johnston ATF_REQUIRE(strcmp(name, "nvlist/number/INT64_MAX") == 0);
159ccf7f846SMark Johnston ATF_REQUIRE((int64_t)nvlist_get_number(nvl, name) == INT64_MAX);
160b236bcf1SEnji Cooper
161b236bcf1SEnji Cooper name = nvlist_next(nvl, &type, &cookie);
162ccf7f846SMark Johnston ATF_REQUIRE(name != NULL);
163ccf7f846SMark Johnston ATF_REQUIRE(type == NV_TYPE_STRING);
164ccf7f846SMark Johnston ATF_REQUIRE(strcmp(name, "nvlist/string/") == 0);
165ccf7f846SMark Johnston ATF_REQUIRE(strcmp(nvlist_get_string(nvl, name), "") == 0);
166b236bcf1SEnji Cooper
167b236bcf1SEnji Cooper name = nvlist_next(nvl, &type, &cookie);
168ccf7f846SMark Johnston ATF_REQUIRE(name != NULL);
169ccf7f846SMark Johnston ATF_REQUIRE(type == NV_TYPE_STRING);
170ccf7f846SMark Johnston ATF_REQUIRE(strcmp(name, "nvlist/string/x") == 0);
171ccf7f846SMark Johnston ATF_REQUIRE(strcmp(nvlist_get_string(nvl, name), "x") == 0);
172b236bcf1SEnji Cooper
173b236bcf1SEnji Cooper name = nvlist_next(nvl, &type, &cookie);
174ccf7f846SMark Johnston ATF_REQUIRE(name != NULL);
175ccf7f846SMark Johnston ATF_REQUIRE(type == NV_TYPE_STRING);
176ccf7f846SMark Johnston ATF_REQUIRE(strcmp(name, "nvlist/string/" ALPHABET) == 0);
177ccf7f846SMark Johnston ATF_REQUIRE(strcmp(nvlist_get_string(nvl, name), ALPHABET) == 0);
178b236bcf1SEnji Cooper
179b236bcf1SEnji Cooper name = nvlist_next(nvl, &type, &cookie);
180ccf7f846SMark Johnston ATF_REQUIRE(name != NULL);
181ccf7f846SMark Johnston ATF_REQUIRE(type == NV_TYPE_DESCRIPTOR);
182ccf7f846SMark Johnston ATF_REQUIRE(strcmp(name, "nvlist/descriptor/STDERR_FILENO") == 0);
183ccf7f846SMark Johnston ATF_REQUIRE(fd_is_valid(nvlist_get_descriptor(nvl, name)));
184b236bcf1SEnji Cooper
185b236bcf1SEnji Cooper name = nvlist_next(nvl, &type, &cookie);
186ccf7f846SMark Johnston ATF_REQUIRE(name != NULL);
187ccf7f846SMark Johnston ATF_REQUIRE(type == NV_TYPE_DESCRIPTOR);
188ccf7f846SMark Johnston ATF_REQUIRE(strcmp(name, "nvlist/descriptor/pipe_rd") == 0);
189908d1eefSMariusz Zaborski fd = nvlist_get_descriptor(nvl, name);
190ccf7f846SMark Johnston ATF_REQUIRE(fd_is_valid(fd));
191ccf7f846SMark Johnston ATF_REQUIRE(read(fd, buf, sizeof(buf)) == 4);
192ccf7f846SMark Johnston ATF_REQUIRE(strncmp(buf, "test", sizeof(buf)) == 0);
193908d1eefSMariusz Zaborski
194908d1eefSMariusz Zaborski name = nvlist_next(nvl, &type, &cookie);
195ccf7f846SMark Johnston ATF_REQUIRE(name != NULL);
196ccf7f846SMark Johnston ATF_REQUIRE(type == NV_TYPE_BINARY);
197ccf7f846SMark Johnston ATF_REQUIRE(strcmp(name, "nvlist/binary/x") == 0);
198ccf7f846SMark Johnston ATF_REQUIRE(memcmp(nvlist_get_binary(nvl, name, NULL), "x", 1) == 0);
199ccf7f846SMark Johnston ATF_REQUIRE(memcmp(nvlist_get_binary(nvl, name, &size), "x", 1) == 0);
200ccf7f846SMark Johnston ATF_REQUIRE(size == 1);
201b236bcf1SEnji Cooper
202b236bcf1SEnji Cooper name = nvlist_next(nvl, &type, &cookie);
203ccf7f846SMark Johnston ATF_REQUIRE(name != NULL);
204ccf7f846SMark Johnston ATF_REQUIRE(type == NV_TYPE_BINARY);
205ccf7f846SMark Johnston ATF_REQUIRE(strcmp(name, "nvlist/binary/" ALPHABET) == 0);
206ccf7f846SMark Johnston ATF_REQUIRE(memcmp(nvlist_get_binary(nvl, name, NULL), ALPHABET,
207ccf7f846SMark Johnston sizeof(ALPHABET)) == 0);
208ccf7f846SMark Johnston ATF_REQUIRE(memcmp(nvlist_get_binary(nvl, name, &size), ALPHABET,
209ccf7f846SMark Johnston sizeof(ALPHABET)) == 0);
210ccf7f846SMark Johnston ATF_REQUIRE(size == sizeof(ALPHABET));
211b236bcf1SEnji Cooper
212b236bcf1SEnji Cooper name = nvlist_next(nvl, &type, &cookie);
213ccf7f846SMark Johnston ATF_REQUIRE(name != NULL);
214ccf7f846SMark Johnston ATF_REQUIRE(type == NV_TYPE_NVLIST);
215ccf7f846SMark Johnston ATF_REQUIRE(strcmp(name, "nvlist/nvlist/empty") == 0);
2162dfd9979SRyan Stone cnvl = nvlist_get_nvlist(nvl, name);
217ccf7f846SMark Johnston ATF_REQUIRE(nvlist_empty(cnvl));
2182dfd9979SRyan Stone
2192dfd9979SRyan Stone name = nvlist_next(nvl, &type, &cookie);
220ccf7f846SMark Johnston ATF_REQUIRE(name != NULL);
221ccf7f846SMark Johnston ATF_REQUIRE(type == NV_TYPE_NVLIST);
222ccf7f846SMark Johnston ATF_REQUIRE(strcmp(name, "nvlist/nvlist") == 0);
223b236bcf1SEnji Cooper cnvl = nvlist_get_nvlist(nvl, name);
224b236bcf1SEnji Cooper
225b236bcf1SEnji Cooper ccookie = NULL;
226b236bcf1SEnji Cooper
227b236bcf1SEnji Cooper cname = nvlist_next(cnvl, &ctype, &ccookie);
228ccf7f846SMark Johnston ATF_REQUIRE(cname != NULL);
229ccf7f846SMark Johnston ATF_REQUIRE(ctype == NV_TYPE_BOOL);
230ccf7f846SMark Johnston ATF_REQUIRE(strcmp(cname, "nvlist/bool/true") == 0);
231ccf7f846SMark Johnston ATF_REQUIRE(nvlist_get_bool(cnvl, cname) == true);
232b236bcf1SEnji Cooper
233b236bcf1SEnji Cooper cname = nvlist_next(cnvl, &ctype, &ccookie);
234ccf7f846SMark Johnston ATF_REQUIRE(cname != NULL);
235ccf7f846SMark Johnston ATF_REQUIRE(ctype == NV_TYPE_BOOL);
236ccf7f846SMark Johnston ATF_REQUIRE(strcmp(cname, "nvlist/bool/false") == 0);
237ccf7f846SMark Johnston ATF_REQUIRE(nvlist_get_bool(cnvl, cname) == false);
238b236bcf1SEnji Cooper
239b236bcf1SEnji Cooper cname = nvlist_next(cnvl, &ctype, &ccookie);
240ccf7f846SMark Johnston ATF_REQUIRE(cname != NULL);
241ccf7f846SMark Johnston ATF_REQUIRE(ctype == NV_TYPE_NUMBER);
242ccf7f846SMark Johnston ATF_REQUIRE(strcmp(cname, "nvlist/number/0") == 0);
243ccf7f846SMark Johnston ATF_REQUIRE(nvlist_get_number(cnvl, cname) == 0);
244b236bcf1SEnji Cooper
245b236bcf1SEnji Cooper cname = nvlist_next(cnvl, &ctype, &ccookie);
246ccf7f846SMark Johnston ATF_REQUIRE(cname != NULL);
247ccf7f846SMark Johnston ATF_REQUIRE(ctype == NV_TYPE_NUMBER);
248ccf7f846SMark Johnston ATF_REQUIRE(strcmp(cname, "nvlist/number/1") == 0);
249ccf7f846SMark Johnston ATF_REQUIRE(nvlist_get_number(cnvl, cname) == 1);
250b236bcf1SEnji Cooper
251b236bcf1SEnji Cooper cname = nvlist_next(cnvl, &ctype, &ccookie);
252ccf7f846SMark Johnston ATF_REQUIRE(cname != NULL);
253ccf7f846SMark Johnston ATF_REQUIRE(ctype == NV_TYPE_NUMBER);
254ccf7f846SMark Johnston ATF_REQUIRE(strcmp(cname, "nvlist/number/-1") == 0);
255ccf7f846SMark Johnston ATF_REQUIRE((int)nvlist_get_number(cnvl, cname) == -1);
256b236bcf1SEnji Cooper
257b236bcf1SEnji Cooper cname = nvlist_next(cnvl, &ctype, &ccookie);
258ccf7f846SMark Johnston ATF_REQUIRE(cname != NULL);
259ccf7f846SMark Johnston ATF_REQUIRE(ctype == NV_TYPE_NUMBER);
260ccf7f846SMark Johnston ATF_REQUIRE(strcmp(cname, "nvlist/number/UINT64_MAX") == 0);
261ccf7f846SMark Johnston ATF_REQUIRE(nvlist_get_number(cnvl, cname) == UINT64_MAX);
262b236bcf1SEnji Cooper
263b236bcf1SEnji Cooper cname = nvlist_next(cnvl, &ctype, &ccookie);
264ccf7f846SMark Johnston ATF_REQUIRE(cname != NULL);
265ccf7f846SMark Johnston ATF_REQUIRE(ctype == NV_TYPE_NUMBER);
266ccf7f846SMark Johnston ATF_REQUIRE(strcmp(cname, "nvlist/number/INT64_MIN") == 0);
267ccf7f846SMark Johnston ATF_REQUIRE((int64_t)nvlist_get_number(cnvl, cname) == INT64_MIN);
268b236bcf1SEnji Cooper
269b236bcf1SEnji Cooper cname = nvlist_next(cnvl, &ctype, &ccookie);
270ccf7f846SMark Johnston ATF_REQUIRE(cname != NULL);
271ccf7f846SMark Johnston ATF_REQUIRE(ctype == NV_TYPE_NUMBER);
272ccf7f846SMark Johnston ATF_REQUIRE(strcmp(cname, "nvlist/number/INT64_MAX") == 0);
273ccf7f846SMark Johnston ATF_REQUIRE((int64_t)nvlist_get_number(cnvl, cname) == INT64_MAX);
274b236bcf1SEnji Cooper
275b236bcf1SEnji Cooper cname = nvlist_next(cnvl, &ctype, &ccookie);
276ccf7f846SMark Johnston ATF_REQUIRE(cname != NULL);
277ccf7f846SMark Johnston ATF_REQUIRE(ctype == NV_TYPE_STRING);
278ccf7f846SMark Johnston ATF_REQUIRE(strcmp(cname, "nvlist/string/") == 0);
279ccf7f846SMark Johnston ATF_REQUIRE(strcmp(nvlist_get_string(cnvl, cname), "") == 0);
280b236bcf1SEnji Cooper
281b236bcf1SEnji Cooper cname = nvlist_next(cnvl, &ctype, &ccookie);
282ccf7f846SMark Johnston ATF_REQUIRE(cname != NULL);
283ccf7f846SMark Johnston ATF_REQUIRE(ctype == NV_TYPE_STRING);
284ccf7f846SMark Johnston ATF_REQUIRE(strcmp(cname, "nvlist/string/x") == 0);
285ccf7f846SMark Johnston ATF_REQUIRE(strcmp(nvlist_get_string(cnvl, cname), "x") == 0);
286b236bcf1SEnji Cooper
287b236bcf1SEnji Cooper cname = nvlist_next(cnvl, &ctype, &ccookie);
288ccf7f846SMark Johnston ATF_REQUIRE(cname != NULL);
289ccf7f846SMark Johnston ATF_REQUIRE(ctype == NV_TYPE_STRING);
290ccf7f846SMark Johnston ATF_REQUIRE(strcmp(cname, "nvlist/string/" ALPHABET) == 0);
291ccf7f846SMark Johnston ATF_REQUIRE(strcmp(nvlist_get_string(cnvl, cname), ALPHABET) == 0);
292b236bcf1SEnji Cooper
293b236bcf1SEnji Cooper cname = nvlist_next(cnvl, &ctype, &ccookie);
294ccf7f846SMark Johnston ATF_REQUIRE(cname != NULL);
295ccf7f846SMark Johnston ATF_REQUIRE(ctype == NV_TYPE_DESCRIPTOR);
296ccf7f846SMark Johnston ATF_REQUIRE(strcmp(cname, "nvlist/descriptor/STDERR_FILENO") == 0);
297ccf7f846SMark Johnston ATF_REQUIRE(fd_is_valid(nvlist_get_descriptor(cnvl, cname)));
298b236bcf1SEnji Cooper
299b236bcf1SEnji Cooper cname = nvlist_next(cnvl, &ctype, &ccookie);
300ccf7f846SMark Johnston ATF_REQUIRE(cname != NULL);
301ccf7f846SMark Johnston ATF_REQUIRE(ctype == NV_TYPE_DESCRIPTOR);
302ccf7f846SMark Johnston ATF_REQUIRE(strcmp(cname, "nvlist/descriptor/pipe_rd") == 0);
303ccf7f846SMark Johnston ATF_REQUIRE(fd_is_valid(nvlist_get_descriptor(cnvl, cname)));
304908d1eefSMariusz Zaborski
305908d1eefSMariusz Zaborski cname = nvlist_next(cnvl, &ctype, &ccookie);
306ccf7f846SMark Johnston ATF_REQUIRE(cname != NULL);
307ccf7f846SMark Johnston ATF_REQUIRE(ctype == NV_TYPE_BINARY);
308ccf7f846SMark Johnston ATF_REQUIRE(strcmp(cname, "nvlist/binary/x") == 0);
309ccf7f846SMark Johnston ATF_REQUIRE(memcmp(nvlist_get_binary(cnvl, cname, NULL), "x", 1) == 0);
310ccf7f846SMark Johnston ATF_REQUIRE(memcmp(nvlist_get_binary(cnvl, cname, &size), "x", 1) == 0);
311ccf7f846SMark Johnston ATF_REQUIRE(size == 1);
312b236bcf1SEnji Cooper
313b236bcf1SEnji Cooper cname = nvlist_next(cnvl, &ctype, &ccookie);
314ccf7f846SMark Johnston ATF_REQUIRE(cname != NULL);
315ccf7f846SMark Johnston ATF_REQUIRE(ctype == NV_TYPE_BINARY);
316ccf7f846SMark Johnston ATF_REQUIRE(strcmp(cname, "nvlist/binary/" ALPHABET) == 0);
317ccf7f846SMark Johnston ATF_REQUIRE(memcmp(nvlist_get_binary(cnvl, cname, NULL), ALPHABET,
318ccf7f846SMark Johnston sizeof(ALPHABET)) == 0);
319ccf7f846SMark Johnston ATF_REQUIRE(memcmp(nvlist_get_binary(cnvl, cname, &size), ALPHABET,
320ccf7f846SMark Johnston sizeof(ALPHABET)) == 0);
321ccf7f846SMark Johnston ATF_REQUIRE(size == sizeof(ALPHABET));
322b236bcf1SEnji Cooper
323b236bcf1SEnji Cooper cname = nvlist_next(cnvl, &ctype, &ccookie);
324ccf7f846SMark Johnston ATF_REQUIRE(cname != NULL);
325ccf7f846SMark Johnston ATF_REQUIRE(ctype == NV_TYPE_NVLIST);
326ccf7f846SMark Johnston ATF_REQUIRE(strcmp(cname, "nvlist/nvlist/empty") == 0);
3272dfd9979SRyan Stone empty = nvlist_get_nvlist(cnvl, cname);
328ccf7f846SMark Johnston ATF_REQUIRE(nvlist_empty(empty));
3292dfd9979SRyan Stone
3302dfd9979SRyan Stone cname = nvlist_next(cnvl, &ctype, &ccookie);
331ccf7f846SMark Johnston ATF_REQUIRE(cname == NULL);
332b236bcf1SEnji Cooper
333b236bcf1SEnji Cooper name = nvlist_next(nvl, &type, &cookie);
334ccf7f846SMark Johnston ATF_REQUIRE(name == NULL);
335b5d787d9SMariusz Zaborski
336b5d787d9SMariusz Zaborski nvlist_destroy(nvl);
337b236bcf1SEnji Cooper }
338b236bcf1SEnji Cooper
3395916ae1fSRobert Wing static void
nvlist_send_recv__send_nvlist(short sotype)3405916ae1fSRobert Wing nvlist_send_recv__send_nvlist(short sotype)
341b236bcf1SEnji Cooper {
342ccf7f846SMark Johnston int socks[2], status;
343b236bcf1SEnji Cooper pid_t pid;
344b236bcf1SEnji Cooper
3455916ae1fSRobert Wing ATF_REQUIRE(socketpair(PF_UNIX, sotype, 0, socks) == 0);
346ccf7f846SMark Johnston
347b236bcf1SEnji Cooper pid = fork();
348ccf7f846SMark Johnston ATF_REQUIRE(pid >= 0);
349ccf7f846SMark Johnston if (pid == 0) {
350b236bcf1SEnji Cooper /* Child. */
351ccf7f846SMark Johnston (void)close(socks[0]);
352ccf7f846SMark Johnston send_nvlist_child(socks[1]);
353991666adSMark Johnston _exit(0);
354b236bcf1SEnji Cooper }
355b236bcf1SEnji Cooper
356ccf7f846SMark Johnston (void)close(socks[1]);
357ccf7f846SMark Johnston send_nvlist_parent(socks[0]);
358ccf7f846SMark Johnston
359ccf7f846SMark Johnston ATF_REQUIRE(waitpid(pid, &status, 0) == pid);
360ccf7f846SMark Johnston ATF_REQUIRE(status == 0);
361991666adSMark Johnston }
362991666adSMark Johnston
3635916ae1fSRobert Wing static void
nvlist_send_recv__send_closed_fd(short sotype)3645916ae1fSRobert Wing nvlist_send_recv__send_closed_fd(short sotype)
365991666adSMark Johnston {
366991666adSMark Johnston nvlist_t *nvl;
367ccf7f846SMark Johnston int socks[2];
368991666adSMark Johnston
3695916ae1fSRobert Wing ATF_REQUIRE(socketpair(PF_UNIX, sotype, 0, socks) == 0);
370991666adSMark Johnston
371991666adSMark Johnston nvl = nvlist_create(0);
372ccf7f846SMark Johnston ATF_REQUIRE(nvl != NULL);
373991666adSMark Johnston nvlist_add_descriptor(nvl, "fd", 12345);
374ccf7f846SMark Johnston ATF_REQUIRE(nvlist_error(nvl) == EBADF);
375991666adSMark Johnston
376ccf7f846SMark Johnston ATF_REQUIRE_ERRNO(EBADF, nvlist_send(socks[1], nvl) != 0);
377991666adSMark Johnston }
378991666adSMark Johnston
379dd8bacfdSMark Johnston static int
nopenfds(void)380dd8bacfdSMark Johnston nopenfds(void)
381dd8bacfdSMark Johnston {
382dd8bacfdSMark Johnston size_t len;
383dd8bacfdSMark Johnston int error, mib[4], n;
384dd8bacfdSMark Johnston
385dd8bacfdSMark Johnston mib[0] = CTL_KERN;
386dd8bacfdSMark Johnston mib[1] = KERN_PROC;
387dd8bacfdSMark Johnston mib[2] = KERN_PROC_NFDS;
388dd8bacfdSMark Johnston mib[3] = 0;
389dd8bacfdSMark Johnston
390dd8bacfdSMark Johnston len = sizeof(n);
391dd8bacfdSMark Johnston error = sysctl(mib, nitems(mib), &n, &len, NULL, 0);
392dd8bacfdSMark Johnston if (error != 0)
393dd8bacfdSMark Johnston return (-1);
394dd8bacfdSMark Johnston return (n);
395dd8bacfdSMark Johnston }
396dd8bacfdSMark Johnston
397dd8bacfdSMark Johnston #define NFDS 512
398dd8bacfdSMark Johnston
399dd8bacfdSMark Johnston static void
send_many_fds_child(int sock)400dd8bacfdSMark Johnston send_many_fds_child(int sock)
401dd8bacfdSMark Johnston {
402dd8bacfdSMark Johnston char name[16];
403dd8bacfdSMark Johnston nvlist_t *nvl;
404dd8bacfdSMark Johnston int anfds, bnfds, fd, i, j;
405dd8bacfdSMark Johnston
406dd8bacfdSMark Johnston fd = open(_PATH_DEVNULL, O_RDONLY);
407dd8bacfdSMark Johnston ATF_REQUIRE(fd >= 0);
408dd8bacfdSMark Johnston
409dd8bacfdSMark Johnston for (i = 1; i < NFDS; i++) {
410dd8bacfdSMark Johnston nvl = nvlist_create(0);
411dd8bacfdSMark Johnston bnfds = nopenfds();
412dd8bacfdSMark Johnston if (bnfds == -1)
413dd8bacfdSMark Johnston err(EXIT_FAILURE, "sysctl");
414dd8bacfdSMark Johnston
415dd8bacfdSMark Johnston for (j = 0; j < i; j++) {
416dd8bacfdSMark Johnston snprintf(name, sizeof(name), "fd%d", j);
417dd8bacfdSMark Johnston nvlist_add_descriptor(nvl, name, fd);
418dd8bacfdSMark Johnston }
419dd8bacfdSMark Johnston nvlist_send(sock, nvl);
420dd8bacfdSMark Johnston nvlist_destroy(nvl);
421dd8bacfdSMark Johnston
422dd8bacfdSMark Johnston anfds = nopenfds();
423dd8bacfdSMark Johnston if (anfds == -1)
424dd8bacfdSMark Johnston err(EXIT_FAILURE, "sysctl");
425dd8bacfdSMark Johnston if (anfds != bnfds)
426dd8bacfdSMark Johnston errx(EXIT_FAILURE, "fd count mismatch");
427dd8bacfdSMark Johnston }
428dd8bacfdSMark Johnston }
429dd8bacfdSMark Johnston
4305916ae1fSRobert Wing static void
nvlist_send_recv__send_many_fds(short sotype)4315916ae1fSRobert Wing nvlist_send_recv__send_many_fds(short sotype)
432dd8bacfdSMark Johnston {
433dd8bacfdSMark Johnston char name[16];
434dd8bacfdSMark Johnston nvlist_t *nvl;
435dd8bacfdSMark Johnston int anfds, bnfds, fd, i, j, socks[2], status;
436dd8bacfdSMark Johnston pid_t pid;
437dd8bacfdSMark Johnston
4385916ae1fSRobert Wing ATF_REQUIRE(socketpair(PF_UNIX, sotype, 0, socks) == 0);
439dd8bacfdSMark Johnston
440dd8bacfdSMark Johnston pid = fork();
441dd8bacfdSMark Johnston ATF_REQUIRE(pid >= 0);
442dd8bacfdSMark Johnston if (pid == 0) {
443dd8bacfdSMark Johnston /* Child. */
444dd8bacfdSMark Johnston (void)close(socks[0]);
445dd8bacfdSMark Johnston send_many_fds_child(socks[1]);
446dd8bacfdSMark Johnston _exit(0);
447dd8bacfdSMark Johnston }
448dd8bacfdSMark Johnston
449dd8bacfdSMark Johnston (void)close(socks[1]);
450dd8bacfdSMark Johnston
451dd8bacfdSMark Johnston for (i = 1; i < NFDS; i++) {
452dd8bacfdSMark Johnston bnfds = nopenfds();
453dd8bacfdSMark Johnston ATF_REQUIRE(bnfds != -1);
454dd8bacfdSMark Johnston
455dd8bacfdSMark Johnston nvl = nvlist_recv(socks[0], 0);
456dd8bacfdSMark Johnston ATF_REQUIRE(nvl != NULL);
457dd8bacfdSMark Johnston for (j = 0; j < i; j++) {
458dd8bacfdSMark Johnston snprintf(name, sizeof(name), "fd%d", j);
459dd8bacfdSMark Johnston fd = nvlist_take_descriptor(nvl, name);
460dd8bacfdSMark Johnston ATF_REQUIRE(close(fd) == 0);
461dd8bacfdSMark Johnston }
462dd8bacfdSMark Johnston nvlist_destroy(nvl);
463dd8bacfdSMark Johnston
464dd8bacfdSMark Johnston anfds = nopenfds();
465dd8bacfdSMark Johnston ATF_REQUIRE(anfds != -1);
466dd8bacfdSMark Johnston ATF_REQUIRE(anfds == bnfds);
467dd8bacfdSMark Johnston }
468dd8bacfdSMark Johnston
469dd8bacfdSMark Johnston ATF_REQUIRE(waitpid(pid, &status, 0) == pid);
470dd8bacfdSMark Johnston ATF_REQUIRE(status == 0);
471dd8bacfdSMark Johnston }
472dd8bacfdSMark Johnston
4735916ae1fSRobert Wing /*
4745916ae1fSRobert Wing * This test needs to tune the following sysctl's:
475a7cb27ceSRobert Wing * net.local.dgram.maxdgram
476a7cb27ceSRobert Wing * net.local.dgram.recvspace
4775916ae1fSRobert Wing */
4785916ae1fSRobert Wing ATF_TC_WITHOUT_HEAD(nvlist_send_recv__send_many_fds__dgram);
ATF_TC_BODY(nvlist_send_recv__send_many_fds__dgram,tc)4795916ae1fSRobert Wing ATF_TC_BODY(nvlist_send_recv__send_many_fds__dgram, tc)
4805916ae1fSRobert Wing {
4815916ae1fSRobert Wing u_long maxdgram, recvspace, temp_maxdgram, temp_recvspace;
4825916ae1fSRobert Wing size_t len;
4835916ae1fSRobert Wing int error;
4845916ae1fSRobert Wing
4857c9948c2SRobert Wing atf_tc_skip("https://bugs.freebsd.org/260891");
4867c9948c2SRobert Wing
4875916ae1fSRobert Wing /* size of the largest datagram to send */
4885916ae1fSRobert Wing temp_maxdgram = 16772;
4895916ae1fSRobert Wing len = sizeof(maxdgram);
4905916ae1fSRobert Wing error = sysctlbyname("net.local.dgram.maxdgram", &maxdgram,
4915916ae1fSRobert Wing &len, &temp_maxdgram, sizeof(temp_maxdgram));
4925916ae1fSRobert Wing if (error != 0)
4935916ae1fSRobert Wing atf_tc_skip("cannot set net.local.dgram.maxdgram: %s", strerror(errno));
4945916ae1fSRobert Wing
4955916ae1fSRobert Wing /*
4965916ae1fSRobert Wing * The receive queue fills up quicker than it's being emptied,
497a7cb27ceSRobert Wing * bump it to a sufficiently large enough value, 1M.
4985916ae1fSRobert Wing */
499a7cb27ceSRobert Wing temp_recvspace = 1048576;
5005916ae1fSRobert Wing len = sizeof(recvspace);
5015916ae1fSRobert Wing error = sysctlbyname("net.local.dgram.recvspace", &recvspace,
5025916ae1fSRobert Wing &len, &temp_recvspace, sizeof(temp_recvspace));
5035916ae1fSRobert Wing if (error != 0)
5045916ae1fSRobert Wing atf_tc_skip("cannot set net.local.dgram.recvspace: %s", strerror(errno));
5055916ae1fSRobert Wing
5065916ae1fSRobert Wing nvlist_send_recv__send_many_fds(SOCK_DGRAM);
5075916ae1fSRobert Wing
5085916ae1fSRobert Wing /* restore original values */
5095916ae1fSRobert Wing error = sysctlbyname("net.local.dgram.maxdgram", NULL, NULL, &maxdgram, sizeof(maxdgram));
5105916ae1fSRobert Wing if (error != 0)
5115916ae1fSRobert Wing warn("failed to restore net.local.dgram.maxdgram");
5125916ae1fSRobert Wing
5135916ae1fSRobert Wing error = sysctlbyname("net.local.dgram.recvspace", NULL, NULL, &recvspace, sizeof(recvspace));
5145916ae1fSRobert Wing if (error != 0)
5155916ae1fSRobert Wing warn("failed to restore net.local.dgram.recvspace");
5165916ae1fSRobert Wing }
5175916ae1fSRobert Wing
5185916ae1fSRobert Wing ATF_TC_WITHOUT_HEAD(nvlist_send_recv__send_many_fds__stream);
ATF_TC_BODY(nvlist_send_recv__send_many_fds__stream,tc)5195916ae1fSRobert Wing ATF_TC_BODY(nvlist_send_recv__send_many_fds__stream, tc)
5205916ae1fSRobert Wing {
5215916ae1fSRobert Wing nvlist_send_recv__send_many_fds(SOCK_STREAM);
5225916ae1fSRobert Wing }
5235916ae1fSRobert Wing
5245916ae1fSRobert Wing ATF_TC_WITHOUT_HEAD(nvlist_send_recv__send_nvlist__dgram);
ATF_TC_BODY(nvlist_send_recv__send_nvlist__dgram,tc)5255916ae1fSRobert Wing ATF_TC_BODY(nvlist_send_recv__send_nvlist__dgram, tc)
5265916ae1fSRobert Wing {
5275916ae1fSRobert Wing nvlist_send_recv__send_nvlist(SOCK_DGRAM);
5285916ae1fSRobert Wing }
5295916ae1fSRobert Wing
5305916ae1fSRobert Wing ATF_TC_WITHOUT_HEAD(nvlist_send_recv__send_nvlist__stream);
ATF_TC_BODY(nvlist_send_recv__send_nvlist__stream,tc)5315916ae1fSRobert Wing ATF_TC_BODY(nvlist_send_recv__send_nvlist__stream, tc)
5325916ae1fSRobert Wing {
5335916ae1fSRobert Wing nvlist_send_recv__send_nvlist(SOCK_STREAM);
5345916ae1fSRobert Wing }
5355916ae1fSRobert Wing
5365916ae1fSRobert Wing ATF_TC_WITHOUT_HEAD(nvlist_send_recv__send_closed_fd__dgram);
ATF_TC_BODY(nvlist_send_recv__send_closed_fd__dgram,tc)5375916ae1fSRobert Wing ATF_TC_BODY(nvlist_send_recv__send_closed_fd__dgram, tc)
5385916ae1fSRobert Wing {
5395916ae1fSRobert Wing nvlist_send_recv__send_closed_fd(SOCK_DGRAM);
5405916ae1fSRobert Wing }
5415916ae1fSRobert Wing
5425916ae1fSRobert Wing ATF_TC_WITHOUT_HEAD(nvlist_send_recv__send_closed_fd__stream);
ATF_TC_BODY(nvlist_send_recv__send_closed_fd__stream,tc)5435916ae1fSRobert Wing ATF_TC_BODY(nvlist_send_recv__send_closed_fd__stream, tc)
5445916ae1fSRobert Wing {
5455916ae1fSRobert Wing nvlist_send_recv__send_closed_fd(SOCK_STREAM);
5465916ae1fSRobert Wing }
5475916ae1fSRobert Wing
548*241a7dddSMariusz Zaborski ATF_TC_WITHOUT_HEAD(nvlist_send_recv__overflow_header_size);
ATF_TC_BODY(nvlist_send_recv__overflow_header_size,tc)549*241a7dddSMariusz Zaborski ATF_TC_BODY(nvlist_send_recv__overflow_header_size, tc)
550*241a7dddSMariusz Zaborski {
551*241a7dddSMariusz Zaborski nvlist_t *nvl;
552*241a7dddSMariusz Zaborski void *packed;
553*241a7dddSMariusz Zaborski size_t packed_size;
554*241a7dddSMariusz Zaborski struct nvlist_header *header;
555*241a7dddSMariusz Zaborski int fd, socks[2], status;
556*241a7dddSMariusz Zaborski pid_t pid;
557*241a7dddSMariusz Zaborski
558*241a7dddSMariusz Zaborski #ifdef NO_ASAN
559*241a7dddSMariusz Zaborski atf_tc_skip("This test requires ASAN");
560*241a7dddSMariusz Zaborski #endif
561*241a7dddSMariusz Zaborski
562*241a7dddSMariusz Zaborski ATF_REQUIRE_EQ(socketpair(PF_UNIX, SOCK_STREAM, 0, socks), 0);
563*241a7dddSMariusz Zaborski
564*241a7dddSMariusz Zaborski pid = fork();
565*241a7dddSMariusz Zaborski ATF_REQUIRE(pid >= 0);
566*241a7dddSMariusz Zaborski
567*241a7dddSMariusz Zaborski if (pid == 0) {
568*241a7dddSMariusz Zaborski /* Child. */
569*241a7dddSMariusz Zaborski fd = socks[0];
570*241a7dddSMariusz Zaborski close(socks[1]);
571*241a7dddSMariusz Zaborski
572*241a7dddSMariusz Zaborski nvl = nvlist_create(0);
573*241a7dddSMariusz Zaborski ATF_REQUIRE(nvl != NULL);
574*241a7dddSMariusz Zaborski ATF_REQUIRE(nvlist_empty(nvl));
575*241a7dddSMariusz Zaborski
576*241a7dddSMariusz Zaborski packed = nvlist_pack(nvl, &packed_size);
577*241a7dddSMariusz Zaborski ATF_REQUIRE(packed != NULL);
578*241a7dddSMariusz Zaborski ATF_REQUIRE(packed_size >= sizeof(struct nvlist_header));
579*241a7dddSMariusz Zaborski
580*241a7dddSMariusz Zaborski header = (struct nvlist_header *)packed;
581*241a7dddSMariusz Zaborski header->nvlh_size = SIZE_MAX - sizeof(struct nvlist_header) + 2;
582*241a7dddSMariusz Zaborski
583*241a7dddSMariusz Zaborski ATF_REQUIRE_EQ(write(fd, packed, packed_size),
584*241a7dddSMariusz Zaborski (ssize_t)sizeof(struct nvlist_header));
585*241a7dddSMariusz Zaborski
586*241a7dddSMariusz Zaborski nvlist_destroy(nvl);
587*241a7dddSMariusz Zaborski free(packed);
588*241a7dddSMariusz Zaborski
589*241a7dddSMariusz Zaborski exit(0);
590*241a7dddSMariusz Zaborski } else {
591*241a7dddSMariusz Zaborski /* Parent */
592*241a7dddSMariusz Zaborski fd = socks[1];
593*241a7dddSMariusz Zaborski close(socks[0]);
594*241a7dddSMariusz Zaborski
595*241a7dddSMariusz Zaborski errno = 0;
596*241a7dddSMariusz Zaborski nvl = nvlist_recv(fd, 0);
597*241a7dddSMariusz Zaborski ATF_REQUIRE(nvl == NULL);
598*241a7dddSMariusz Zaborski
599*241a7dddSMariusz Zaborski /*
600*241a7dddSMariusz Zaborski * Make sure it has failed on EINVAL, and not on
601*241a7dddSMariusz Zaborski * errors returned by malloc or recv.
602*241a7dddSMariusz Zaborski */
603*241a7dddSMariusz Zaborski ATF_REQUIRE(errno == EINVAL);
604*241a7dddSMariusz Zaborski
605*241a7dddSMariusz Zaborski ATF_REQUIRE(waitpid(pid, &status, 0) == pid);
606*241a7dddSMariusz Zaborski ATF_REQUIRE(status == 0);
607*241a7dddSMariusz Zaborski close(fd);
608*241a7dddSMariusz Zaborski }
609*241a7dddSMariusz Zaborski }
610*241a7dddSMariusz Zaborski
611*241a7dddSMariusz Zaborski ATF_TC_WITHOUT_HEAD(nvlist_send_recv__invalid_fd_size);
ATF_TC_BODY(nvlist_send_recv__invalid_fd_size,tc)612*241a7dddSMariusz Zaborski ATF_TC_BODY(nvlist_send_recv__invalid_fd_size, tc)
613*241a7dddSMariusz Zaborski {
614*241a7dddSMariusz Zaborski nvlist_t *nvl;
615*241a7dddSMariusz Zaborski void *packed;
616*241a7dddSMariusz Zaborski size_t packed_size;
617*241a7dddSMariusz Zaborski struct nvlist_header *header;
618*241a7dddSMariusz Zaborski int fd, socks[2], status;
619*241a7dddSMariusz Zaborski pid_t pid;
620*241a7dddSMariusz Zaborski
621*241a7dddSMariusz Zaborski ATF_REQUIRE_EQ(socketpair(PF_UNIX, SOCK_STREAM, 0, socks), 0);
622*241a7dddSMariusz Zaborski
623*241a7dddSMariusz Zaborski pid = fork();
624*241a7dddSMariusz Zaborski ATF_REQUIRE(pid >= 0);
625*241a7dddSMariusz Zaborski
626*241a7dddSMariusz Zaborski if (pid == 0) {
627*241a7dddSMariusz Zaborski /* Child. */
628*241a7dddSMariusz Zaborski fd = socks[0];
629*241a7dddSMariusz Zaborski close(socks[1]);
630*241a7dddSMariusz Zaborski
631*241a7dddSMariusz Zaborski nvl = nvlist_create(0);
632*241a7dddSMariusz Zaborski ATF_REQUIRE(nvl != NULL);
633*241a7dddSMariusz Zaborski ATF_REQUIRE(nvlist_empty(nvl));
634*241a7dddSMariusz Zaborski
635*241a7dddSMariusz Zaborski nvlist_add_string(nvl, "nvl/string", "test");
636*241a7dddSMariusz Zaborski ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
637*241a7dddSMariusz Zaborski
638*241a7dddSMariusz Zaborski packed = nvlist_pack(nvl, &packed_size);
639*241a7dddSMariusz Zaborski ATF_REQUIRE(packed != NULL);
640*241a7dddSMariusz Zaborski ATF_REQUIRE(packed_size >= sizeof(struct nvlist_header));
641*241a7dddSMariusz Zaborski
642*241a7dddSMariusz Zaborski header = (struct nvlist_header *)packed;
643*241a7dddSMariusz Zaborski header->nvlh_descriptors = 0x20;
644*241a7dddSMariusz Zaborski
645*241a7dddSMariusz Zaborski ATF_REQUIRE_EQ(write(fd, packed, packed_size),
646*241a7dddSMariusz Zaborski (ssize_t)packed_size);
647*241a7dddSMariusz Zaborski
648*241a7dddSMariusz Zaborski nvlist_destroy(nvl);
649*241a7dddSMariusz Zaborski free(packed);
650*241a7dddSMariusz Zaborski
651*241a7dddSMariusz Zaborski exit(0);
652*241a7dddSMariusz Zaborski } else {
653*241a7dddSMariusz Zaborski /* Parent */
654*241a7dddSMariusz Zaborski fd = socks[1];
655*241a7dddSMariusz Zaborski close(socks[0]);
656*241a7dddSMariusz Zaborski
657*241a7dddSMariusz Zaborski nvl = nvlist_recv(fd, 0);
658*241a7dddSMariusz Zaborski ATF_REQUIRE(nvl == NULL);
659*241a7dddSMariusz Zaborski
660*241a7dddSMariusz Zaborski ATF_REQUIRE(waitpid(pid, &status, 0) == pid);
661*241a7dddSMariusz Zaborski ATF_REQUIRE(status == 0);
662*241a7dddSMariusz Zaborski }
663*241a7dddSMariusz Zaborski
664*241a7dddSMariusz Zaborski close(fd);
665*241a7dddSMariusz Zaborski }
666*241a7dddSMariusz Zaborski
667*241a7dddSMariusz Zaborski ATF_TC_WITHOUT_HEAD(nvlist_send_recv__overflow_fd_size);
ATF_TC_BODY(nvlist_send_recv__overflow_fd_size,tc)668*241a7dddSMariusz Zaborski ATF_TC_BODY(nvlist_send_recv__overflow_fd_size, tc)
669*241a7dddSMariusz Zaborski {
670*241a7dddSMariusz Zaborski nvlist_t *nvl;
671*241a7dddSMariusz Zaborski void *packed;
672*241a7dddSMariusz Zaborski size_t packed_size;
673*241a7dddSMariusz Zaborski struct nvlist_header *header;
674*241a7dddSMariusz Zaborski int fd, socks[2], fds[1], status;
675*241a7dddSMariusz Zaborski pid_t pid;
676*241a7dddSMariusz Zaborski
677*241a7dddSMariusz Zaborski ATF_REQUIRE_EQ(socketpair(PF_UNIX, SOCK_STREAM, 0, socks), 0);
678*241a7dddSMariusz Zaborski
679*241a7dddSMariusz Zaborski pid = fork();
680*241a7dddSMariusz Zaborski ATF_REQUIRE(pid >= 0);
681*241a7dddSMariusz Zaborski
682*241a7dddSMariusz Zaborski if (pid == 0) {
683*241a7dddSMariusz Zaborski /* Child. */
684*241a7dddSMariusz Zaborski fd = socks[0];
685*241a7dddSMariusz Zaborski close(socks[1]);
686*241a7dddSMariusz Zaborski
687*241a7dddSMariusz Zaborski nvl = nvlist_create(0);
688*241a7dddSMariusz Zaborski ATF_REQUIRE(nvl != NULL);
689*241a7dddSMariusz Zaborski ATF_REQUIRE(nvlist_empty(nvl));
690*241a7dddSMariusz Zaborski
691*241a7dddSMariusz Zaborski nvlist_add_string(nvl, "nvl/string", "test");
692*241a7dddSMariusz Zaborski ATF_REQUIRE_EQ(nvlist_error(nvl), 0);
693*241a7dddSMariusz Zaborski
694*241a7dddSMariusz Zaborski packed = nvlist_pack(nvl, &packed_size);
695*241a7dddSMariusz Zaborski ATF_REQUIRE(packed != NULL);
696*241a7dddSMariusz Zaborski ATF_REQUIRE(packed_size >= sizeof(struct nvlist_header));
697*241a7dddSMariusz Zaborski
698*241a7dddSMariusz Zaborski header = (struct nvlist_header *)packed;
699*241a7dddSMariusz Zaborski header->nvlh_descriptors = 0x4000000000000002;
700*241a7dddSMariusz Zaborski
701*241a7dddSMariusz Zaborski ATF_REQUIRE_EQ(write(fd, packed, packed_size),
702*241a7dddSMariusz Zaborski (ssize_t)packed_size);
703*241a7dddSMariusz Zaborski
704*241a7dddSMariusz Zaborski fds[0] = dup(STDERR_FILENO);
705*241a7dddSMariusz Zaborski ATF_REQUIRE(fds[0] >= 0);
706*241a7dddSMariusz Zaborski ATF_REQUIRE_EQ(fd_send(fd, fds, 1), 0);
707*241a7dddSMariusz Zaborski
708*241a7dddSMariusz Zaborski nvlist_destroy(nvl);
709*241a7dddSMariusz Zaborski free(packed);
710*241a7dddSMariusz Zaborski
711*241a7dddSMariusz Zaborski close(fds[0]);
712*241a7dddSMariusz Zaborski close(fd);
713*241a7dddSMariusz Zaborski
714*241a7dddSMariusz Zaborski exit(0);
715*241a7dddSMariusz Zaborski } else {
716*241a7dddSMariusz Zaborski /* Parent */
717*241a7dddSMariusz Zaborski fd = socks[1];
718*241a7dddSMariusz Zaborski close(socks[0]);
719*241a7dddSMariusz Zaborski
720*241a7dddSMariusz Zaborski nvl = nvlist_recv(fd, 0);
721*241a7dddSMariusz Zaborski ATF_REQUIRE(nvl == NULL);
722*241a7dddSMariusz Zaborski
723*241a7dddSMariusz Zaborski /* Make sure that fd was not parsed by nvlist */
724*241a7dddSMariusz Zaborski ATF_REQUIRE(fd_recv(fd, fds, 1) == 0);
725*241a7dddSMariusz Zaborski
726*241a7dddSMariusz Zaborski ATF_REQUIRE(waitpid(pid, &status, 0) == pid);
727*241a7dddSMariusz Zaborski ATF_REQUIRE(status == 0);
728*241a7dddSMariusz Zaborski
729*241a7dddSMariusz Zaborski close(fds[0]);
730*241a7dddSMariusz Zaborski close(fd);
731*241a7dddSMariusz Zaborski }
732*241a7dddSMariusz Zaborski }
733*241a7dddSMariusz Zaborski
ATF_TP_ADD_TCS(tp)734ccf7f846SMark Johnston ATF_TP_ADD_TCS(tp)
735991666adSMark Johnston {
736991666adSMark Johnston
7375916ae1fSRobert Wing ATF_TP_ADD_TC(tp, nvlist_send_recv__send_nvlist__dgram);
7385916ae1fSRobert Wing ATF_TP_ADD_TC(tp, nvlist_send_recv__send_nvlist__stream);
7395916ae1fSRobert Wing ATF_TP_ADD_TC(tp, nvlist_send_recv__send_closed_fd__dgram);
7405916ae1fSRobert Wing ATF_TP_ADD_TC(tp, nvlist_send_recv__send_closed_fd__stream);
7415916ae1fSRobert Wing ATF_TP_ADD_TC(tp, nvlist_send_recv__send_many_fds__dgram);
7425916ae1fSRobert Wing ATF_TP_ADD_TC(tp, nvlist_send_recv__send_many_fds__stream);
743991666adSMark Johnston
744*241a7dddSMariusz Zaborski ATF_TP_ADD_TC(tp, nvlist_send_recv__overflow_header_size);
745*241a7dddSMariusz Zaborski ATF_TP_ADD_TC(tp, nvlist_send_recv__invalid_fd_size);
746*241a7dddSMariusz Zaborski ATF_TP_ADD_TC(tp, nvlist_send_recv__overflow_fd_size);
747*241a7dddSMariusz Zaborski
748ccf7f846SMark Johnston return (atf_no_error());
749b236bcf1SEnji Cooper }
750