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