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 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
208 static void
fcntl_tests_2(int fd)209 fcntl_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
255 static void
fcntl_tests_send_0(int sock)256 fcntl_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
280 static void
fcntl_tests_recv_0(int sock)281 fcntl_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
410 int
main(void)411 main(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