xref: /openbsd-src/regress/sys/kern/unp-write-closed/unp-write-closed.c (revision 39bc8ae496118835b834638658fc7af326a8a2dd)
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