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
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
205static void
206fcntl_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
249static void
250fcntl_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
274static void
275fcntl_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
404int
405main(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