1 /*-
2 * Copyright (c) 2012 The FreeBSD Foundation
3 * All rights reserved.
4 *
5 * This software was developed by Pawel Jakub Dawidek under sponsorship from
6 * the FreeBSD Foundation.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32
33 #include <sys/types.h>
34 #include <sys/capsicum.h>
35 #include <sys/procdesc.h>
36 #include <sys/socket.h>
37 #include <sys/wait.h>
38
39 #include <err.h>
40 #include <errno.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <unistd.h>
44
45 #include "misc.h"
46
47 static void
fcntl_tests_0(int fd)48 fcntl_tests_0(int fd)
49 {
50 uint32_t fcntlrights;
51
52 fcntlrights = 0;
53 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
54 CHECK(fcntlrights == CAP_FCNTL_ALL);
55
56 CHECK(fcntl(fd, F_GETFD) == 0);
57 CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
58 CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
59 CHECK(fcntl(fd, F_SETFD, 0) == 0);
60 CHECK(fcntl(fd, F_GETFD) == 0);
61
62 CHECK(fcntl(fd, F_GETFL) == O_RDWR);
63 CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == 0);
64 CHECK(fcntl(fd, F_GETFL) == (O_RDWR | O_NONBLOCK));
65 CHECK(fcntl(fd, F_SETFL, 0) == 0);
66 CHECK(fcntl(fd, F_GETFL) == O_RDWR);
67
68 errno = 0;
69 CHECK(cap_fcntls_limit(fd, ~CAP_FCNTL_ALL) == -1);
70 CHECK(errno == EINVAL);
71 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == 0);
72 fcntlrights = 0;
73 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
74 CHECK(fcntlrights == (CAP_FCNTL_GETFL | CAP_FCNTL_SETFL));
75 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == 0);
76 fcntlrights = 0;
77 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
78 CHECK(fcntlrights == (CAP_FCNTL_GETFL | CAP_FCNTL_SETFL));
79
80 CHECK(fcntl(fd, F_GETFD) == 0);
81 CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
82 CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
83 CHECK(fcntl(fd, F_SETFD, 0) == 0);
84 CHECK(fcntl(fd, F_GETFD) == 0);
85
86 CHECK(fcntl(fd, F_GETFL) == O_RDWR);
87 CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == 0);
88 CHECK(fcntl(fd, F_GETFL) == (O_RDWR | O_NONBLOCK));
89 CHECK(fcntl(fd, F_SETFL, 0) == 0);
90 CHECK(fcntl(fd, F_GETFL) == O_RDWR);
91
92 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == 0);
93 fcntlrights = 0;
94 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
95 CHECK(fcntlrights == CAP_FCNTL_GETFL);
96 errno = 0;
97 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1);
98 CHECK(errno == ENOTCAPABLE);
99 fcntlrights = 0;
100 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
101 CHECK(fcntlrights == CAP_FCNTL_GETFL);
102
103 CHECK(fcntl(fd, F_GETFD) == 0);
104 CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
105 CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
106 CHECK(fcntl(fd, F_SETFD, 0) == 0);
107 CHECK(fcntl(fd, F_GETFD) == 0);
108
109 CHECK(fcntl(fd, F_GETFL) == O_RDWR);
110 errno = 0;
111 CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1);
112 CHECK(errno == ENOTCAPABLE);
113 CHECK(fcntl(fd, F_GETFL) == O_RDWR);
114 errno = 0;
115 CHECK(fcntl(fd, F_SETFL, 0) == -1);
116 CHECK(errno == ENOTCAPABLE);
117 CHECK(fcntl(fd, F_GETFL) == O_RDWR);
118
119 CHECK(cap_fcntls_limit(fd, 0) == 0);
120 fcntlrights = CAP_FCNTL_ALL;
121 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
122 CHECK(fcntlrights == 0);
123 errno = 0;
124 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1);
125 CHECK(errno == ENOTCAPABLE);
126 fcntlrights = CAP_FCNTL_ALL;
127 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
128 CHECK(fcntlrights == 0);
129 errno = 0;
130 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == -1);
131 CHECK(errno == ENOTCAPABLE);
132 fcntlrights = CAP_FCNTL_ALL;
133 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
134 CHECK(fcntlrights == 0);
135
136 CHECK(fcntl(fd, F_GETFD) == 0);
137 CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
138 CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
139 CHECK(fcntl(fd, F_SETFD, 0) == 0);
140 CHECK(fcntl(fd, F_GETFD) == 0);
141
142 errno = 0;
143 CHECK(fcntl(fd, F_GETFL) == -1);
144 CHECK(errno == ENOTCAPABLE);
145 errno = 0;
146 CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1);
147 CHECK(errno == ENOTCAPABLE);
148 errno = 0;
149 CHECK(fcntl(fd, F_SETFL, 0) == -1);
150 CHECK(errno == ENOTCAPABLE);
151 errno = 0;
152 CHECK(fcntl(fd, F_GETFL) == -1);
153 CHECK(errno == ENOTCAPABLE);
154 }
155
156 static void
fcntl_tests_1(int fd)157 fcntl_tests_1(int fd)
158 {
159 uint32_t fcntlrights;
160
161 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == 0);
162 fcntlrights = 0;
163 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
164 CHECK(fcntlrights == CAP_FCNTL_GETFL);
165
166 CHECK(cap_rights_limit(fd, CAP_ALL & ~CAP_FCNTL) == 0);
167
168 fcntlrights = CAP_FCNTL_ALL;
169 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
170 CHECK(fcntlrights == 0);
171
172 errno = 0;
173 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1);
174 CHECK(errno == ENOTCAPABLE);
175 fcntlrights = CAP_FCNTL_ALL;
176 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
177 CHECK(fcntlrights == 0);
178 errno = 0;
179 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == -1);
180 CHECK(errno == ENOTCAPABLE);
181 fcntlrights = CAP_FCNTL_ALL;
182 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
183 CHECK(fcntlrights == 0);
184
185 CHECK(fcntl(fd, F_GETFD) == 0);
186 CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
187 CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
188 CHECK(fcntl(fd, F_SETFD, 0) == 0);
189 CHECK(fcntl(fd, F_GETFD) == 0);
190
191 errno = 0;
192 CHECK(fcntl(fd, F_GETFL) == -1);
193 CHECK(errno == ENOTCAPABLE);
194 errno = 0;
195 CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1);
196 CHECK(errno == ENOTCAPABLE);
197 errno = 0;
198 CHECK(fcntl(fd, F_SETFL, 0) == -1);
199 CHECK(errno == ENOTCAPABLE);
200 errno = 0;
201 CHECK(fcntl(fd, F_GETFL) == -1);
202 CHECK(errno == ENOTCAPABLE);
203 }
204
205 static void
fcntl_tests_2(int fd)206 fcntl_tests_2(int fd)
207 {
208 uint32_t fcntlrights;
209
210 CHECK(cap_rights_limit(fd, CAP_ALL & ~CAP_FCNTL) == 0);
211
212 fcntlrights = CAP_FCNTL_ALL;
213 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
214 CHECK(fcntlrights == 0);
215
216 errno = 0;
217 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1);
218 CHECK(errno == ENOTCAPABLE);
219 fcntlrights = CAP_FCNTL_ALL;
220 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
221 CHECK(fcntlrights == 0);
222 errno = 0;
223 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == -1);
224 CHECK(errno == ENOTCAPABLE);
225 fcntlrights = CAP_FCNTL_ALL;
226 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
227 CHECK(fcntlrights == 0);
228
229 CHECK(fcntl(fd, F_GETFD) == 0);
230 CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
231 CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
232 CHECK(fcntl(fd, F_SETFD, 0) == 0);
233 CHECK(fcntl(fd, F_GETFD) == 0);
234
235 errno = 0;
236 CHECK(fcntl(fd, F_GETFL) == -1);
237 CHECK(errno == ENOTCAPABLE);
238 errno = 0;
239 CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1);
240 CHECK(errno == ENOTCAPABLE);
241 errno = 0;
242 CHECK(fcntl(fd, F_SETFL, 0) == -1);
243 CHECK(errno == ENOTCAPABLE);
244 errno = 0;
245 CHECK(fcntl(fd, F_GETFL) == -1);
246 CHECK(errno == ENOTCAPABLE);
247 }
248
249 static void
fcntl_tests_send_0(int sock)250 fcntl_tests_send_0(int sock)
251 {
252 int fd;
253
254 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
255 CHECK(descriptor_send(sock, fd) == 0);
256 CHECK(close(fd) == 0);
257
258 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
259 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == 0);
260 CHECK(descriptor_send(sock, fd) == 0);
261 CHECK(close(fd) == 0);
262
263 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
264 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == 0);
265 CHECK(descriptor_send(sock, fd) == 0);
266 CHECK(close(fd) == 0);
267
268 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
269 CHECK(cap_fcntls_limit(fd, 0) == 0);
270 CHECK(descriptor_send(sock, fd) == 0);
271 CHECK(close(fd) == 0);
272 }
273
274 static void
fcntl_tests_recv_0(int sock)275 fcntl_tests_recv_0(int sock)
276 {
277 uint32_t fcntlrights;
278 int fd;
279
280 CHECK(descriptor_recv(sock, &fd) == 0);
281
282 fcntlrights = 0;
283 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
284 CHECK(fcntlrights == CAP_FCNTL_ALL);
285
286 CHECK(fcntl(fd, F_GETFD) == 0);
287 CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
288 CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
289 CHECK(fcntl(fd, F_SETFD, 0) == 0);
290 CHECK(fcntl(fd, F_GETFD) == 0);
291
292 CHECK(fcntl(fd, F_GETFL) == O_RDWR);
293 CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == 0);
294 CHECK(fcntl(fd, F_GETFL) == (O_RDWR | O_NONBLOCK));
295 CHECK(fcntl(fd, F_SETFL, 0) == 0);
296 CHECK(fcntl(fd, F_GETFL) == O_RDWR);
297
298 CHECK(close(fd) == 0);
299
300 CHECK(descriptor_recv(sock, &fd) == 0);
301
302 fcntlrights = 0;
303 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
304 CHECK(fcntlrights == (CAP_FCNTL_GETFL | CAP_FCNTL_SETFL));
305 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == 0);
306 fcntlrights = 0;
307 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
308 CHECK(fcntlrights == (CAP_FCNTL_GETFL | CAP_FCNTL_SETFL));
309
310 CHECK(fcntl(fd, F_GETFD) == 0);
311 CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
312 CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
313 CHECK(fcntl(fd, F_SETFD, 0) == 0);
314 CHECK(fcntl(fd, F_GETFD) == 0);
315
316 CHECK(fcntl(fd, F_GETFL) == O_RDWR);
317 CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == 0);
318 CHECK(fcntl(fd, F_GETFL) == (O_RDWR | O_NONBLOCK));
319 CHECK(fcntl(fd, F_SETFL, 0) == 0);
320 CHECK(fcntl(fd, F_GETFL) == O_RDWR);
321
322 CHECK(close(fd) == 0);
323
324 CHECK(descriptor_recv(sock, &fd) == 0);
325
326 fcntlrights = 0;
327 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
328 CHECK(fcntlrights == CAP_FCNTL_GETFL);
329 errno = 0;
330 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1);
331 CHECK(errno == ENOTCAPABLE);
332 fcntlrights = 0;
333 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
334 CHECK(fcntlrights == CAP_FCNTL_GETFL);
335 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == 0);
336 fcntlrights = 0;
337 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
338 CHECK(fcntlrights == CAP_FCNTL_GETFL);
339
340 CHECK(fcntl(fd, F_GETFD) == 0);
341 CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
342 CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
343 CHECK(fcntl(fd, F_SETFD, 0) == 0);
344 CHECK(fcntl(fd, F_GETFD) == 0);
345
346 CHECK(fcntl(fd, F_GETFL) == O_RDWR);
347 errno = 0;
348 CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1);
349 CHECK(errno == ENOTCAPABLE);
350 CHECK(fcntl(fd, F_GETFL) == O_RDWR);
351 errno = 0;
352 CHECK(fcntl(fd, F_SETFL, 0) == -1);
353 CHECK(errno == ENOTCAPABLE);
354 CHECK(fcntl(fd, F_GETFL) == O_RDWR);
355
356 CHECK(close(fd) == 0);
357
358 CHECK(descriptor_recv(sock, &fd) == 0);
359
360 fcntlrights = 0;
361 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
362 CHECK(fcntlrights == 0);
363 errno = 0;
364 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1);
365 CHECK(errno == ENOTCAPABLE);
366 fcntlrights = 0;
367 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
368 CHECK(fcntlrights == 0);
369 errno = 0;
370 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == -1);
371 CHECK(errno == ENOTCAPABLE);
372 fcntlrights = 0;
373 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
374 CHECK(fcntlrights == 0);
375 errno = 0;
376 CHECK(cap_fcntls_limit(fd, CAP_FCNTL_SETFL) == -1);
377 CHECK(errno == ENOTCAPABLE);
378 fcntlrights = 0;
379 CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
380 CHECK(fcntlrights == 0);
381
382 CHECK(fcntl(fd, F_GETFD) == 0);
383 CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
384 CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
385 CHECK(fcntl(fd, F_SETFD, 0) == 0);
386 CHECK(fcntl(fd, F_GETFD) == 0);
387
388 errno = 0;
389 CHECK(fcntl(fd, F_GETFL) == -1);
390 CHECK(errno == ENOTCAPABLE);
391 errno = 0;
392 CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1);
393 CHECK(errno == ENOTCAPABLE);
394 errno = 0;
395 CHECK(fcntl(fd, F_SETFL, 0) == -1);
396 CHECK(errno == ENOTCAPABLE);
397 errno = 0;
398 CHECK(fcntl(fd, F_GETFL) == -1);
399 CHECK(errno == ENOTCAPABLE);
400
401 CHECK(close(fd) == 0);
402 }
403
404 int
main(void)405 main(void)
406 {
407 int fd, pfd, sp[2];
408 pid_t pid;
409
410 printf("1..870\n");
411
412 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
413 fcntl_tests_0(fd);
414 CHECK(close(fd) == 0);
415
416 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
417 fcntl_tests_1(fd);
418 CHECK(close(fd) == 0);
419
420 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
421 fcntl_tests_2(fd);
422 CHECK(close(fd) == 0);
423
424 /* Child inherits descriptor and operates on it first. */
425 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
426 CHECK((pid = fork()) >= 0);
427 if (pid == 0) {
428 fcntl_tests_0(fd);
429 CHECK(close(fd) == 0);
430 exit(0);
431 } else {
432 CHECK(waitpid(pid, NULL, 0) == pid);
433 fcntl_tests_0(fd);
434 }
435 CHECK(close(fd) == 0);
436
437 /* Child inherits descriptor, but operates on it after parent. */
438 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
439 CHECK((pid = fork()) >= 0);
440 if (pid == 0) {
441 sleep(1);
442 fcntl_tests_0(fd);
443 CHECK(close(fd) == 0);
444 exit(0);
445 } else {
446 fcntl_tests_0(fd);
447 CHECK(waitpid(pid, NULL, 0) == pid);
448 }
449 CHECK(close(fd) == 0);
450
451 /* Child inherits descriptor and operates on it first. */
452 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
453 CHECK((pid = pdfork(&pfd, 0)) >= 0);
454 if (pid == 0) {
455 fcntl_tests_1(fd);
456 exit(0);
457 } else {
458 CHECK(pdwait(pfd) == 0);
459 /*
460 It fails with EBADF, which I believe is a bug.
461 CHECK(close(pfd) == 0);
462 */
463 fcntl_tests_1(fd);
464 }
465 CHECK(close(fd) == 0);
466
467 /* Child inherits descriptor, but operates on it after parent. */
468 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
469 CHECK((pid = pdfork(&pfd, 0)) >= 0);
470 if (pid == 0) {
471 sleep(1);
472 fcntl_tests_1(fd);
473 exit(0);
474 } else {
475 fcntl_tests_1(fd);
476 CHECK(pdwait(pfd) == 0);
477 /*
478 It fails with EBADF, which I believe is a bug.
479 CHECK(close(pfd) == 0);
480 */
481 }
482 CHECK(close(fd) == 0);
483
484 /* Child inherits descriptor and operates on it first. */
485 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
486 CHECK((pid = fork()) >= 0);
487 if (pid == 0) {
488 fcntl_tests_2(fd);
489 exit(0);
490 } else {
491 CHECK(waitpid(pid, NULL, 0) == pid);
492 fcntl_tests_2(fd);
493 }
494 CHECK(close(fd) == 0);
495
496 /* Child inherits descriptor, but operates on it after parent. */
497 CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
498 CHECK((pid = fork()) >= 0);
499 if (pid == 0) {
500 sleep(1);
501 fcntl_tests_2(fd);
502 exit(0);
503 } else {
504 fcntl_tests_2(fd);
505 CHECK(waitpid(pid, NULL, 0) == pid);
506 }
507 CHECK(close(fd) == 0);
508
509 /* Send descriptors from parent to child. */
510 CHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, sp) == 0);
511 CHECK((pid = fork()) >= 0);
512 if (pid == 0) {
513 CHECK(close(sp[0]) == 0);
514 fcntl_tests_recv_0(sp[1]);
515 CHECK(close(sp[1]) == 0);
516 exit(0);
517 } else {
518 CHECK(close(sp[1]) == 0);
519 fcntl_tests_send_0(sp[0]);
520 CHECK(waitpid(pid, NULL, 0) == pid);
521 CHECK(close(sp[0]) == 0);
522 }
523
524 /* Send descriptors from child to parent. */
525 CHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, sp) == 0);
526 CHECK((pid = fork()) >= 0);
527 if (pid == 0) {
528 CHECK(close(sp[0]) == 0);
529 fcntl_tests_send_0(sp[1]);
530 CHECK(close(sp[1]) == 0);
531 exit(0);
532 } else {
533 CHECK(close(sp[1]) == 0);
534 fcntl_tests_recv_0(sp[0]);
535 CHECK(waitpid(pid, NULL, 0) == pid);
536 CHECK(close(sp[0]) == 0);
537 }
538
539 exit(0);
540 }
541