]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - tools/regression/capsicum/syscalls/cap_fcntls_limit.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / tools / regression / capsicum / syscalls / cap_fcntls_limit.c
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/capability.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
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
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
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
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
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
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 }