1 /* $OpenBSD: unp-write-closed.c,v 1.2 2024/07/14 18:49:32 anton Exp $ */
2 /*
3 * Copyright (c) 2024 Vitaliy Makkoveev <mvs@openbsd.org>
4 * Copyright (c) 2024 Alenander Bluhm <bluhm@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 #include <sys/types.h>
20 #include <sys/socket.h>
21 #include <sys/wait.h>
22
23 #include <err.h>
24 #include <errno.h>
25 #include <signal.h>
26 #include <unistd.h>
27
28 sig_atomic_t done = 0;
29
30 static void
handler(int sigraised)31 handler(int sigraised)
32 {
33 done = 1;
34 }
35
36 int
main(int argc,char * argv[])37 main(int argc, char *argv[])
38 {
39 int i, s[2], status;
40 pid_t pid;
41
42 if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
43 err(1, "signal pipe");
44 if (signal(SIGALRM, handler) == SIG_ERR)
45 err(1, "signal alrm");
46 alarm(30);
47
48 while (!done) {
49 if (socketpair(AF_UNIX, SOCK_STREAM, 0, s) < 0)
50 err(1, "socketpair");
51
52 switch ((pid = fork())) {
53 case -1:
54 err(1, "fork");
55 case 0:
56 if (close(s[0]) < 0)
57 err(1, "child close 0");
58 if (close(s[1]) < 0)
59 err(1, "child close 1");
60 return 0;
61 default:
62 if (close(s[1]) < 0)
63 err(1, "parent close 1");
64 for (i = 1000000; i > 0; i--) {
65 if (write(s[0], "1", 1) < 0)
66 break;
67 }
68 if (i <= 0)
69 errx(1, "write did not fail");
70 if (errno != EPIPE)
71 err(1, "write");
72 if (close(s[0]) < 0)
73 err(1, "parent close 1");
74 if (waitpid(pid, &status, 0) < 0)
75 err(1, "waitpid");
76 if (status != 0)
77 errx(1, "child status %d", status);
78 break;
79 }
80 }
81
82 return 0;
83 }
84