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
47static void
48fcntl_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
156static void
157fcntl_tests_1(int fd)
158{
159	uint32_t fcntlrights;
160	cap_rights_t rights;
161
162	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == 0);
163	fcntlrights = 0;
164	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
165	CHECK(fcntlrights == CAP_FCNTL_GETFL);
166
167	CAP_ALL(&rights);
168	cap_rights_clear(&rights, CAP_FCNTL);
169	CHECK(cap_rights_limit(fd, &rights) == 0);
170
171	fcntlrights = CAP_FCNTL_ALL;
172	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
173	CHECK(fcntlrights == 0);
174
175	errno = 0;
176	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1);
177	CHECK(errno == ENOTCAPABLE);
178	fcntlrights = CAP_FCNTL_ALL;
179	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
180	CHECK(fcntlrights == 0);
181	errno = 0;
182	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == -1);
183	CHECK(errno == ENOTCAPABLE);
184	fcntlrights = CAP_FCNTL_ALL;
185	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
186	CHECK(fcntlrights == 0);
187
188	CHECK(fcntl(fd, F_GETFD) == 0);
189	CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
190	CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
191	CHECK(fcntl(fd, F_SETFD, 0) == 0);
192	CHECK(fcntl(fd, F_GETFD) == 0);
193
194	errno = 0;
195	CHECK(fcntl(fd, F_GETFL) == -1);
196	CHECK(errno == ENOTCAPABLE);
197	errno = 0;
198	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1);
199	CHECK(errno == ENOTCAPABLE);
200	errno = 0;
201	CHECK(fcntl(fd, F_SETFL, 0) == -1);
202	CHECK(errno == ENOTCAPABLE);
203	errno = 0;
204	CHECK(fcntl(fd, F_GETFL) == -1);
205	CHECK(errno == ENOTCAPABLE);
206}
207
208static void
209fcntl_tests_2(int fd)
210{
211	uint32_t fcntlrights;
212	cap_rights_t rights;
213
214	CAP_ALL(&rights);
215	cap_rights_clear(&rights, CAP_FCNTL);
216	CHECK(cap_rights_limit(fd, &rights) == 0);
217
218	fcntlrights = CAP_FCNTL_ALL;
219	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
220	CHECK(fcntlrights == 0);
221
222	errno = 0;
223	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1);
224	CHECK(errno == ENOTCAPABLE);
225	fcntlrights = CAP_FCNTL_ALL;
226	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
227	CHECK(fcntlrights == 0);
228	errno = 0;
229	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == -1);
230	CHECK(errno == ENOTCAPABLE);
231	fcntlrights = CAP_FCNTL_ALL;
232	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
233	CHECK(fcntlrights == 0);
234
235	CHECK(fcntl(fd, F_GETFD) == 0);
236	CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
237	CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
238	CHECK(fcntl(fd, F_SETFD, 0) == 0);
239	CHECK(fcntl(fd, F_GETFD) == 0);
240
241	errno = 0;
242	CHECK(fcntl(fd, F_GETFL) == -1);
243	CHECK(errno == ENOTCAPABLE);
244	errno = 0;
245	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1);
246	CHECK(errno == ENOTCAPABLE);
247	errno = 0;
248	CHECK(fcntl(fd, F_SETFL, 0) == -1);
249	CHECK(errno == ENOTCAPABLE);
250	errno = 0;
251	CHECK(fcntl(fd, F_GETFL) == -1);
252	CHECK(errno == ENOTCAPABLE);
253}
254
255static void
256fcntl_tests_send_0(int sock)
257{
258	int fd;
259
260	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
261	CHECK(descriptor_send(sock, fd) == 0);
262	CHECK(close(fd) == 0);
263
264	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
265	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == 0);
266	CHECK(descriptor_send(sock, fd) == 0);
267	CHECK(close(fd) == 0);
268
269	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
270	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == 0);
271	CHECK(descriptor_send(sock, fd) == 0);
272	CHECK(close(fd) == 0);
273
274	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
275	CHECK(cap_fcntls_limit(fd, 0) == 0);
276	CHECK(descriptor_send(sock, fd) == 0);
277	CHECK(close(fd) == 0);
278}
279
280static void
281fcntl_tests_recv_0(int sock)
282{
283	uint32_t fcntlrights;
284	int fd;
285
286	CHECK(descriptor_recv(sock, &fd) == 0);
287
288	fcntlrights = 0;
289	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
290	CHECK(fcntlrights == CAP_FCNTL_ALL);
291
292	CHECK(fcntl(fd, F_GETFD) == 0);
293	CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
294	CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
295	CHECK(fcntl(fd, F_SETFD, 0) == 0);
296	CHECK(fcntl(fd, F_GETFD) == 0);
297
298	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
299	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == 0);
300	CHECK(fcntl(fd, F_GETFL) == (O_RDWR | O_NONBLOCK));
301	CHECK(fcntl(fd, F_SETFL, 0) == 0);
302	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
303
304	CHECK(close(fd) == 0);
305
306	CHECK(descriptor_recv(sock, &fd) == 0);
307
308	fcntlrights = 0;
309	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
310	CHECK(fcntlrights == (CAP_FCNTL_GETFL | CAP_FCNTL_SETFL));
311	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == 0);
312	fcntlrights = 0;
313	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
314	CHECK(fcntlrights == (CAP_FCNTL_GETFL | CAP_FCNTL_SETFL));
315
316	CHECK(fcntl(fd, F_GETFD) == 0);
317	CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
318	CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
319	CHECK(fcntl(fd, F_SETFD, 0) == 0);
320	CHECK(fcntl(fd, F_GETFD) == 0);
321
322	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
323	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == 0);
324	CHECK(fcntl(fd, F_GETFL) == (O_RDWR | O_NONBLOCK));
325	CHECK(fcntl(fd, F_SETFL, 0) == 0);
326	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
327
328	CHECK(close(fd) == 0);
329
330	CHECK(descriptor_recv(sock, &fd) == 0);
331
332	fcntlrights = 0;
333	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
334	CHECK(fcntlrights == CAP_FCNTL_GETFL);
335	errno = 0;
336	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1);
337	CHECK(errno == ENOTCAPABLE);
338	fcntlrights = 0;
339	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
340	CHECK(fcntlrights == CAP_FCNTL_GETFL);
341	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == 0);
342	fcntlrights = 0;
343	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
344	CHECK(fcntlrights == CAP_FCNTL_GETFL);
345
346	CHECK(fcntl(fd, F_GETFD) == 0);
347	CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
348	CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
349	CHECK(fcntl(fd, F_SETFD, 0) == 0);
350	CHECK(fcntl(fd, F_GETFD) == 0);
351
352	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
353	errno = 0;
354	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1);
355	CHECK(errno == ENOTCAPABLE);
356	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
357	errno = 0;
358	CHECK(fcntl(fd, F_SETFL, 0) == -1);
359	CHECK(errno == ENOTCAPABLE);
360	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
361
362	CHECK(close(fd) == 0);
363
364	CHECK(descriptor_recv(sock, &fd) == 0);
365
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 | CAP_FCNTL_SETFL) == -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_GETFL) == -1);
377	CHECK(errno == ENOTCAPABLE);
378	fcntlrights = 0;
379	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
380	CHECK(fcntlrights == 0);
381	errno = 0;
382	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_SETFL) == -1);
383	CHECK(errno == ENOTCAPABLE);
384	fcntlrights = 0;
385	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
386	CHECK(fcntlrights == 0);
387
388	CHECK(fcntl(fd, F_GETFD) == 0);
389	CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
390	CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
391	CHECK(fcntl(fd, F_SETFD, 0) == 0);
392	CHECK(fcntl(fd, F_GETFD) == 0);
393
394	errno = 0;
395	CHECK(fcntl(fd, F_GETFL) == -1);
396	CHECK(errno == ENOTCAPABLE);
397	errno = 0;
398	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1);
399	CHECK(errno == ENOTCAPABLE);
400	errno = 0;
401	CHECK(fcntl(fd, F_SETFL, 0) == -1);
402	CHECK(errno == ENOTCAPABLE);
403	errno = 0;
404	CHECK(fcntl(fd, F_GETFL) == -1);
405	CHECK(errno == ENOTCAPABLE);
406
407	CHECK(close(fd) == 0);
408}
409
410int
411main(void)
412{
413	int fd, pfd, sp[2];
414	pid_t pid;
415
416	printf("1..870\n");
417
418	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
419	fcntl_tests_0(fd);
420	CHECK(close(fd) == 0);
421
422	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
423	fcntl_tests_1(fd);
424	CHECK(close(fd) == 0);
425
426	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
427	fcntl_tests_2(fd);
428	CHECK(close(fd) == 0);
429
430	/* Child inherits descriptor and operates on it first. */
431	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
432	CHECK((pid = fork()) >= 0);
433	if (pid == 0) {
434		fcntl_tests_0(fd);
435		CHECK(close(fd) == 0);
436		exit(0);
437	} else {
438		CHECK(waitpid(pid, NULL, 0) == pid);
439		fcntl_tests_0(fd);
440	}
441	CHECK(close(fd) == 0);
442
443	/* Child inherits descriptor, but operates on it after parent. */
444	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
445	CHECK((pid = fork()) >= 0);
446	if (pid == 0) {
447		sleep(1);
448		fcntl_tests_0(fd);
449		CHECK(close(fd) == 0);
450		exit(0);
451	} else {
452		fcntl_tests_0(fd);
453		CHECK(waitpid(pid, NULL, 0) == pid);
454	}
455	CHECK(close(fd) == 0);
456
457	/* Child inherits descriptor and operates on it first. */
458	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
459	CHECK((pid = pdfork(&pfd, 0)) >= 0);
460	if (pid == 0) {
461		fcntl_tests_1(fd);
462		exit(0);
463	} else {
464		CHECK(pdwait(pfd) == 0);
465/*
466		It fails with EBADF, which I believe is a bug.
467		CHECK(close(pfd) == 0);
468*/
469		fcntl_tests_1(fd);
470	}
471	CHECK(close(fd) == 0);
472
473	/* Child inherits descriptor, but operates on it after parent. */
474	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
475	CHECK((pid = pdfork(&pfd, 0)) >= 0);
476	if (pid == 0) {
477		sleep(1);
478		fcntl_tests_1(fd);
479		exit(0);
480	} else {
481		fcntl_tests_1(fd);
482		CHECK(pdwait(pfd) == 0);
483/*
484		It fails with EBADF, which I believe is a bug.
485		CHECK(close(pfd) == 0);
486*/
487	}
488	CHECK(close(fd) == 0);
489
490	/* Child inherits descriptor and operates on it first. */
491	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
492	CHECK((pid = fork()) >= 0);
493	if (pid == 0) {
494		fcntl_tests_2(fd);
495		exit(0);
496	} else {
497		CHECK(waitpid(pid, NULL, 0) == pid);
498		fcntl_tests_2(fd);
499	}
500	CHECK(close(fd) == 0);
501
502	/* Child inherits descriptor, but operates on it after parent. */
503	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
504	CHECK((pid = fork()) >= 0);
505	if (pid == 0) {
506		sleep(1);
507		fcntl_tests_2(fd);
508		exit(0);
509	} else {
510		fcntl_tests_2(fd);
511		CHECK(waitpid(pid, NULL, 0) == pid);
512	}
513	CHECK(close(fd) == 0);
514
515	/* Send descriptors from parent to child. */
516	CHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, sp) == 0);
517	CHECK((pid = fork()) >= 0);
518	if (pid == 0) {
519		CHECK(close(sp[0]) == 0);
520		fcntl_tests_recv_0(sp[1]);
521		CHECK(close(sp[1]) == 0);
522		exit(0);
523	} else {
524		CHECK(close(sp[1]) == 0);
525		fcntl_tests_send_0(sp[0]);
526		CHECK(waitpid(pid, NULL, 0) == pid);
527		CHECK(close(sp[0]) == 0);
528	}
529
530	/* Send descriptors from child to parent. */
531	CHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, sp) == 0);
532	CHECK((pid = fork()) >= 0);
533	if (pid == 0) {
534		CHECK(close(sp[0]) == 0);
535		fcntl_tests_send_0(sp[1]);
536		CHECK(close(sp[1]) == 0);
537		exit(0);
538	} else {
539		CHECK(close(sp[1]) == 0);
540		fcntl_tests_recv_0(sp[0]);
541		CHECK(waitpid(pid, NULL, 0) == pid);
542		CHECK(close(sp[0]) == 0);
543	}
544
545	exit(0);
546}
547