xref: /freebsd/tools/regression/sockets/unix_sorflush/unix_sorflush.c (revision 1d386b48a555f61cb7325543adbbb5c3f3407a66)
19cf15e96SRobert Watson /*-
29cf15e96SRobert Watson  * Copyright (c) 2008 Robert N. M. Watson
39cf15e96SRobert Watson  * All rights reserved.
49cf15e96SRobert Watson  *
59cf15e96SRobert Watson  * Redistribution and use in source and binary forms, with or without
69cf15e96SRobert Watson  * modification, are permitted provided that the following conditions
79cf15e96SRobert Watson  * are met:
89cf15e96SRobert Watson  * 1. Redistributions of source code must retain the above copyright
99cf15e96SRobert Watson  *    notice, this list of conditions and the following disclaimer.
109cf15e96SRobert Watson  * 2. Redistributions in binary form must reproduce the above copyright
119cf15e96SRobert Watson  *    notice, this list of conditions and the following disclaimer in the
129cf15e96SRobert Watson  *    documentation and/or other materials provided with the distribution.
139cf15e96SRobert Watson  *
149cf15e96SRobert Watson  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
159cf15e96SRobert Watson  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
169cf15e96SRobert Watson  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
179cf15e96SRobert Watson  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
189cf15e96SRobert Watson  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
199cf15e96SRobert Watson  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
209cf15e96SRobert Watson  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
219cf15e96SRobert Watson  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
229cf15e96SRobert Watson  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
239cf15e96SRobert Watson  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
249cf15e96SRobert Watson  * SUCH DAMAGE.
259cf15e96SRobert Watson  */
269cf15e96SRobert Watson 
279cf15e96SRobert Watson /*
289cf15e96SRobert Watson  * Reproduce a race in which:
299cf15e96SRobert Watson  *
309cf15e96SRobert Watson  * - Process (a) is blocked in read on a socket waiting on data.
319cf15e96SRobert Watson  * - Process (b) is blocked in shutdown() on a socket waiting on (a).
329cf15e96SRobert Watson  * - Process (c) delivers a signal to (b) interrupting its wait.
339cf15e96SRobert Watson  *
349cf15e96SRobert Watson  * This race is premised on shutdown() not interrupting (a) properly, and the
359cf15e96SRobert Watson  * signal to (b) causing problems in the kernel.
369cf15e96SRobert Watson  */
379cf15e96SRobert Watson 
389cf15e96SRobert Watson #include <sys/cdefs.h>
399cf15e96SRobert Watson #include <sys/socket.h>
409cf15e96SRobert Watson 
419cf15e96SRobert Watson #include <err.h>
429cf15e96SRobert Watson #include <signal.h>
439cf15e96SRobert Watson #include <stdio.h>
449cf15e96SRobert Watson #include <stdlib.h>
459cf15e96SRobert Watson #include <unistd.h>
469cf15e96SRobert Watson 
479cf15e96SRobert Watson static void
receive_and_exit(int s)489cf15e96SRobert Watson receive_and_exit(int s)
499cf15e96SRobert Watson {
509cf15e96SRobert Watson 	ssize_t ssize;
519cf15e96SRobert Watson 	char ch;
529cf15e96SRobert Watson 
539cf15e96SRobert Watson 	ssize = recv(s, &ch, sizeof(ch), 0);
549cf15e96SRobert Watson 	if (ssize < 0)
559cf15e96SRobert Watson 		err(-1, "receive_and_exit: recv");
569cf15e96SRobert Watson 	exit(0);
579cf15e96SRobert Watson }
589cf15e96SRobert Watson 
599cf15e96SRobert Watson static void
shutdown_and_exit(int s)609cf15e96SRobert Watson shutdown_and_exit(int s)
619cf15e96SRobert Watson {
629cf15e96SRobert Watson 
639cf15e96SRobert Watson 	if (shutdown(s, SHUT_RD) < 0)
649cf15e96SRobert Watson 		err(-1, "shutdown_and_exit: shutdown");
659cf15e96SRobert Watson 	exit(0);
669cf15e96SRobert Watson }
679cf15e96SRobert Watson 
689cf15e96SRobert Watson int
main(void)69*1103e0c1SEnji Cooper main(void)
709cf15e96SRobert Watson {
719cf15e96SRobert Watson 	pid_t pida, pidb;
729cf15e96SRobert Watson 	int sv[2];
739cf15e96SRobert Watson 
749cf15e96SRobert Watson 	if (socketpair(PF_LOCAL, SOCK_STREAM, 0, sv) < 0)
759cf15e96SRobert Watson 		err(-1, "socketpair");
769cf15e96SRobert Watson 
779cf15e96SRobert Watson 	pida = fork();
789cf15e96SRobert Watson 	if (pida < 0)
799cf15e96SRobert Watson 		err(-1, "fork");
809cf15e96SRobert Watson 	if (pida == 0)
819cf15e96SRobert Watson 		receive_and_exit(sv[1]);
829cf15e96SRobert Watson 	sleep(1);
839cf15e96SRobert Watson 	pidb = fork();
849cf15e96SRobert Watson 	if (pidb < 0) {
859cf15e96SRobert Watson 		warn("fork");
869cf15e96SRobert Watson 		(void)kill(pida, SIGKILL);
879cf15e96SRobert Watson 		exit(-1);
889cf15e96SRobert Watson 	}
899cf15e96SRobert Watson 	if (pidb == 0)
909cf15e96SRobert Watson 		shutdown_and_exit(sv[1]);
919cf15e96SRobert Watson 	sleep(1);
929cf15e96SRobert Watson 	if (kill(pidb, SIGKILL) < 0)
939cf15e96SRobert Watson 		err(-1, "kill");
949cf15e96SRobert Watson 	sleep(1);
959cf15e96SRobert Watson 	printf("ok 1 - unix_sorflush\n");
969cf15e96SRobert Watson 	exit(0);
979cf15e96SRobert Watson }
98