1175821Srwatson/*-
2175821Srwatson * Copyright (c) 2008 Robert N. M. Watson
3175821Srwatson * All rights reserved.
4175821Srwatson *
5175821Srwatson * Redistribution and use in source and binary forms, with or without
6175821Srwatson * modification, are permitted provided that the following conditions
7175821Srwatson * are met:
8175821Srwatson * 1. Redistributions of source code must retain the above copyright
9175821Srwatson *    notice, this list of conditions and the following disclaimer.
10175821Srwatson * 2. Redistributions in binary form must reproduce the above copyright
11175821Srwatson *    notice, this list of conditions and the following disclaimer in the
12175821Srwatson *    documentation and/or other materials provided with the distribution.
13175821Srwatson *
14175821Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15175821Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16175821Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17175821Srwatson * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18175821Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19175821Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20175821Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21175821Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22175821Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23175821Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24175821Srwatson * SUCH DAMAGE.
25175821Srwatson */
26175821Srwatson
27175821Srwatson/*
28175821Srwatson * Reproduce a race in which:
29175821Srwatson *
30175821Srwatson * - Process (a) is blocked in read on a socket waiting on data.
31175821Srwatson * - Process (b) is blocked in shutdown() on a socket waiting on (a).
32175821Srwatson * - Process (c) delivers a signal to (b) interrupting its wait.
33175821Srwatson *
34175821Srwatson * This race is premised on shutdown() not interrupting (a) properly, and the
35175821Srwatson * signal to (b) causing problems in the kernel.
36175821Srwatson */
37175821Srwatson
38175821Srwatson#include <sys/cdefs.h>
39175821Srwatson__FBSDID("$FreeBSD$");
40175821Srwatson
41175821Srwatson#include <sys/socket.h>
42175821Srwatson
43175821Srwatson#include <err.h>
44175821Srwatson#include <signal.h>
45175821Srwatson#include <stdio.h>
46175821Srwatson#include <stdlib.h>
47175821Srwatson#include <unistd.h>
48175821Srwatson
49175821Srwatsonstatic void
50175821Srwatsonreceive_and_exit(int s)
51175821Srwatson{
52175821Srwatson	ssize_t ssize;
53175821Srwatson	char ch;
54175821Srwatson
55175821Srwatson	ssize = recv(s, &ch, sizeof(ch), 0);
56175821Srwatson	if (ssize < 0)
57175821Srwatson		err(-1, "receive_and_exit: recv");
58175821Srwatson	exit(0);
59175821Srwatson}
60175821Srwatson
61175821Srwatsonstatic void
62175821Srwatsonshutdown_and_exit(int s)
63175821Srwatson{
64175821Srwatson
65175821Srwatson	if (shutdown(s, SHUT_RD) < 0)
66175821Srwatson		err(-1, "shutdown_and_exit: shutdown");
67175821Srwatson	exit(0);
68175821Srwatson}
69175821Srwatson
70175821Srwatsonint
71175821Srwatsonmain(int argc, char *argv[])
72175821Srwatson{
73175821Srwatson	pid_t pida, pidb;
74175821Srwatson	int sv[2];
75175821Srwatson
76175821Srwatson	if (socketpair(PF_LOCAL, SOCK_STREAM, 0, sv) < 0)
77175821Srwatson		err(-1, "socketpair");
78175821Srwatson
79175821Srwatson	pida = fork();
80175821Srwatson	if (pida < 0)
81175821Srwatson		err(-1, "fork");
82175821Srwatson	if (pida == 0)
83175821Srwatson		receive_and_exit(sv[1]);
84175821Srwatson	sleep(1);
85175821Srwatson	pidb = fork();
86175821Srwatson	if (pidb < 0) {
87175821Srwatson		warn("fork");
88175821Srwatson		(void)kill(pida, SIGKILL);
89175821Srwatson		exit(-1);
90175821Srwatson	}
91175821Srwatson	if (pidb == 0)
92175821Srwatson		shutdown_and_exit(sv[1]);
93175821Srwatson	sleep(1);
94175821Srwatson	if (kill(pidb, SIGKILL) < 0)
95175821Srwatson		err(-1, "kill");
96175821Srwatson	sleep(1);
97175821Srwatson	printf("ok 1 - unix_sorflush\n");
98175821Srwatson	exit(0);
99175821Srwatson}
100