1247606Spjd/*-
2247606Spjd * Copyright (c) 2012 The FreeBSD Foundation
3247606Spjd * All rights reserved.
4247606Spjd *
5247606Spjd * This software was developed by Pawel Jakub Dawidek under sponsorship from
6247606Spjd * the FreeBSD Foundation.
7247606Spjd *
8247606Spjd * Redistribution and use in source and binary forms, with or without
9247606Spjd * modification, are permitted provided that the following conditions
10247606Spjd * are met:
11247606Spjd * 1. Redistributions of source code must retain the above copyright
12247606Spjd *    notice, this list of conditions and the following disclaimer.
13247606Spjd * 2. Redistributions in binary form must reproduce the above copyright
14247606Spjd *    notice, this list of conditions and the following disclaimer in the
15247606Spjd *    documentation and/or other materials provided with the distribution.
16247606Spjd *
17247606Spjd * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
18247606Spjd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19247606Spjd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20247606Spjd * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
21247606Spjd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22247606Spjd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23247606Spjd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24247606Spjd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25247606Spjd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26247606Spjd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27247606Spjd * SUCH DAMAGE.
28247606Spjd */
29247606Spjd
30247606Spjd#include <sys/cdefs.h>
31247606Spjd__FBSDID("$FreeBSD$");
32247606Spjd
33247606Spjd#include <sys/types.h>
34263234Srwatson#include <sys/capsicum.h>
35247606Spjd#include <sys/procdesc.h>
36247606Spjd#include <sys/socket.h>
37247606Spjd#include <sys/wait.h>
38247606Spjd
39247606Spjd#include <err.h>
40247606Spjd#include <errno.h>
41247606Spjd#include <stdio.h>
42247606Spjd#include <stdlib.h>
43247606Spjd#include <unistd.h>
44247606Spjd
45247606Spjd#include "misc.h"
46247606Spjd
47247606Spjdstatic void
48247606Spjdfcntl_tests_0(int fd)
49247606Spjd{
50247606Spjd	uint32_t fcntlrights;
51247606Spjd
52247606Spjd	fcntlrights = 0;
53247606Spjd	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
54247606Spjd	CHECK(fcntlrights == CAP_FCNTL_ALL);
55247606Spjd
56247606Spjd	CHECK(fcntl(fd, F_GETFD) == 0);
57247606Spjd	CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
58247606Spjd	CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
59247606Spjd	CHECK(fcntl(fd, F_SETFD, 0) == 0);
60247606Spjd	CHECK(fcntl(fd, F_GETFD) == 0);
61247606Spjd
62247606Spjd	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
63247606Spjd	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == 0);
64247606Spjd	CHECK(fcntl(fd, F_GETFL) == (O_RDWR | O_NONBLOCK));
65247606Spjd	CHECK(fcntl(fd, F_SETFL, 0) == 0);
66247606Spjd	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
67247606Spjd
68247606Spjd	errno = 0;
69247606Spjd	CHECK(cap_fcntls_limit(fd, ~CAP_FCNTL_ALL) == -1);
70247606Spjd	CHECK(errno == EINVAL);
71247606Spjd	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == 0);
72247606Spjd	fcntlrights = 0;
73247606Spjd	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
74247606Spjd	CHECK(fcntlrights == (CAP_FCNTL_GETFL | CAP_FCNTL_SETFL));
75247606Spjd	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == 0);
76247606Spjd	fcntlrights = 0;
77247606Spjd	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
78247606Spjd	CHECK(fcntlrights == (CAP_FCNTL_GETFL | CAP_FCNTL_SETFL));
79247606Spjd
80247606Spjd	CHECK(fcntl(fd, F_GETFD) == 0);
81247606Spjd	CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
82247606Spjd	CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
83247606Spjd	CHECK(fcntl(fd, F_SETFD, 0) == 0);
84247606Spjd	CHECK(fcntl(fd, F_GETFD) == 0);
85247606Spjd
86247606Spjd	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
87247606Spjd	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == 0);
88247606Spjd	CHECK(fcntl(fd, F_GETFL) == (O_RDWR | O_NONBLOCK));
89247606Spjd	CHECK(fcntl(fd, F_SETFL, 0) == 0);
90247606Spjd	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
91247606Spjd
92247606Spjd	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == 0);
93247606Spjd	fcntlrights = 0;
94247606Spjd	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
95247606Spjd	CHECK(fcntlrights == CAP_FCNTL_GETFL);
96247606Spjd	errno = 0;
97247606Spjd	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1);
98247606Spjd	CHECK(errno == ENOTCAPABLE);
99247606Spjd	fcntlrights = 0;
100247606Spjd	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
101247606Spjd	CHECK(fcntlrights == CAP_FCNTL_GETFL);
102247606Spjd
103247606Spjd	CHECK(fcntl(fd, F_GETFD) == 0);
104247606Spjd	CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
105247606Spjd	CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
106247606Spjd	CHECK(fcntl(fd, F_SETFD, 0) == 0);
107247606Spjd	CHECK(fcntl(fd, F_GETFD) == 0);
108247606Spjd
109247606Spjd	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
110247606Spjd	errno = 0;
111247606Spjd	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1);
112247606Spjd	CHECK(errno == ENOTCAPABLE);
113247606Spjd	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
114247606Spjd	errno = 0;
115247606Spjd	CHECK(fcntl(fd, F_SETFL, 0) == -1);
116247606Spjd	CHECK(errno == ENOTCAPABLE);
117247606Spjd	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
118247606Spjd
119247606Spjd	CHECK(cap_fcntls_limit(fd, 0) == 0);
120247606Spjd	fcntlrights = CAP_FCNTL_ALL;
121247606Spjd	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
122247606Spjd	CHECK(fcntlrights == 0);
123247606Spjd	errno = 0;
124247606Spjd	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1);
125247606Spjd	CHECK(errno == ENOTCAPABLE);
126247606Spjd	fcntlrights = CAP_FCNTL_ALL;
127247606Spjd	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
128247606Spjd	CHECK(fcntlrights == 0);
129247606Spjd	errno = 0;
130247606Spjd	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == -1);
131247606Spjd	CHECK(errno == ENOTCAPABLE);
132247606Spjd	fcntlrights = CAP_FCNTL_ALL;
133247606Spjd	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
134247606Spjd	CHECK(fcntlrights == 0);
135247606Spjd
136247606Spjd	CHECK(fcntl(fd, F_GETFD) == 0);
137247606Spjd	CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
138247606Spjd	CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
139247606Spjd	CHECK(fcntl(fd, F_SETFD, 0) == 0);
140247606Spjd	CHECK(fcntl(fd, F_GETFD) == 0);
141247606Spjd
142247606Spjd	errno = 0;
143247606Spjd	CHECK(fcntl(fd, F_GETFL) == -1);
144247606Spjd	CHECK(errno == ENOTCAPABLE);
145247606Spjd	errno = 0;
146247606Spjd	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1);
147247606Spjd	CHECK(errno == ENOTCAPABLE);
148247606Spjd	errno = 0;
149247606Spjd	CHECK(fcntl(fd, F_SETFL, 0) == -1);
150247606Spjd	CHECK(errno == ENOTCAPABLE);
151247606Spjd	errno = 0;
152247606Spjd	CHECK(fcntl(fd, F_GETFL) == -1);
153247606Spjd	CHECK(errno == ENOTCAPABLE);
154247606Spjd}
155247606Spjd
156247606Spjdstatic void
157247606Spjdfcntl_tests_1(int fd)
158247606Spjd{
159247606Spjd	uint32_t fcntlrights;
160247606Spjd
161247606Spjd	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == 0);
162247606Spjd	fcntlrights = 0;
163247606Spjd	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
164247606Spjd	CHECK(fcntlrights == CAP_FCNTL_GETFL);
165247606Spjd
166247606Spjd	CHECK(cap_rights_limit(fd, CAP_ALL & ~CAP_FCNTL) == 0);
167247606Spjd
168247606Spjd	fcntlrights = CAP_FCNTL_ALL;
169247606Spjd	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
170247606Spjd	CHECK(fcntlrights == 0);
171247606Spjd
172247606Spjd	errno = 0;
173247606Spjd	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1);
174247606Spjd	CHECK(errno == ENOTCAPABLE);
175247606Spjd	fcntlrights = CAP_FCNTL_ALL;
176247606Spjd	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
177247606Spjd	CHECK(fcntlrights == 0);
178247606Spjd	errno = 0;
179247606Spjd	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == -1);
180247606Spjd	CHECK(errno == ENOTCAPABLE);
181247606Spjd	fcntlrights = CAP_FCNTL_ALL;
182247606Spjd	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
183247606Spjd	CHECK(fcntlrights == 0);
184247606Spjd
185247606Spjd	CHECK(fcntl(fd, F_GETFD) == 0);
186247606Spjd	CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
187247606Spjd	CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
188247606Spjd	CHECK(fcntl(fd, F_SETFD, 0) == 0);
189247606Spjd	CHECK(fcntl(fd, F_GETFD) == 0);
190247606Spjd
191247606Spjd	errno = 0;
192247606Spjd	CHECK(fcntl(fd, F_GETFL) == -1);
193247606Spjd	CHECK(errno == ENOTCAPABLE);
194247606Spjd	errno = 0;
195247606Spjd	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1);
196247606Spjd	CHECK(errno == ENOTCAPABLE);
197247606Spjd	errno = 0;
198247606Spjd	CHECK(fcntl(fd, F_SETFL, 0) == -1);
199247606Spjd	CHECK(errno == ENOTCAPABLE);
200247606Spjd	errno = 0;
201247606Spjd	CHECK(fcntl(fd, F_GETFL) == -1);
202247606Spjd	CHECK(errno == ENOTCAPABLE);
203247606Spjd}
204247606Spjd
205247606Spjdstatic void
206247606Spjdfcntl_tests_2(int fd)
207247606Spjd{
208247606Spjd	uint32_t fcntlrights;
209247606Spjd
210247606Spjd	CHECK(cap_rights_limit(fd, CAP_ALL & ~CAP_FCNTL) == 0);
211247606Spjd
212247606Spjd	fcntlrights = CAP_FCNTL_ALL;
213247606Spjd	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
214247606Spjd	CHECK(fcntlrights == 0);
215247606Spjd
216247606Spjd	errno = 0;
217247606Spjd	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1);
218247606Spjd	CHECK(errno == ENOTCAPABLE);
219247606Spjd	fcntlrights = CAP_FCNTL_ALL;
220247606Spjd	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
221247606Spjd	CHECK(fcntlrights == 0);
222247606Spjd	errno = 0;
223247606Spjd	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == -1);
224247606Spjd	CHECK(errno == ENOTCAPABLE);
225247606Spjd	fcntlrights = CAP_FCNTL_ALL;
226247606Spjd	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
227247606Spjd	CHECK(fcntlrights == 0);
228247606Spjd
229247606Spjd	CHECK(fcntl(fd, F_GETFD) == 0);
230247606Spjd	CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
231247606Spjd	CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
232247606Spjd	CHECK(fcntl(fd, F_SETFD, 0) == 0);
233247606Spjd	CHECK(fcntl(fd, F_GETFD) == 0);
234247606Spjd
235247606Spjd	errno = 0;
236247606Spjd	CHECK(fcntl(fd, F_GETFL) == -1);
237247606Spjd	CHECK(errno == ENOTCAPABLE);
238247606Spjd	errno = 0;
239247606Spjd	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1);
240247606Spjd	CHECK(errno == ENOTCAPABLE);
241247606Spjd	errno = 0;
242247606Spjd	CHECK(fcntl(fd, F_SETFL, 0) == -1);
243247606Spjd	CHECK(errno == ENOTCAPABLE);
244247606Spjd	errno = 0;
245247606Spjd	CHECK(fcntl(fd, F_GETFL) == -1);
246247606Spjd	CHECK(errno == ENOTCAPABLE);
247247606Spjd}
248247606Spjd
249247606Spjdstatic void
250247606Spjdfcntl_tests_send_0(int sock)
251247606Spjd{
252247606Spjd	int fd;
253247606Spjd
254247606Spjd	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
255247606Spjd	CHECK(descriptor_send(sock, fd) == 0);
256247606Spjd	CHECK(close(fd) == 0);
257247606Spjd
258247606Spjd	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
259247606Spjd	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == 0);
260247606Spjd	CHECK(descriptor_send(sock, fd) == 0);
261247606Spjd	CHECK(close(fd) == 0);
262247606Spjd
263247606Spjd	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
264247606Spjd	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == 0);
265247606Spjd	CHECK(descriptor_send(sock, fd) == 0);
266247606Spjd	CHECK(close(fd) == 0);
267247606Spjd
268247606Spjd	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
269247606Spjd	CHECK(cap_fcntls_limit(fd, 0) == 0);
270247606Spjd	CHECK(descriptor_send(sock, fd) == 0);
271247606Spjd	CHECK(close(fd) == 0);
272247606Spjd}
273247606Spjd
274247606Spjdstatic void
275247606Spjdfcntl_tests_recv_0(int sock)
276247606Spjd{
277247606Spjd	uint32_t fcntlrights;
278247606Spjd	int fd;
279247606Spjd
280247606Spjd	CHECK(descriptor_recv(sock, &fd) == 0);
281247606Spjd
282247606Spjd	fcntlrights = 0;
283247606Spjd	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
284247606Spjd	CHECK(fcntlrights == CAP_FCNTL_ALL);
285247606Spjd
286247606Spjd	CHECK(fcntl(fd, F_GETFD) == 0);
287247606Spjd	CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
288247606Spjd	CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
289247606Spjd	CHECK(fcntl(fd, F_SETFD, 0) == 0);
290247606Spjd	CHECK(fcntl(fd, F_GETFD) == 0);
291247606Spjd
292247606Spjd	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
293247606Spjd	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == 0);
294247606Spjd	CHECK(fcntl(fd, F_GETFL) == (O_RDWR | O_NONBLOCK));
295247606Spjd	CHECK(fcntl(fd, F_SETFL, 0) == 0);
296247606Spjd	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
297247606Spjd
298247606Spjd	CHECK(close(fd) == 0);
299247606Spjd
300247606Spjd	CHECK(descriptor_recv(sock, &fd) == 0);
301247606Spjd
302247606Spjd	fcntlrights = 0;
303247606Spjd	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
304247606Spjd	CHECK(fcntlrights == (CAP_FCNTL_GETFL | CAP_FCNTL_SETFL));
305247606Spjd	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == 0);
306247606Spjd	fcntlrights = 0;
307247606Spjd	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
308247606Spjd	CHECK(fcntlrights == (CAP_FCNTL_GETFL | CAP_FCNTL_SETFL));
309247606Spjd
310247606Spjd	CHECK(fcntl(fd, F_GETFD) == 0);
311247606Spjd	CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
312247606Spjd	CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
313247606Spjd	CHECK(fcntl(fd, F_SETFD, 0) == 0);
314247606Spjd	CHECK(fcntl(fd, F_GETFD) == 0);
315247606Spjd
316247606Spjd	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
317247606Spjd	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == 0);
318247606Spjd	CHECK(fcntl(fd, F_GETFL) == (O_RDWR | O_NONBLOCK));
319247606Spjd	CHECK(fcntl(fd, F_SETFL, 0) == 0);
320247606Spjd	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
321247606Spjd
322247606Spjd	CHECK(close(fd) == 0);
323247606Spjd
324247606Spjd	CHECK(descriptor_recv(sock, &fd) == 0);
325247606Spjd
326247606Spjd	fcntlrights = 0;
327247606Spjd	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
328247606Spjd	CHECK(fcntlrights == CAP_FCNTL_GETFL);
329247606Spjd	errno = 0;
330247606Spjd	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1);
331247606Spjd	CHECK(errno == ENOTCAPABLE);
332247606Spjd	fcntlrights = 0;
333247606Spjd	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
334247606Spjd	CHECK(fcntlrights == CAP_FCNTL_GETFL);
335247606Spjd	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == 0);
336247606Spjd	fcntlrights = 0;
337247606Spjd	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
338247606Spjd	CHECK(fcntlrights == CAP_FCNTL_GETFL);
339247606Spjd
340247606Spjd	CHECK(fcntl(fd, F_GETFD) == 0);
341247606Spjd	CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
342247606Spjd	CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
343247606Spjd	CHECK(fcntl(fd, F_SETFD, 0) == 0);
344247606Spjd	CHECK(fcntl(fd, F_GETFD) == 0);
345247606Spjd
346247606Spjd	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
347247606Spjd	errno = 0;
348247606Spjd	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1);
349247606Spjd	CHECK(errno == ENOTCAPABLE);
350247606Spjd	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
351247606Spjd	errno = 0;
352247606Spjd	CHECK(fcntl(fd, F_SETFL, 0) == -1);
353247606Spjd	CHECK(errno == ENOTCAPABLE);
354247606Spjd	CHECK(fcntl(fd, F_GETFL) == O_RDWR);
355247606Spjd
356247606Spjd	CHECK(close(fd) == 0);
357247606Spjd
358247606Spjd	CHECK(descriptor_recv(sock, &fd) == 0);
359247606Spjd
360247606Spjd	fcntlrights = 0;
361247606Spjd	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
362247606Spjd	CHECK(fcntlrights == 0);
363247606Spjd	errno = 0;
364247606Spjd	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL | CAP_FCNTL_SETFL) == -1);
365247606Spjd	CHECK(errno == ENOTCAPABLE);
366247606Spjd	fcntlrights = 0;
367247606Spjd	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
368247606Spjd	CHECK(fcntlrights == 0);
369247606Spjd	errno = 0;
370247606Spjd	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_GETFL) == -1);
371247606Spjd	CHECK(errno == ENOTCAPABLE);
372247606Spjd	fcntlrights = 0;
373247606Spjd	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
374247606Spjd	CHECK(fcntlrights == 0);
375247606Spjd	errno = 0;
376247606Spjd	CHECK(cap_fcntls_limit(fd, CAP_FCNTL_SETFL) == -1);
377247606Spjd	CHECK(errno == ENOTCAPABLE);
378247606Spjd	fcntlrights = 0;
379247606Spjd	CHECK(cap_fcntls_get(fd, &fcntlrights) == 0);
380247606Spjd	CHECK(fcntlrights == 0);
381247606Spjd
382247606Spjd	CHECK(fcntl(fd, F_GETFD) == 0);
383247606Spjd	CHECK(fcntl(fd, F_SETFD, FD_CLOEXEC) == 0);
384247606Spjd	CHECK(fcntl(fd, F_GETFD) == FD_CLOEXEC);
385247606Spjd	CHECK(fcntl(fd, F_SETFD, 0) == 0);
386247606Spjd	CHECK(fcntl(fd, F_GETFD) == 0);
387247606Spjd
388247606Spjd	errno = 0;
389247606Spjd	CHECK(fcntl(fd, F_GETFL) == -1);
390247606Spjd	CHECK(errno == ENOTCAPABLE);
391247606Spjd	errno = 0;
392247606Spjd	CHECK(fcntl(fd, F_SETFL, O_NONBLOCK) == -1);
393247606Spjd	CHECK(errno == ENOTCAPABLE);
394247606Spjd	errno = 0;
395247606Spjd	CHECK(fcntl(fd, F_SETFL, 0) == -1);
396247606Spjd	CHECK(errno == ENOTCAPABLE);
397247606Spjd	errno = 0;
398247606Spjd	CHECK(fcntl(fd, F_GETFL) == -1);
399247606Spjd	CHECK(errno == ENOTCAPABLE);
400247606Spjd
401247606Spjd	CHECK(close(fd) == 0);
402247606Spjd}
403247606Spjd
404247606Spjdint
405247606Spjdmain(void)
406247606Spjd{
407247606Spjd	int fd, pfd, sp[2];
408247606Spjd	pid_t pid;
409247606Spjd
410247606Spjd	printf("1..870\n");
411247606Spjd
412247606Spjd	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
413247606Spjd	fcntl_tests_0(fd);
414247606Spjd	CHECK(close(fd) == 0);
415247606Spjd
416247606Spjd	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
417247606Spjd	fcntl_tests_1(fd);
418247606Spjd	CHECK(close(fd) == 0);
419247606Spjd
420247606Spjd	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
421247606Spjd	fcntl_tests_2(fd);
422247606Spjd	CHECK(close(fd) == 0);
423247606Spjd
424247606Spjd	/* Child inherits descriptor and operates on it first. */
425247606Spjd	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
426247606Spjd	CHECK((pid = fork()) >= 0);
427247606Spjd	if (pid == 0) {
428247606Spjd		fcntl_tests_0(fd);
429247606Spjd		CHECK(close(fd) == 0);
430247606Spjd		exit(0);
431247606Spjd	} else {
432247606Spjd		CHECK(waitpid(pid, NULL, 0) == pid);
433247606Spjd		fcntl_tests_0(fd);
434247606Spjd	}
435247606Spjd	CHECK(close(fd) == 0);
436247606Spjd
437247606Spjd	/* Child inherits descriptor, but operates on it after parent. */
438247606Spjd	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
439247606Spjd	CHECK((pid = fork()) >= 0);
440247606Spjd	if (pid == 0) {
441247606Spjd		sleep(1);
442247606Spjd		fcntl_tests_0(fd);
443247606Spjd		CHECK(close(fd) == 0);
444247606Spjd		exit(0);
445247606Spjd	} else {
446247606Spjd		fcntl_tests_0(fd);
447247606Spjd		CHECK(waitpid(pid, NULL, 0) == pid);
448247606Spjd	}
449247606Spjd	CHECK(close(fd) == 0);
450247606Spjd
451247606Spjd	/* Child inherits descriptor and operates on it first. */
452247606Spjd	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
453247606Spjd	CHECK((pid = pdfork(&pfd, 0)) >= 0);
454247606Spjd	if (pid == 0) {
455247606Spjd		fcntl_tests_1(fd);
456247606Spjd		exit(0);
457247606Spjd	} else {
458247606Spjd		CHECK(pdwait(pfd) == 0);
459247606Spjd/*
460247606Spjd		It fails with EBADF, which I believe is a bug.
461247606Spjd		CHECK(close(pfd) == 0);
462247606Spjd*/
463247606Spjd		fcntl_tests_1(fd);
464247606Spjd	}
465247606Spjd	CHECK(close(fd) == 0);
466247606Spjd
467247606Spjd	/* Child inherits descriptor, but operates on it after parent. */
468247606Spjd	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
469247606Spjd	CHECK((pid = pdfork(&pfd, 0)) >= 0);
470247606Spjd	if (pid == 0) {
471247606Spjd		sleep(1);
472247606Spjd		fcntl_tests_1(fd);
473247606Spjd		exit(0);
474247606Spjd	} else {
475247606Spjd		fcntl_tests_1(fd);
476247606Spjd		CHECK(pdwait(pfd) == 0);
477247606Spjd/*
478247606Spjd		It fails with EBADF, which I believe is a bug.
479247606Spjd		CHECK(close(pfd) == 0);
480247606Spjd*/
481247606Spjd	}
482247606Spjd	CHECK(close(fd) == 0);
483247606Spjd
484247606Spjd	/* Child inherits descriptor and operates on it first. */
485247606Spjd	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
486247606Spjd	CHECK((pid = fork()) >= 0);
487247606Spjd	if (pid == 0) {
488247606Spjd		fcntl_tests_2(fd);
489247606Spjd		exit(0);
490247606Spjd	} else {
491247606Spjd		CHECK(waitpid(pid, NULL, 0) == pid);
492247606Spjd		fcntl_tests_2(fd);
493247606Spjd	}
494247606Spjd	CHECK(close(fd) == 0);
495247606Spjd
496247606Spjd	/* Child inherits descriptor, but operates on it after parent. */
497247606Spjd	CHECK((fd = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0);
498247606Spjd	CHECK((pid = fork()) >= 0);
499247606Spjd	if (pid == 0) {
500247606Spjd		sleep(1);
501247606Spjd		fcntl_tests_2(fd);
502247606Spjd		exit(0);
503247606Spjd	} else {
504247606Spjd		fcntl_tests_2(fd);
505247606Spjd		CHECK(waitpid(pid, NULL, 0) == pid);
506247606Spjd	}
507247606Spjd	CHECK(close(fd) == 0);
508247606Spjd
509247606Spjd	/* Send descriptors from parent to child. */
510247606Spjd	CHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, sp) == 0);
511247606Spjd	CHECK((pid = fork()) >= 0);
512247606Spjd	if (pid == 0) {
513247606Spjd		CHECK(close(sp[0]) == 0);
514247606Spjd		fcntl_tests_recv_0(sp[1]);
515247606Spjd		CHECK(close(sp[1]) == 0);
516247606Spjd		exit(0);
517247606Spjd	} else {
518247606Spjd		CHECK(close(sp[1]) == 0);
519247606Spjd		fcntl_tests_send_0(sp[0]);
520247606Spjd		CHECK(waitpid(pid, NULL, 0) == pid);
521247606Spjd		CHECK(close(sp[0]) == 0);
522247606Spjd	}
523247606Spjd
524247606Spjd	/* Send descriptors from child to parent. */
525247606Spjd	CHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, sp) == 0);
526247606Spjd	CHECK((pid = fork()) >= 0);
527247606Spjd	if (pid == 0) {
528247606Spjd		CHECK(close(sp[0]) == 0);
529247606Spjd		fcntl_tests_send_0(sp[1]);
530247606Spjd		CHECK(close(sp[1]) == 0);
531247606Spjd		exit(0);
532247606Spjd	} else {
533247606Spjd		CHECK(close(sp[1]) == 0);
534247606Spjd		fcntl_tests_recv_0(sp[0]);
535247606Spjd		CHECK(waitpid(pid, NULL, 0) == pid);
536247606Spjd		CHECK(close(sp[0]) == 0);
537247606Spjd	}
538247606Spjd
539247606Spjd	exit(0);
540247606Spjd}
541