xref: /freebsd/tools/regression/sockets/unix_gc/unix_gc.c (revision c8c3fc568f8fc2452af398e08d1f11f001d45a4c)
1c8c3fc56SRobert Watson /*-
2c8c3fc56SRobert Watson  * Copyright (c) 2007 Robert N. M. Watson
3c8c3fc56SRobert Watson  * All rights reserved.
4c8c3fc56SRobert Watson  *
5c8c3fc56SRobert Watson  * Redistribution and use in source and binary forms, with or without
6c8c3fc56SRobert Watson  * modification, are permitted provided that the following conditions
7c8c3fc56SRobert Watson  * are met:
8c8c3fc56SRobert Watson  * 1. Redistributions of source code must retain the above copyright
9c8c3fc56SRobert Watson  *    notice, this list of conditions and the following disclaimer.
10c8c3fc56SRobert Watson  * 2. Redistributions in binary form must reproduce the above copyright
11c8c3fc56SRobert Watson  *    notice, this list of conditions and the following disclaimer in the
12c8c3fc56SRobert Watson  *    documentation and/or other materials provided with the distribution.
13c8c3fc56SRobert Watson  *
14c8c3fc56SRobert Watson  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15c8c3fc56SRobert Watson  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16c8c3fc56SRobert Watson  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17c8c3fc56SRobert Watson  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18c8c3fc56SRobert Watson  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19c8c3fc56SRobert Watson  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20c8c3fc56SRobert Watson  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21c8c3fc56SRobert Watson  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22c8c3fc56SRobert Watson  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23c8c3fc56SRobert Watson  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24c8c3fc56SRobert Watson  * SUCH DAMAGE.
25c8c3fc56SRobert Watson  *
26c8c3fc56SRobert Watson  * $FreeBSD$
27c8c3fc56SRobert Watson  */
28c8c3fc56SRobert Watson 
29c8c3fc56SRobert Watson /*
30c8c3fc56SRobert Watson  * A few regression tests for UNIX domain sockets.  Run from single-user mode
31c8c3fc56SRobert Watson  * as it checks the openfiles sysctl to look for leaks, and we don't want that
32c8c3fc56SRobert Watson  * changing due to other processes doing stuff.
33c8c3fc56SRobert Watson  */
34c8c3fc56SRobert Watson 
35c8c3fc56SRobert Watson #include <sys/types.h>
36c8c3fc56SRobert Watson #include <sys/signal.h>
37c8c3fc56SRobert Watson #include <sys/socket.h>
38c8c3fc56SRobert Watson #include <sys/sysctl.h>
39c8c3fc56SRobert Watson #include <sys/un.h>
40c8c3fc56SRobert Watson #include <sys/wait.h>
41c8c3fc56SRobert Watson 
42c8c3fc56SRobert Watson #include <netinet/in.h>
43c8c3fc56SRobert Watson 
44c8c3fc56SRobert Watson #include <err.h>
45c8c3fc56SRobert Watson #include <errno.h>
46c8c3fc56SRobert Watson #include <fcntl.h>
47c8c3fc56SRobert Watson #include <limits.h>
48c8c3fc56SRobert Watson #include <stdio.h>
49c8c3fc56SRobert Watson #include <stdlib.h>
50c8c3fc56SRobert Watson #include <string.h>
51c8c3fc56SRobert Watson #include <unistd.h>
52c8c3fc56SRobert Watson 
53c8c3fc56SRobert Watson static int forcegc = 1;
54c8c3fc56SRobert Watson static char dpath[PATH_MAX];
55c8c3fc56SRobert Watson static const char *test;
56c8c3fc56SRobert Watson 
57c8c3fc56SRobert Watson static int
58c8c3fc56SRobert Watson getopenfiles(void)
59c8c3fc56SRobert Watson {
60c8c3fc56SRobert Watson 	size_t len;
61c8c3fc56SRobert Watson 	int i;
62c8c3fc56SRobert Watson 
63c8c3fc56SRobert Watson 	len = sizeof(i);
64c8c3fc56SRobert Watson 	if (sysctlbyname("kern.openfiles", &i, &len, NULL, 0) < 0)
65c8c3fc56SRobert Watson 		err(-1, "kern.openfiles");
66c8c3fc56SRobert Watson 	return (i);
67c8c3fc56SRobert Watson }
68c8c3fc56SRobert Watson 
69c8c3fc56SRobert Watson static int
70c8c3fc56SRobert Watson getinflight(void)
71c8c3fc56SRobert Watson {
72c8c3fc56SRobert Watson 	size_t len;
73c8c3fc56SRobert Watson 	int i;
74c8c3fc56SRobert Watson 
75c8c3fc56SRobert Watson 	len = sizeof(i);
76c8c3fc56SRobert Watson 	if (sysctlbyname("net.local.inflight", &i, &len, NULL, 0) < 0)
77c8c3fc56SRobert Watson 		err(-1, "net.local.inflight");
78c8c3fc56SRobert Watson 	return (i);
79c8c3fc56SRobert Watson }
80c8c3fc56SRobert Watson 
81c8c3fc56SRobert Watson static void
82c8c3fc56SRobert Watson sendfd(int fd, int fdtosend)
83c8c3fc56SRobert Watson {
84c8c3fc56SRobert Watson 	struct msghdr mh;
85c8c3fc56SRobert Watson 	struct message { struct cmsghdr msg_hdr; int fd; } m;
86c8c3fc56SRobert Watson 	ssize_t len;
87c8c3fc56SRobert Watson 	int after_inflight, before_inflight;
88c8c3fc56SRobert Watson 
89c8c3fc56SRobert Watson 	before_inflight = getinflight();
90c8c3fc56SRobert Watson 
91c8c3fc56SRobert Watson 	bzero(&mh, sizeof(mh));
92c8c3fc56SRobert Watson 	bzero(&m, sizeof(m));
93c8c3fc56SRobert Watson 	mh.msg_control = &m;
94c8c3fc56SRobert Watson 	mh.msg_controllen = sizeof(m);
95c8c3fc56SRobert Watson 	m.msg_hdr.cmsg_len = sizeof(m);
96c8c3fc56SRobert Watson 	m.msg_hdr.cmsg_level = SOL_SOCKET;
97c8c3fc56SRobert Watson 	m.msg_hdr.cmsg_type = SCM_RIGHTS;
98c8c3fc56SRobert Watson 	m.fd = fdtosend;
99c8c3fc56SRobert Watson 	len = sendmsg(fd, &mh, 0);
100c8c3fc56SRobert Watson 	if (len < 0)
101c8c3fc56SRobert Watson 		err(-1, "%s: sendmsg", test);
102c8c3fc56SRobert Watson 	after_inflight = getinflight();
103c8c3fc56SRobert Watson 	if (after_inflight != before_inflight + 1)
104c8c3fc56SRobert Watson 		errx(-1, "%s: sendfd: before %d after %d\n", test,
105c8c3fc56SRobert Watson 		    before_inflight, after_inflight);
106c8c3fc56SRobert Watson }
107c8c3fc56SRobert Watson 
108c8c3fc56SRobert Watson static void
109c8c3fc56SRobert Watson close2(int fd1, int fd2)
110c8c3fc56SRobert Watson {
111c8c3fc56SRobert Watson 
112c8c3fc56SRobert Watson 	close(fd1);
113c8c3fc56SRobert Watson 	close(fd2);
114c8c3fc56SRobert Watson }
115c8c3fc56SRobert Watson 
116c8c3fc56SRobert Watson static void
117c8c3fc56SRobert Watson close3(int fd1, int fd2, int fd3)
118c8c3fc56SRobert Watson {
119c8c3fc56SRobert Watson 
120c8c3fc56SRobert Watson 	close2(fd1, fd2);
121c8c3fc56SRobert Watson 	close(fd3);
122c8c3fc56SRobert Watson }
123c8c3fc56SRobert Watson 
124c8c3fc56SRobert Watson static void
125c8c3fc56SRobert Watson close4(int fd1, int fd2, int fd3, int fd4)
126c8c3fc56SRobert Watson {
127c8c3fc56SRobert Watson 
128c8c3fc56SRobert Watson 	close2(fd1, fd2);
129c8c3fc56SRobert Watson 	close2(fd3, fd4);
130c8c3fc56SRobert Watson }
131c8c3fc56SRobert Watson 
132c8c3fc56SRobert Watson static void
133c8c3fc56SRobert Watson close5(int fd1, int fd2, int fd3, int fd4, int fd5)
134c8c3fc56SRobert Watson {
135c8c3fc56SRobert Watson 
136c8c3fc56SRobert Watson 	close3(fd1, fd2, fd3);
137c8c3fc56SRobert Watson 	close2(fd4, fd5);
138c8c3fc56SRobert Watson }
139c8c3fc56SRobert Watson 
140c8c3fc56SRobert Watson static int
141c8c3fc56SRobert Watson my_socket(int domain, int type, int proto)
142c8c3fc56SRobert Watson {
143c8c3fc56SRobert Watson 	int sock;
144c8c3fc56SRobert Watson 
145c8c3fc56SRobert Watson 	sock = socket(domain, type, proto);
146c8c3fc56SRobert Watson 	if (sock < 0)
147c8c3fc56SRobert Watson 		err(-1, "%s: socket", test);
148c8c3fc56SRobert Watson 	return (sock);
149c8c3fc56SRobert Watson }
150c8c3fc56SRobert Watson 
151c8c3fc56SRobert Watson static void
152c8c3fc56SRobert Watson my_bind(int sock, struct sockaddr *sa, socklen_t len)
153c8c3fc56SRobert Watson {
154c8c3fc56SRobert Watson 
155c8c3fc56SRobert Watson 	if (bind(sock, sa, len) < 0)
156c8c3fc56SRobert Watson 		err(-1, "%s: bind", test);
157c8c3fc56SRobert Watson }
158c8c3fc56SRobert Watson 
159c8c3fc56SRobert Watson static void
160c8c3fc56SRobert Watson my_connect(int sock, struct sockaddr *sa, socklen_t len)
161c8c3fc56SRobert Watson {
162c8c3fc56SRobert Watson 
163c8c3fc56SRobert Watson 	if (connect(sock, sa, len) < 0)
164c8c3fc56SRobert Watson 		err(-1, "%s: connect", test);
165c8c3fc56SRobert Watson }
166c8c3fc56SRobert Watson 
167c8c3fc56SRobert Watson static void
168c8c3fc56SRobert Watson my_listen(int sock, int backlog)
169c8c3fc56SRobert Watson {
170c8c3fc56SRobert Watson 
171c8c3fc56SRobert Watson 	if (listen(sock, backlog) < 0)
172c8c3fc56SRobert Watson 		err(-1, "%s: listen", test);
173c8c3fc56SRobert Watson }
174c8c3fc56SRobert Watson 
175c8c3fc56SRobert Watson static void
176c8c3fc56SRobert Watson my_socketpair(int *sv)
177c8c3fc56SRobert Watson {
178c8c3fc56SRobert Watson 
179c8c3fc56SRobert Watson 	if (socketpair(PF_UNIX, SOCK_STREAM, 0, sv) < 0)
180c8c3fc56SRobert Watson 		err(-1, "%s: socketpair", test);
181c8c3fc56SRobert Watson }
182c8c3fc56SRobert Watson 
183c8c3fc56SRobert Watson static void
184c8c3fc56SRobert Watson my_getsockname(int s, struct sockaddr *sa, socklen_t *salen)
185c8c3fc56SRobert Watson {
186c8c3fc56SRobert Watson 
187c8c3fc56SRobert Watson 	if (getsockname(s, sa, salen) < 0)
188c8c3fc56SRobert Watson 		err(-1, "%s: getsockname", test);
189c8c3fc56SRobert Watson }
190c8c3fc56SRobert Watson 
191c8c3fc56SRobert Watson static void
192c8c3fc56SRobert Watson setnonblock(int s)
193c8c3fc56SRobert Watson {
194c8c3fc56SRobert Watson 
195c8c3fc56SRobert Watson 	if (fcntl(s, F_SETFL, O_NONBLOCK) < 0)
196c8c3fc56SRobert Watson 		err(-1, "%s: fcntl(F_SETFL, O_NONBLOCK)", test);
197c8c3fc56SRobert Watson }
198c8c3fc56SRobert Watson 
199c8c3fc56SRobert Watson static void
200c8c3fc56SRobert Watson alloc3fds(int *s, int *sv)
201c8c3fc56SRobert Watson {
202c8c3fc56SRobert Watson 
203c8c3fc56SRobert Watson 	if ((*s = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
204c8c3fc56SRobert Watson 		err(-1, "%s: socket", test);
205c8c3fc56SRobert Watson 	if (socketpair(PF_UNIX, SOCK_STREAM, 0, sv) < 0)
206c8c3fc56SRobert Watson 		err(-1, "%s: socketpair", test);
207c8c3fc56SRobert Watson }
208c8c3fc56SRobert Watson 
209c8c3fc56SRobert Watson static void
210c8c3fc56SRobert Watson alloc5fds(int *s, int *sva, int *svb)
211c8c3fc56SRobert Watson {
212c8c3fc56SRobert Watson 
213c8c3fc56SRobert Watson 	if ((*s = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
214c8c3fc56SRobert Watson 		err(-1, "%s: socket", test);
215c8c3fc56SRobert Watson 	if (socketpair(PF_UNIX, SOCK_STREAM, 0, sva) < 0)
216c8c3fc56SRobert Watson 		err(-1, "%s: socketpair", test);
217c8c3fc56SRobert Watson 	if (socketpair(PF_UNIX, SOCK_STREAM, 0, svb) < 0)
218c8c3fc56SRobert Watson 		err(-1, "%s: socketpair", test);
219c8c3fc56SRobert Watson }
220c8c3fc56SRobert Watson 
221c8c3fc56SRobert Watson static void
222c8c3fc56SRobert Watson save_sysctls(int *before_inflight, int *before_openfiles)
223c8c3fc56SRobert Watson {
224c8c3fc56SRobert Watson 
225c8c3fc56SRobert Watson 	*before_inflight = getinflight();
226c8c3fc56SRobert Watson 	*before_openfiles = getopenfiles();
227c8c3fc56SRobert Watson }
228c8c3fc56SRobert Watson 
229c8c3fc56SRobert Watson /*
230c8c3fc56SRobert Watson  * Try hard to make sure that the GC does in fact run before we test the
231c8c3fc56SRobert Watson  * condition of things.
232c8c3fc56SRobert Watson  */
233c8c3fc56SRobert Watson static void
234c8c3fc56SRobert Watson trigger_gc(void)
235c8c3fc56SRobert Watson {
236c8c3fc56SRobert Watson 	int s;
237c8c3fc56SRobert Watson 
238c8c3fc56SRobert Watson 	if (forcegc) {
239c8c3fc56SRobert Watson 		if ((s = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
240c8c3fc56SRobert Watson 			err(-1, "trigger_gc: socket");
241c8c3fc56SRobert Watson 		close(s);
242c8c3fc56SRobert Watson 	}
243c8c3fc56SRobert Watson 	sleep(1);
244c8c3fc56SRobert Watson }
245c8c3fc56SRobert Watson 
246c8c3fc56SRobert Watson static void
247c8c3fc56SRobert Watson test_sysctls(int before_inflight, int before_openfiles)
248c8c3fc56SRobert Watson {
249c8c3fc56SRobert Watson 	int after_inflight, after_openfiles;
250c8c3fc56SRobert Watson 
251c8c3fc56SRobert Watson 	trigger_gc();
252c8c3fc56SRobert Watson 	after_inflight = getinflight();
253c8c3fc56SRobert Watson 	if (after_inflight != before_inflight)
254c8c3fc56SRobert Watson 		warnx("%s: before inflight: %d, after inflight: %d",
255c8c3fc56SRobert Watson 		    test, before_inflight, after_inflight);
256c8c3fc56SRobert Watson 
257c8c3fc56SRobert Watson 	after_openfiles = getopenfiles();
258c8c3fc56SRobert Watson 	if (after_openfiles != before_openfiles)
259c8c3fc56SRobert Watson 		warnx("%s: before: %d, after: %d", test, before_openfiles,
260c8c3fc56SRobert Watson 		    after_openfiles);
261c8c3fc56SRobert Watson }
262c8c3fc56SRobert Watson 
263c8c3fc56SRobert Watson static void
264c8c3fc56SRobert Watson twosome_nothing(void)
265c8c3fc56SRobert Watson {
266c8c3fc56SRobert Watson 	int inflight, openfiles;
267c8c3fc56SRobert Watson 	int sv[2];
268c8c3fc56SRobert Watson 
269c8c3fc56SRobert Watson 	/*
270c8c3fc56SRobert Watson 	 * Create a pair, close in one order.
271c8c3fc56SRobert Watson 	 */
272c8c3fc56SRobert Watson 	test = "twosome_nothing1";
273c8c3fc56SRobert Watson 	printf("%s\n", test);
274c8c3fc56SRobert Watson 	save_sysctls(&inflight, &openfiles);
275c8c3fc56SRobert Watson 	my_socketpair(sv);
276c8c3fc56SRobert Watson 	close2(sv[0], sv[1]);
277c8c3fc56SRobert Watson 	test_sysctls(inflight, openfiles);
278c8c3fc56SRobert Watson 
279c8c3fc56SRobert Watson 	/*
280c8c3fc56SRobert Watson 	 * Create a pair, close in the other order.
281c8c3fc56SRobert Watson 	 */
282c8c3fc56SRobert Watson 	test = "twosome_nothing2";
283c8c3fc56SRobert Watson 	printf("%s\n", test);
284c8c3fc56SRobert Watson 	save_sysctls(&inflight, &openfiles);
285c8c3fc56SRobert Watson 	my_socketpair(sv);
286c8c3fc56SRobert Watson 	close2(sv[0], sv[1]);
287c8c3fc56SRobert Watson 	test_sysctls(inflight, openfiles);
288c8c3fc56SRobert Watson }
289c8c3fc56SRobert Watson 
290c8c3fc56SRobert Watson /*
291c8c3fc56SRobert Watson  * Using a socket pair, send various endpoints over the pair and close in
292c8c3fc56SRobert Watson  * various orders.
293c8c3fc56SRobert Watson  */
294c8c3fc56SRobert Watson static void
295c8c3fc56SRobert Watson twosome_drop_work(const char *testname, int sendvia, int tosend, int closefirst)
296c8c3fc56SRobert Watson {
297c8c3fc56SRobert Watson 	int inflight, openfiles;
298c8c3fc56SRobert Watson 	int sv[2];
299c8c3fc56SRobert Watson 
300c8c3fc56SRobert Watson 	printf("%s\n", testname);
301c8c3fc56SRobert Watson 	test = testname;
302c8c3fc56SRobert Watson 	save_sysctls(&inflight, &openfiles);
303c8c3fc56SRobert Watson 	my_socketpair(sv);
304c8c3fc56SRobert Watson 	sendfd(sv[sendvia], sv[tosend]);
305c8c3fc56SRobert Watson 	if (closefirst == 0)
306c8c3fc56SRobert Watson 		close2(sv[0], sv[1]);
307c8c3fc56SRobert Watson 	else
308c8c3fc56SRobert Watson 		close2(sv[1], sv[0]);
309c8c3fc56SRobert Watson 	test_sysctls(inflight, openfiles);
310c8c3fc56SRobert Watson }
311c8c3fc56SRobert Watson 
312c8c3fc56SRobert Watson static void
313c8c3fc56SRobert Watson twosome_drop(void)
314c8c3fc56SRobert Watson {
315c8c3fc56SRobert Watson 
316c8c3fc56SRobert Watson 	/*
317c8c3fc56SRobert Watson 	 * In various combations, some wastefully symmetric, create socket
318c8c3fc56SRobert Watson 	 * pairs and send one or another endpoint over one or another
319c8c3fc56SRobert Watson 	 * endpoint, closing the endpoints in various orders.
320c8c3fc56SRobert Watson 	 */
321c8c3fc56SRobert Watson 	twosome_drop_work("twosome_drop1", 0, 0, 0);
322c8c3fc56SRobert Watson 	twosome_drop_work("twosome_drop2", 0, 0, 1);
323c8c3fc56SRobert Watson 	twosome_drop_work("twosome_drop3", 0, 1, 0);
324c8c3fc56SRobert Watson 	twosome_drop_work("twosome_drop4", 0, 1, 1);
325c8c3fc56SRobert Watson 	twosome_drop_work("twosome_drop5", 1, 0, 0);
326c8c3fc56SRobert Watson 	twosome_drop_work("twosome_drop6", 1, 0, 1);
327c8c3fc56SRobert Watson 	twosome_drop_work("twosome_drop7", 1, 1, 0);
328c8c3fc56SRobert Watson 	twosome_drop_work("twosome_drop8", 1, 1, 1);
329c8c3fc56SRobert Watson }
330c8c3fc56SRobert Watson 
331c8c3fc56SRobert Watson static void
332c8c3fc56SRobert Watson threesome_nothing(void)
333c8c3fc56SRobert Watson {
334c8c3fc56SRobert Watson 	int inflight, openfiles;
335c8c3fc56SRobert Watson 	int s, sv[2];
336c8c3fc56SRobert Watson 
337c8c3fc56SRobert Watson 	test = "threesome_nothing";
338c8c3fc56SRobert Watson 	printf("%s\n", test);
339c8c3fc56SRobert Watson 	save_sysctls(&inflight, &openfiles);
340c8c3fc56SRobert Watson 	alloc3fds(&s, sv);
341c8c3fc56SRobert Watson 	close3(s, sv[0], sv[1]);
342c8c3fc56SRobert Watson 	test_sysctls(inflight, openfiles);
343c8c3fc56SRobert Watson }
344c8c3fc56SRobert Watson 
345c8c3fc56SRobert Watson /*
346c8c3fc56SRobert Watson  * threesome_drop: create a pair and a spare, send the spare over the pair, and
347c8c3fc56SRobert Watson  * close in various orders and make sure all the fds went away.
348c8c3fc56SRobert Watson  */
349c8c3fc56SRobert Watson static void
350c8c3fc56SRobert Watson threesome_drop(void)
351c8c3fc56SRobert Watson {
352c8c3fc56SRobert Watson 	int inflight, openfiles;
353c8c3fc56SRobert Watson 	int s, sv[2];
354c8c3fc56SRobert Watson 
355c8c3fc56SRobert Watson 	/*
356c8c3fc56SRobert Watson 	 * threesome_drop1: close sent send receive
357c8c3fc56SRobert Watson 	 */
358c8c3fc56SRobert Watson 	test = "threesome_drop1";
359c8c3fc56SRobert Watson 	printf("%s\n", test);
360c8c3fc56SRobert Watson 	save_sysctls(&inflight, &openfiles);
361c8c3fc56SRobert Watson 	alloc3fds(&s, sv);
362c8c3fc56SRobert Watson 	sendfd(sv[0], s);
363c8c3fc56SRobert Watson 	close3(s, sv[0], sv[1]);
364c8c3fc56SRobert Watson 	test_sysctls(inflight, openfiles);
365c8c3fc56SRobert Watson 
366c8c3fc56SRobert Watson 	/*
367c8c3fc56SRobert Watson 	 * threesome_drop2: close sent receive send
368c8c3fc56SRobert Watson 	 */
369c8c3fc56SRobert Watson 	test = "threesome_drop2";
370c8c3fc56SRobert Watson 	printf("%s\n", test);
371c8c3fc56SRobert Watson 	save_sysctls(&inflight, &openfiles);
372c8c3fc56SRobert Watson 	alloc3fds(&s, sv);
373c8c3fc56SRobert Watson 	sendfd(sv[0], s);
374c8c3fc56SRobert Watson 	close3(s, sv[1], sv[0]);
375c8c3fc56SRobert Watson 	test_sysctls(inflight, openfiles);
376c8c3fc56SRobert Watson 
377c8c3fc56SRobert Watson 	/*
378c8c3fc56SRobert Watson 	 * threesome_drop3: close receive sent send
379c8c3fc56SRobert Watson 	 */
380c8c3fc56SRobert Watson 	test = "threesome_drop3";
381c8c3fc56SRobert Watson 	printf("%s\n", test);
382c8c3fc56SRobert Watson 	save_sysctls(&inflight, &openfiles);
383c8c3fc56SRobert Watson 	alloc3fds(&s, sv);
384c8c3fc56SRobert Watson 	sendfd(sv[0], s);
385c8c3fc56SRobert Watson 	close3(sv[1], s, sv[0]);
386c8c3fc56SRobert Watson 	test_sysctls(inflight, openfiles);
387c8c3fc56SRobert Watson 
388c8c3fc56SRobert Watson 	/*
389c8c3fc56SRobert Watson 	 * threesome_drop4: close receive send sent
390c8c3fc56SRobert Watson 	 */
391c8c3fc56SRobert Watson 	test = "threesome_drop4";
392c8c3fc56SRobert Watson 	printf("%s\n", test);
393c8c3fc56SRobert Watson 	save_sysctls(&inflight, &openfiles);
394c8c3fc56SRobert Watson 	alloc3fds(&s, sv);
395c8c3fc56SRobert Watson 	sendfd(sv[0], s);
396c8c3fc56SRobert Watson 	close3(sv[1], sv[0], s);
397c8c3fc56SRobert Watson 	test_sysctls(inflight, openfiles);
398c8c3fc56SRobert Watson 
399c8c3fc56SRobert Watson 	/*
400c8c3fc56SRobert Watson 	 * threesome_drop5: close send receive sent
401c8c3fc56SRobert Watson 	 */
402c8c3fc56SRobert Watson 	test = "threesome_drop5";
403c8c3fc56SRobert Watson 	printf("%s\n", test);
404c8c3fc56SRobert Watson 	save_sysctls(&inflight, &openfiles);
405c8c3fc56SRobert Watson 	alloc3fds(&s, sv);
406c8c3fc56SRobert Watson 	sendfd(sv[0], s);
407c8c3fc56SRobert Watson 	close3(sv[0], sv[1], s);
408c8c3fc56SRobert Watson 	test_sysctls(inflight, openfiles);
409c8c3fc56SRobert Watson 
410c8c3fc56SRobert Watson 	/*
411c8c3fc56SRobert Watson 	 * threesome_drop6: close send sent receive
412c8c3fc56SRobert Watson 	 */
413c8c3fc56SRobert Watson 	test = "threesome_drop6";
414c8c3fc56SRobert Watson 	printf("%s\n", test);
415c8c3fc56SRobert Watson 	save_sysctls(&inflight, &openfiles);
416c8c3fc56SRobert Watson 	alloc3fds(&s, sv);
417c8c3fc56SRobert Watson 	close3(sv[0], s, sv[1]);
418c8c3fc56SRobert Watson 	test_sysctls(inflight, openfiles);
419c8c3fc56SRobert Watson }
420c8c3fc56SRobert Watson 
421c8c3fc56SRobert Watson /*
422c8c3fc56SRobert Watson  * Fivesome tests: create two socket pairs and a spare, send the spare over
423c8c3fc56SRobert Watson  * the first socket pair, then send the first socket pair over the second
424c8c3fc56SRobert Watson  * socket pair, and GC.  Do various closes at various points to exercise
425c8c3fc56SRobert Watson  * various cases.
426c8c3fc56SRobert Watson  */
427c8c3fc56SRobert Watson static void
428c8c3fc56SRobert Watson fivesome_nothing(void)
429c8c3fc56SRobert Watson {
430c8c3fc56SRobert Watson 	int inflight, openfiles;
431c8c3fc56SRobert Watson 	int spare, sva[2], svb[2];
432c8c3fc56SRobert Watson 
433c8c3fc56SRobert Watson 	test = "fivesome_nothing";
434c8c3fc56SRobert Watson 	printf("%s\n", test);
435c8c3fc56SRobert Watson 	save_sysctls(&inflight, &openfiles);
436c8c3fc56SRobert Watson 	alloc5fds(&spare, sva, svb);
437c8c3fc56SRobert Watson 	close5(spare, sva[0], sva[1], svb[0], svb[1]);
438c8c3fc56SRobert Watson 	test_sysctls(inflight, openfiles);
439c8c3fc56SRobert Watson }
440c8c3fc56SRobert Watson 
441c8c3fc56SRobert Watson static void
442c8c3fc56SRobert Watson fivesome_drop_work(const char *testname, int close_spare_after_send,
443c8c3fc56SRobert Watson     int close_sva_after_send)
444c8c3fc56SRobert Watson {
445c8c3fc56SRobert Watson 	int inflight, openfiles;
446c8c3fc56SRobert Watson 	int spare, sva[2], svb[2];
447c8c3fc56SRobert Watson 
448c8c3fc56SRobert Watson 	printf("%s\n", testname);
449c8c3fc56SRobert Watson 	test = testname;
450c8c3fc56SRobert Watson 	save_sysctls(&inflight, &openfiles);
451c8c3fc56SRobert Watson 	alloc5fds(&spare, sva, svb);
452c8c3fc56SRobert Watson 
453c8c3fc56SRobert Watson 	/*
454c8c3fc56SRobert Watson 	 * Send spare over sva.
455c8c3fc56SRobert Watson 	 */
456c8c3fc56SRobert Watson 	sendfd(sva[0], spare);
457c8c3fc56SRobert Watson 	if (close_spare_after_send)
458c8c3fc56SRobert Watson 		close(spare);
459c8c3fc56SRobert Watson 
460c8c3fc56SRobert Watson 	/*
461c8c3fc56SRobert Watson 	 * Send sva over svb.
462c8c3fc56SRobert Watson 	 */
463c8c3fc56SRobert Watson 	sendfd(svb[0], sva[0]);
464c8c3fc56SRobert Watson 	sendfd(svb[0], sva[1]);
465c8c3fc56SRobert Watson 	if (close_sva_after_send)
466c8c3fc56SRobert Watson 		close2(sva[0], sva[1]);
467c8c3fc56SRobert Watson 
468c8c3fc56SRobert Watson 	close2(svb[0], svb[1]);
469c8c3fc56SRobert Watson 
470c8c3fc56SRobert Watson 	if (!close_sva_after_send)
471c8c3fc56SRobert Watson 		close2(sva[0], sva[1]);
472c8c3fc56SRobert Watson 	if (!close_spare_after_send)
473c8c3fc56SRobert Watson 		close(spare);
474c8c3fc56SRobert Watson 
475c8c3fc56SRobert Watson 	test_sysctls(inflight, openfiles);
476c8c3fc56SRobert Watson }
477c8c3fc56SRobert Watson 
478c8c3fc56SRobert Watson static void
479c8c3fc56SRobert Watson fivesome_drop(void)
480c8c3fc56SRobert Watson {
481c8c3fc56SRobert Watson 
482c8c3fc56SRobert Watson 	fivesome_drop_work("fivesome_drop1", 0, 0);
483c8c3fc56SRobert Watson 	fivesome_drop_work("fivesome_drop2", 0, 1);
484c8c3fc56SRobert Watson 	fivesome_drop_work("fivesome_drop3", 1, 0);
485c8c3fc56SRobert Watson 	fivesome_drop_work("fivesome_drop4", 1, 1);
486c8c3fc56SRobert Watson }
487c8c3fc56SRobert Watson 
488c8c3fc56SRobert Watson /*
489c8c3fc56SRobert Watson  * Create a somewhat nasty dual-socket socket intended to upset the garbage
490c8c3fc56SRobert Watson  * collector if mark-and-sweep is wrong.
491c8c3fc56SRobert Watson  */
492c8c3fc56SRobert Watson static void
493c8c3fc56SRobert Watson complex_cycles(void)
494c8c3fc56SRobert Watson {
495c8c3fc56SRobert Watson 	int inflight, openfiles;
496c8c3fc56SRobert Watson 	int spare, sva[2], svb[2];
497c8c3fc56SRobert Watson 
498c8c3fc56SRobert Watson 	test = "complex_cycles";
499c8c3fc56SRobert Watson 	printf("%s\n", test);
500c8c3fc56SRobert Watson 	save_sysctls(&inflight, &openfiles);
501c8c3fc56SRobert Watson 	alloc5fds(&spare, sva, svb);
502c8c3fc56SRobert Watson 	sendfd(sva[0], svb[0]);
503c8c3fc56SRobert Watson 	sendfd(sva[0], svb[1]);
504c8c3fc56SRobert Watson 	sendfd(svb[0], sva[0]);
505c8c3fc56SRobert Watson 	sendfd(svb[0], sva[1]);
506c8c3fc56SRobert Watson 	sendfd(svb[0], spare);
507c8c3fc56SRobert Watson 	sendfd(sva[0], spare);
508c8c3fc56SRobert Watson 	close5(spare, sva[0], sva[1], svb[0], svb[1]);
509c8c3fc56SRobert Watson 	test_sysctls(inflight, openfiles);
510c8c3fc56SRobert Watson }
511c8c3fc56SRobert Watson 
512c8c3fc56SRobert Watson /*
513c8c3fc56SRobert Watson  * Listen sockets can also be passed over UNIX domain sockets, so test
514c8c3fc56SRobert Watson  * various cases, including ones where listen sockets have waiting sockets
515c8c3fc56SRobert Watson  * hanging off them...
516c8c3fc56SRobert Watson  */
517c8c3fc56SRobert Watson static void
518c8c3fc56SRobert Watson listen_nothing(void)
519c8c3fc56SRobert Watson {
520c8c3fc56SRobert Watson 	struct sockaddr_un sun;
521c8c3fc56SRobert Watson 	struct sockaddr_in sin;
522c8c3fc56SRobert Watson 	int inflight, openfiles;
523c8c3fc56SRobert Watson 	int s;
524c8c3fc56SRobert Watson 
525c8c3fc56SRobert Watson 	test = "listen_nothing_unp";
526c8c3fc56SRobert Watson 	printf("%s\n", test);
527c8c3fc56SRobert Watson 	bzero(&sun, sizeof(sun));
528c8c3fc56SRobert Watson 	sun.sun_family = AF_LOCAL;
529c8c3fc56SRobert Watson 	sun.sun_len = sizeof(sun);
530c8c3fc56SRobert Watson 	snprintf(sun.sun_path, sizeof(sun.sun_path), "%s/%s", dpath, test);
531c8c3fc56SRobert Watson 	save_sysctls(&inflight, &openfiles);
532c8c3fc56SRobert Watson 	s = my_socket(PF_LOCAL, SOCK_STREAM, 0);
533c8c3fc56SRobert Watson 	my_bind(s, (struct sockaddr *)&sun, sizeof(sun));
534c8c3fc56SRobert Watson 	my_listen(s, -1);
535c8c3fc56SRobert Watson 	close(s);
536c8c3fc56SRobert Watson 	(void)unlink(sun.sun_path);
537c8c3fc56SRobert Watson 	test_sysctls(inflight, openfiles);
538c8c3fc56SRobert Watson 
539c8c3fc56SRobert Watson 	test = "listen_nothing_inet";
540c8c3fc56SRobert Watson 	printf("%s\n", test);
541c8c3fc56SRobert Watson 	bzero(&sin, sizeof(sin));
542c8c3fc56SRobert Watson 	sin.sin_family = AF_INET;
543c8c3fc56SRobert Watson 	sin.sin_len = sizeof(sin);
544c8c3fc56SRobert Watson 	sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
545c8c3fc56SRobert Watson 	sin.sin_port = htons(0);
546c8c3fc56SRobert Watson 	save_sysctls(&inflight, &openfiles);
547c8c3fc56SRobert Watson 	s = my_socket(PF_INET, SOCK_STREAM, 0);
548c8c3fc56SRobert Watson 	my_bind(s, (struct sockaddr *)&sin, sizeof(sin));
549c8c3fc56SRobert Watson 	my_listen(s, -1);
550c8c3fc56SRobert Watson 	close(s);
551c8c3fc56SRobert Watson 	test_sysctls(inflight, openfiles);
552c8c3fc56SRobert Watson }
553c8c3fc56SRobert Watson 
554c8c3fc56SRobert Watson /*
555c8c3fc56SRobert Watson  * Send a listen UDP socket over a UNIX domain socket.
556c8c3fc56SRobert Watson  *
557c8c3fc56SRobert Watson  * Send a listen TCP socket over a UNIX domain socket.
558c8c3fc56SRobert Watson  *
559c8c3fc56SRobert Watson  * Do each twice, with closing of the listen socket vs. socketpair in
560c8c3fc56SRobert Watson  * different orders.
561c8c3fc56SRobert Watson  */
562c8c3fc56SRobert Watson static void
563c8c3fc56SRobert Watson listen_drop(void)
564c8c3fc56SRobert Watson {
565c8c3fc56SRobert Watson 	struct sockaddr_un sun;
566c8c3fc56SRobert Watson 	struct sockaddr_in sin;
567c8c3fc56SRobert Watson 	int inflight, openfiles;
568c8c3fc56SRobert Watson 	int s, sv[2];
569c8c3fc56SRobert Watson 
570c8c3fc56SRobert Watson 	bzero(&sun, sizeof(sun));
571c8c3fc56SRobert Watson 	sun.sun_family = AF_LOCAL;
572c8c3fc56SRobert Watson 	sun.sun_len = sizeof(sun);
573c8c3fc56SRobert Watson 
574c8c3fc56SRobert Watson 	/*
575c8c3fc56SRobert Watson 	 * Close listen socket first.
576c8c3fc56SRobert Watson 	 */
577c8c3fc56SRobert Watson 	test = "listen_drop_unp1";
578c8c3fc56SRobert Watson 	printf("%s\n", test);
579c8c3fc56SRobert Watson 	snprintf(sun.sun_path, sizeof(sun.sun_path), "%s/%s", dpath, test);
580c8c3fc56SRobert Watson 	save_sysctls(&inflight, &openfiles);
581c8c3fc56SRobert Watson 	s = my_socket(PF_LOCAL, SOCK_STREAM, 0);
582c8c3fc56SRobert Watson 	my_bind(s, (struct sockaddr *)&sun, sizeof(sun));
583c8c3fc56SRobert Watson 	my_listen(s, -1);
584c8c3fc56SRobert Watson 	my_socketpair(sv);
585c8c3fc56SRobert Watson 	sendfd(sv[0], s);
586c8c3fc56SRobert Watson 	close3(s, sv[0], sv[1]);
587c8c3fc56SRobert Watson 	test_sysctls(inflight, openfiles);
588c8c3fc56SRobert Watson 
589c8c3fc56SRobert Watson 	/*
590c8c3fc56SRobert Watson 	 * Close socketpair first.
591c8c3fc56SRobert Watson 	 */
592c8c3fc56SRobert Watson 	test = "listen_drop_unp2";
593c8c3fc56SRobert Watson 	printf("%s\n", test);
594c8c3fc56SRobert Watson 	snprintf(sun.sun_path, sizeof(sun.sun_path), "%s/%s", dpath, test);
595c8c3fc56SRobert Watson 	save_sysctls(&inflight, &openfiles);
596c8c3fc56SRobert Watson 	s = my_socket(PF_LOCAL, SOCK_STREAM, 0);
597c8c3fc56SRobert Watson 	my_bind(s, (struct sockaddr *)&sun, sizeof(sun));
598c8c3fc56SRobert Watson 	my_listen(s, -1);
599c8c3fc56SRobert Watson 	my_socketpair(sv);
600c8c3fc56SRobert Watson 	sendfd(sv[0], s);
601c8c3fc56SRobert Watson 	close3(sv[0], sv[1], s);
602c8c3fc56SRobert Watson 	test_sysctls(inflight, openfiles);
603c8c3fc56SRobert Watson 
604c8c3fc56SRobert Watson 	sin.sin_family = AF_INET;
605c8c3fc56SRobert Watson 	sin.sin_len = sizeof(sin);
606c8c3fc56SRobert Watson 	sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
607c8c3fc56SRobert Watson 	sin.sin_port = htons(0);
608c8c3fc56SRobert Watson 
609c8c3fc56SRobert Watson 	/*
610c8c3fc56SRobert Watson 	 * Close listen socket first.
611c8c3fc56SRobert Watson 	 */
612c8c3fc56SRobert Watson 	test = "listen_drop_inet1";
613c8c3fc56SRobert Watson 	printf("%s\n", test);
614c8c3fc56SRobert Watson 	bzero(&sun, sizeof(sun));
615c8c3fc56SRobert Watson 	save_sysctls(&inflight, &openfiles);
616c8c3fc56SRobert Watson 	s = my_socket(PF_INET, SOCK_STREAM, 0);
617c8c3fc56SRobert Watson 	my_bind(s, (struct sockaddr *)&sin, sizeof(sin));
618c8c3fc56SRobert Watson 	my_listen(s, -1);
619c8c3fc56SRobert Watson 	my_socketpair(sv);
620c8c3fc56SRobert Watson 	sendfd(sv[0], s);
621c8c3fc56SRobert Watson 	close3(s, sv[0], sv[1]);
622c8c3fc56SRobert Watson 	test_sysctls(inflight, openfiles);
623c8c3fc56SRobert Watson 
624c8c3fc56SRobert Watson 	/*
625c8c3fc56SRobert Watson 	 * Close socketpair first.
626c8c3fc56SRobert Watson 	 */
627c8c3fc56SRobert Watson 	test = "listen_drop_inet2";
628c8c3fc56SRobert Watson 	printf("%s\n", test);
629c8c3fc56SRobert Watson 	bzero(&sun, sizeof(sun));
630c8c3fc56SRobert Watson 	save_sysctls(&inflight, &openfiles);
631c8c3fc56SRobert Watson 	s = my_socket(PF_INET, SOCK_STREAM, 0);
632c8c3fc56SRobert Watson 	my_bind(s, (struct sockaddr *)&sin, sizeof(sin));
633c8c3fc56SRobert Watson 	my_listen(s, -1);
634c8c3fc56SRobert Watson 	my_socketpair(sv);
635c8c3fc56SRobert Watson 	sendfd(sv[0], s);
636c8c3fc56SRobert Watson 	close3(sv[0], sv[1], s);
637c8c3fc56SRobert Watson 	test_sysctls(inflight, openfiles);
638c8c3fc56SRobert Watson }
639c8c3fc56SRobert Watson 
640c8c3fc56SRobert Watson /*
641c8c3fc56SRobert Watson  * Up things a notch with listen sockets: add connections that can be
642c8c3fc56SRobert Watson  * accepted to the listen queues.
643c8c3fc56SRobert Watson  */
644c8c3fc56SRobert Watson static void
645c8c3fc56SRobert Watson listen_connect_nothing(void)
646c8c3fc56SRobert Watson {
647c8c3fc56SRobert Watson 	struct sockaddr_in sin;
648c8c3fc56SRobert Watson 	int slisten, sconnect, sv[2];
649c8c3fc56SRobert Watson 	int inflight, openfiles;
650c8c3fc56SRobert Watson 	socklen_t len;
651c8c3fc56SRobert Watson 
652c8c3fc56SRobert Watson 	test = "listen_connect_nothing";
653c8c3fc56SRobert Watson 	printf("%s\n", test);
654c8c3fc56SRobert Watson 	save_sysctls(&inflight, &openfiles);
655c8c3fc56SRobert Watson 
656c8c3fc56SRobert Watson 	slisten = my_socket(PF_INET, SOCK_STREAM, 0);
657c8c3fc56SRobert Watson 	my_bind(slisten, (struct sockaddr *)&sin, sizeof(sin));
658c8c3fc56SRobert Watson 	my_listen(slisten, -1);
659c8c3fc56SRobert Watson 
660c8c3fc56SRobert Watson 	my_socketpair(sv);
661c8c3fc56SRobert Watson 
662c8c3fc56SRobert Watson 	len = sizeof(sin);
663c8c3fc56SRobert Watson 	my_getsockname(slisten, (struct sockaddr *)&sin, &len);
664c8c3fc56SRobert Watson 
665c8c3fc56SRobert Watson 	sconnect = my_socket(PF_INET, SOCK_STREAM, 0);
666c8c3fc56SRobert Watson 	setnonblock(sconnect);
667c8c3fc56SRobert Watson 	my_connect(sconnect, (struct sockaddr *)&sin, len);
668c8c3fc56SRobert Watson 
669c8c3fc56SRobert Watson 	sleep(1);
670c8c3fc56SRobert Watson 
671c8c3fc56SRobert Watson 	close4(slisten, sconnect, sv[0], sv[1]);
672c8c3fc56SRobert Watson 
673c8c3fc56SRobert Watson 	test_sysctls(inflight, openfiles);
674c8c3fc56SRobert Watson }
675c8c3fc56SRobert Watson 
676c8c3fc56SRobert Watson static void
677c8c3fc56SRobert Watson listen_connect_drop(void)
678c8c3fc56SRobert Watson {
679c8c3fc56SRobert Watson 	struct sockaddr_in sin;
680c8c3fc56SRobert Watson 	int slisten, sconnect, sv[2];
681c8c3fc56SRobert Watson 	int inflight, openfiles;
682c8c3fc56SRobert Watson 	socklen_t len;
683c8c3fc56SRobert Watson 
684c8c3fc56SRobert Watson 	test = "listen_connect_drop";
685c8c3fc56SRobert Watson 	printf("%s\n", test);
686c8c3fc56SRobert Watson 	save_sysctls(&inflight, &openfiles);
687c8c3fc56SRobert Watson 
688c8c3fc56SRobert Watson 	slisten = my_socket(PF_INET, SOCK_STREAM, 0);
689c8c3fc56SRobert Watson 	my_bind(slisten, (struct sockaddr *)&sin, sizeof(sin));
690c8c3fc56SRobert Watson 	my_listen(slisten, -1);
691c8c3fc56SRobert Watson 
692c8c3fc56SRobert Watson 	my_socketpair(sv);
693c8c3fc56SRobert Watson 
694c8c3fc56SRobert Watson 	len = sizeof(sin);
695c8c3fc56SRobert Watson 	my_getsockname(slisten, (struct sockaddr *)&sin, &len);
696c8c3fc56SRobert Watson 
697c8c3fc56SRobert Watson 	sconnect = my_socket(PF_INET, SOCK_STREAM, 0);
698c8c3fc56SRobert Watson 	setnonblock(sconnect);
699c8c3fc56SRobert Watson 	my_connect(sconnect, (struct sockaddr *)&sin, len);
700c8c3fc56SRobert Watson 
701c8c3fc56SRobert Watson 	sleep(1);
702c8c3fc56SRobert Watson 	sendfd(sv[0], slisten);
703c8c3fc56SRobert Watson 	close3(slisten, sv[0], sv[1]);
704c8c3fc56SRobert Watson 	sleep(1);
705c8c3fc56SRobert Watson 	close(sconnect);
706c8c3fc56SRobert Watson 
707c8c3fc56SRobert Watson 	test_sysctls(inflight, openfiles);
708c8c3fc56SRobert Watson }
709c8c3fc56SRobert Watson 
710c8c3fc56SRobert Watson #define	RMDIR	"rm -Rf "
711c8c3fc56SRobert Watson int
712c8c3fc56SRobert Watson main(int argc, char *argv[])
713c8c3fc56SRobert Watson {
714c8c3fc56SRobert Watson 	char cmd[sizeof(RMDIR) + PATH_MAX];
715c8c3fc56SRobert Watson 	int serrno;
716c8c3fc56SRobert Watson 	pid_t pid;
717c8c3fc56SRobert Watson 
718c8c3fc56SRobert Watson 	strlcpy(dpath, "/tmp/unpgc.XXXXXXXX", sizeof(dpath));
719c8c3fc56SRobert Watson 	if (mkdtemp(dpath) == NULL)
720c8c3fc56SRobert Watson 		err(-1, "mkdtemp");
721c8c3fc56SRobert Watson 
722c8c3fc56SRobert Watson 	/*
723c8c3fc56SRobert Watson 	 * Set up a parent process to GC temporary storage when we're done.
724c8c3fc56SRobert Watson 	 */
725c8c3fc56SRobert Watson 	pid = fork();
726c8c3fc56SRobert Watson 	if (pid < 0) {
727c8c3fc56SRobert Watson 		serrno = errno;
728c8c3fc56SRobert Watson 		(void)rmdir(dpath);
729c8c3fc56SRobert Watson 		errno = serrno;
730c8c3fc56SRobert Watson 		err(-1, "fork");
731c8c3fc56SRobert Watson 	}
732c8c3fc56SRobert Watson 	if (pid > 0) {
733c8c3fc56SRobert Watson 		signal(SIGINT, SIG_IGN);
734c8c3fc56SRobert Watson 		while (waitpid(pid, NULL, 0) != pid);
735c8c3fc56SRobert Watson 		snprintf(cmd, sizeof(cmd), "%s %s", RMDIR, dpath);
736c8c3fc56SRobert Watson 		(void)system(cmd);
737c8c3fc56SRobert Watson 		exit(0);
738c8c3fc56SRobert Watson 	}
739c8c3fc56SRobert Watson 
740c8c3fc56SRobert Watson 	printf("Start: inflight %d open %d\n", getinflight(),
741c8c3fc56SRobert Watson 	    getopenfiles());
742c8c3fc56SRobert Watson 
743c8c3fc56SRobert Watson 	twosome_nothing();
744c8c3fc56SRobert Watson 	twosome_drop();
745c8c3fc56SRobert Watson 
746c8c3fc56SRobert Watson 	threesome_nothing();
747c8c3fc56SRobert Watson 	threesome_drop();
748c8c3fc56SRobert Watson 
749c8c3fc56SRobert Watson 	fivesome_nothing();
750c8c3fc56SRobert Watson 	fivesome_drop();
751c8c3fc56SRobert Watson 
752c8c3fc56SRobert Watson 	complex_cycles();
753c8c3fc56SRobert Watson 
754c8c3fc56SRobert Watson 	listen_nothing();
755c8c3fc56SRobert Watson 	listen_drop();
756c8c3fc56SRobert Watson 
757c8c3fc56SRobert Watson 	listen_connect_nothing();
758c8c3fc56SRobert Watson 	listen_connect_drop();
759c8c3fc56SRobert Watson 
760c8c3fc56SRobert Watson 	printf("Finish: inflight %d open %d\n", getinflight(),
761c8c3fc56SRobert Watson 	    getopenfiles());
762c8c3fc56SRobert Watson 	return (0);
763c8c3fc56SRobert Watson }
764