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