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/types.h>
31#include <sys/capsicum.h>
32#include <sys/procdesc.h>
33#include <sys/socket.h>
34#include <sys/wait.h>
35
36#include <err.h>
37#include <errno.h>
38#include <stdio.h>
39#include <stdlib.h>
40#include <unistd.h>
41
42#include "misc.h"
43
44static void
45fcntl_tests_0(int fd)
46{
47	uint32_t fcntlrights;
48
49	fcntlrights = 0;
50	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
51	CHECK(fcntlrights == CAP_FCNTL_ALL);
52
53	CHECK(fcntl(fd, F_GETFD) == 0);
54	CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
55	CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
56	CHECK(fcntl(fd, F_SETFD, 0) == 0);
57	CHECK(fcntl(fd, F_GETFD) == 0);
58
59	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
60	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == 0);
61	CHECK(fcntl(fd, F_GETFL) == (O_RDWR | O_NONBLOCK));
62	CHECK(fcntl(fd, F_SETFL, 0) == 0);
63	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
64
65	errno = 0;
66	CHECK(cap_fcntls_limit(fd, ~CAP_FCNTL_ALL) == -1);
67	CHECK(errno == EINVAL);
68	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == 0);
69	fcntlrights = 0;
70	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
71	CHECK(fcntlrights == (CAP_FCNTL_GETFL | CAP_FCNTL_SETFL));
72	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == 0);
73	fcntlrights = 0;
74	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
75	CHECK(fcntlrights == (CAP_FCNTL_GETFL | CAP_FCNTL_SETFL));
76
77	CHECK(fcntl(fd, F_GETFD) == 0);
78	CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
79	CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
80	CHECK(fcntl(fd, F_SETFD, 0) == 0);
81	CHECK(fcntl(fd, F_GETFD) == 0);
82
83	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
84	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == 0);
85	CHECK(fcntl(fd, F_GETFL) == (O_RDWR | O_NONBLOCK));
86	CHECK(fcntl(fd, F_SETFL, 0) == 0);
87	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
88
89	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == 0);
90	fcntlrights = 0;
91	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
92	CHECK(fcntlrights == CAP_FCNTL_GETFL);
93	errno = 0;
94	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1);
95	CHECK(errno == ENOTCAPABLE);
96	fcntlrights = 0;
97	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
98	CHECK(fcntlrights == CAP_FCNTL_GETFL);
99
100	CHECK(fcntl(fd, F_GETFD) == 0);
101	CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
102	CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
103	CHECK(fcntl(fd, F_SETFD, 0) == 0);
104	CHECK(fcntl(fd, F_GETFD) == 0);
105
106	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
107	errno = 0;
108	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1);
109	CHECK(errno == ENOTCAPABLE);
110	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
111	errno = 0;
112	CHECK(fcntl(fd, F_SETFL, 0) == -1);
113	CHECK(errno == ENOTCAPABLE);
114	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
115
116	CHECK(cap_fcntls_limit(fd, 0) == 0);
117	fcntlrights = CAP_FCNTL_ALL;
118	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
119	CHECK(fcntlrights == 0);
120	errno = 0;
121	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1);
122	CHECK(errno == ENOTCAPABLE);
123	fcntlrights = CAP_FCNTL_ALL;
124	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
125	CHECK(fcntlrights == 0);
126	errno = 0;
127	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == -1);
128	CHECK(errno == ENOTCAPABLE);
129	fcntlrights = CAP_FCNTL_ALL;
130	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
131	CHECK(fcntlrights == 0);
132
133	CHECK(fcntl(fd, F_GETFD) == 0);
134	CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
135	CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
136	CHECK(fcntl(fd, F_SETFD, 0) == 0);
137	CHECK(fcntl(fd, F_GETFD) == 0);
138
139	errno = 0;
140	CHECK(fcntl(fd, F_GETFL) == -1);
141	CHECK(errno == ENOTCAPABLE);
142	errno = 0;
143	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1);
144	CHECK(errno == ENOTCAPABLE);
145	errno = 0;
146	CHECK(fcntl(fd, F_SETFL, 0) == -1);
147	CHECK(errno == ENOTCAPABLE);
148	errno = 0;
149	CHECK(fcntl(fd, F_GETFL) == -1);
150	CHECK(errno == ENOTCAPABLE);
151}
152
153static void
154fcntl_tests_1(int fd)
155{
156	uint32_t fcntlrights;
157	cap_rights_t rights;
158
159	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == 0);
160	fcntlrights = 0;
161	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
162	CHECK(fcntlrights == CAP_FCNTL_GETFL);
163
164	CAP_ALL(&rights);
165	cap_rights_clear(&rights, CAP_FCNTL);
166	CHECK(cap_rights_limit(fd, &rights) == 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
205static void
206fcntl_tests_2(int fd)
207{
208	uint32_t fcntlrights;
209	cap_rights_t rights;
210
211	CAP_ALL(&rights);
212	cap_rights_clear(&rights, CAP_FCNTL);
213	CHECK(cap_rights_limit(fd, &rights) == 0);
214
215	fcntlrights = CAP_FCNTL_ALL;
216	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
217	CHECK(fcntlrights == 0);
218
219	errno = 0;
220	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1);
221	CHECK(errno == ENOTCAPABLE);
222	fcntlrights = CAP_FCNTL_ALL;
223	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
224	CHECK(fcntlrights == 0);
225	errno = 0;
226	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == -1);
227	CHECK(errno == ENOTCAPABLE);
228	fcntlrights = CAP_FCNTL_ALL;
229	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
230	CHECK(fcntlrights == 0);
231
232	CHECK(fcntl(fd, F_GETFD) == 0);
233	CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
234	CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
235	CHECK(fcntl(fd, F_SETFD, 0) == 0);
236	CHECK(fcntl(fd, F_GETFD) == 0);
237
238	errno = 0;
239	CHECK(fcntl(fd, F_GETFL) == -1);
240	CHECK(errno == ENOTCAPABLE);
241	errno = 0;
242	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1);
243	CHECK(errno == ENOTCAPABLE);
244	errno = 0;
245	CHECK(fcntl(fd, F_SETFL, 0) == -1);
246	CHECK(errno == ENOTCAPABLE);
247	errno = 0;
248	CHECK(fcntl(fd, F_GETFL) == -1);
249	CHECK(errno == ENOTCAPABLE);
250}
251
252static void
253fcntl_tests_send_0(int sock)
254{
255	int fd;
256
257	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
258	CHECK(descriptor_send(sock, fd) == 0);
259	CHECK(close(fd) == 0);
260
261	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
262	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == 0);
263	CHECK(descriptor_send(sock, fd) == 0);
264	CHECK(close(fd) == 0);
265
266	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
267	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == 0);
268	CHECK(descriptor_send(sock, fd) == 0);
269	CHECK(close(fd) == 0);
270
271	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
272	CHECK(cap_fcntls_limit(fd, 0) == 0);
273	CHECK(descriptor_send(sock, fd) == 0);
274	CHECK(close(fd) == 0);
275}
276
277static void
278fcntl_tests_recv_0(int sock)
279{
280	uint32_t fcntlrights;
281	int fd;
282
283	CHECK(descriptor_recv(sock, &fd) == 0);
284
285	fcntlrights = 0;
286	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
287	CHECK(fcntlrights == CAP_FCNTL_ALL);
288
289	CHECK(fcntl(fd, F_GETFD) == 0);
290	CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
291	CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
292	CHECK(fcntl(fd, F_SETFD, 0) == 0);
293	CHECK(fcntl(fd, F_GETFD) == 0);
294
295	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
296	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == 0);
297	CHECK(fcntl(fd, F_GETFL) == (O_RDWR | O_NONBLOCK));
298	CHECK(fcntl(fd, F_SETFL, 0) == 0);
299	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
300
301	CHECK(close(fd) == 0);
302
303	CHECK(descriptor_recv(sock, &fd) == 0);
304
305	fcntlrights = 0;
306	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
307	CHECK(fcntlrights == (CAP_FCNTL_GETFL | CAP_FCNTL_SETFL));
308	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == 0);
309	fcntlrights = 0;
310	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
311	CHECK(fcntlrights == (CAP_FCNTL_GETFL | CAP_FCNTL_SETFL));
312
313	CHECK(fcntl(fd, F_GETFD) == 0);
314	CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
315	CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
316	CHECK(fcntl(fd, F_SETFD, 0) == 0);
317	CHECK(fcntl(fd, F_GETFD) == 0);
318
319	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
320	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == 0);
321	CHECK(fcntl(fd, F_GETFL) == (O_RDWR | O_NONBLOCK));
322	CHECK(fcntl(fd, F_SETFL, 0) == 0);
323	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
324
325	CHECK(close(fd) == 0);
326
327	CHECK(descriptor_recv(sock, &fd) == 0);
328
329	fcntlrights = 0;
330	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
331	CHECK(fcntlrights == CAP_FCNTL_GETFL);
332	errno = 0;
333	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1);
334	CHECK(errno == ENOTCAPABLE);
335	fcntlrights = 0;
336	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
337	CHECK(fcntlrights == CAP_FCNTL_GETFL);
338	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == 0);
339	fcntlrights = 0;
340	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
341	CHECK(fcntlrights == CAP_FCNTL_GETFL);
342
343	CHECK(fcntl(fd, F_GETFD) == 0);
344	CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
345	CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
346	CHECK(fcntl(fd, F_SETFD, 0) == 0);
347	CHECK(fcntl(fd, F_GETFD) == 0);
348
349	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
350	errno = 0;
351	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1);
352	CHECK(errno == ENOTCAPABLE);
353	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
354	errno = 0;
355	CHECK(fcntl(fd, F_SETFL, 0) == -1);
356	CHECK(errno == ENOTCAPABLE);
357	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
358
359	CHECK(close(fd) == 0);
360
361	CHECK(descriptor_recv(sock, &fd) == 0);
362
363	fcntlrights = 0;
364	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
365	CHECK(fcntlrights == 0);
366	errno = 0;
367	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1);
368	CHECK(errno == ENOTCAPABLE);
369	fcntlrights = 0;
370	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
371	CHECK(fcntlrights == 0);
372	errno = 0;
373	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == -1);
374	CHECK(errno == ENOTCAPABLE);
375	fcntlrights = 0;
376	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
377	CHECK(fcntlrights == 0);
378	errno = 0;
379	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_SETFL) == -1);
380	CHECK(errno == ENOTCAPABLE);
381	fcntlrights = 0;
382	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
383	CHECK(fcntlrights == 0);
384
385	CHECK(fcntl(fd, F_GETFD) == 0);
386	CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
387	CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
388	CHECK(fcntl(fd, F_SETFD, 0) == 0);
389	CHECK(fcntl(fd, F_GETFD) == 0);
390
391	errno = 0;
392	CHECK(fcntl(fd, F_GETFL) == -1);
393	CHECK(errno == ENOTCAPABLE);
394	errno = 0;
395	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1);
396	CHECK(errno == ENOTCAPABLE);
397	errno = 0;
398	CHECK(fcntl(fd, F_SETFL, 0) == -1);
399	CHECK(errno == ENOTCAPABLE);
400	errno = 0;
401	CHECK(fcntl(fd, F_GETFL) == -1);
402	CHECK(errno == ENOTCAPABLE);
403
404	CHECK(close(fd) == 0);
405}
406
407int
408main(void)
409{
410	int fd, pfd, sp[2];
411	pid_t pid;
412
413	printf("1..870\n");
414
415	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
416	fcntl_tests_0(fd);
417	CHECK(close(fd) == 0);
418
419	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
420	fcntl_tests_1(fd);
421	CHECK(close(fd) == 0);
422
423	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
424	fcntl_tests_2(fd);
425	CHECK(close(fd) == 0);
426
427	/* Child inherits descriptor and operates on it first. */
428	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
429	CHECK((pid = fork()) >= 0);
430	if (pid == 0) {
431		fcntl_tests_0(fd);
432		CHECK(close(fd) == 0);
433		exit(0);
434	} else {
435		CHECK(waitpid(pid, NULL, 0) == pid);
436		fcntl_tests_0(fd);
437	}
438	CHECK(close(fd) == 0);
439
440	/* Child inherits descriptor, but operates on it after parent. */
441	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
442	CHECK((pid = fork()) >= 0);
443	if (pid == 0) {
444		sleep(1);
445		fcntl_tests_0(fd);
446		CHECK(close(fd) == 0);
447		exit(0);
448	} else {
449		fcntl_tests_0(fd);
450		CHECK(waitpid(pid, NULL, 0) == pid);
451	}
452	CHECK(close(fd) == 0);
453
454	/* Child inherits descriptor and operates on it first. */
455	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
456	CHECK((pid = pdfork(&pfd, 0)) >= 0);
457	if (pid == 0) {
458		fcntl_tests_1(fd);
459		exit(0);
460	} else {
461		CHECK(pdwait(pfd) == 0);
462/*
463		It fails with EBADF, which I believe is a bug.
464		CHECK(close(pfd) == 0);
465*/
466		fcntl_tests_1(fd);
467	}
468	CHECK(close(fd) == 0);
469
470	/* Child inherits descriptor, but operates on it after parent. */
471	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
472	CHECK((pid = pdfork(&pfd, 0)) >= 0);
473	if (pid == 0) {
474		sleep(1);
475		fcntl_tests_1(fd);
476		exit(0);
477	} else {
478		fcntl_tests_1(fd);
479		CHECK(pdwait(pfd) == 0);
480/*
481		It fails with EBADF, which I believe is a bug.
482		CHECK(close(pfd) == 0);
483*/
484	}
485	CHECK(close(fd) == 0);
486
487	/* Child inherits descriptor and operates on it first. */
488	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
489	CHECK((pid = fork()) >= 0);
490	if (pid == 0) {
491		fcntl_tests_2(fd);
492		exit(0);
493	} else {
494		CHECK(waitpid(pid, NULL, 0) == pid);
495		fcntl_tests_2(fd);
496	}
497	CHECK(close(fd) == 0);
498
499	/* Child inherits descriptor, but operates on it after parent. */
500	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
501	CHECK((pid = fork()) >= 0);
502	if (pid == 0) {
503		sleep(1);
504		fcntl_tests_2(fd);
505		exit(0);
506	} else {
507		fcntl_tests_2(fd);
508		CHECK(waitpid(pid, NULL, 0) == pid);
509	}
510	CHECK(close(fd) == 0);
511
512	/* Send descriptors from parent to child. */
513	CHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, sp) == 0);
514	CHECK((pid = fork()) >= 0);
515	if (pid == 0) {
516		CHECK(close(sp[0]) == 0);
517		fcntl_tests_recv_0(sp[1]);
518		CHECK(close(sp[1]) == 0);
519		exit(0);
520	} else {
521		CHECK(close(sp[1]) == 0);
522		fcntl_tests_send_0(sp[0]);
523		CHECK(waitpid(pid, NULL, 0) == pid);
524		CHECK(close(sp[0]) == 0);
525	}
526
527	/* Send descriptors from child to parent. */
528	CHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, sp) == 0);
529	CHECK((pid = fork()) >= 0);
530	if (pid == 0) {
531		CHECK(close(sp[0]) == 0);
532		fcntl_tests_send_0(sp[1]);
533		CHECK(close(sp[1]) == 0);
534		exit(0);
535	} else {
536		CHECK(close(sp[1]) == 0);
537		fcntl_tests_recv_0(sp[0]);
538		CHECK(waitpid(pid, NULL, 0) == pid);
539		CHECK(close(sp[0]) == 0);
540	}
541
542	exit(0);
543}
544