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