xref: /xnu-11215.41.3/tests/pipe_read_infloop_55437634.c (revision 33de042d024d46de5ff4e89f2471de6608e37fa4)
1 #include <stdio.h>
2 #include <stdlib.h>
3 
4 #include <sys/types.h>
5 #include <sys/uio.h>
6 #include <unistd.h>
7 
8 #include <darwintest.h>
9 
10 static void
too_long(int ignored)11 too_long(int ignored)
12 {
13 	T_ASSERT_FAIL("child readv is blocked");
14 }
15 
16 T_DECL(pipe_read_infloop_55437634, "Infinite loop in pipe_read")
17 {
18 	int p[2];
19 	char c = 0;
20 	struct iovec iov = {
21 		.iov_base = &c,
22 		.iov_len = 0x100000000UL
23 	};
24 	pid_t child;
25 	int status = 0;
26 
27 	T_SETUPBEGIN;
28 	/* create a pipe with some data in it: */
29 	T_ASSERT_POSIX_SUCCESS(pipe(p), NULL);
30 	T_ASSERT_POSIX_SUCCESS(write(p[1], "A", 1), NULL);
31 	T_SETUPEND;
32 
33 	T_ASSERT_POSIX_SUCCESS(child = fork(), NULL);
34 
35 	if (!child) {
36 		readv(p[0], &iov, 1);
37 		exit(0);
38 	}
39 
40 	/*
41 	 * if the waitpid takes too long, the child is probably stuck in the
42 	 * infinite loop, so fail via too_long.
43 	 */
44 	T_ASSERT_NE(signal(SIGALRM, too_long), SIG_ERR, NULL);
45 	T_ASSERT_POSIX_SUCCESS(alarm(10), NULL);
46 
47 	/* this will hang if the bug is there: */
48 	T_ASSERT_POSIX_SUCCESS(waitpid(child, &status, 0), NULL);
49 
50 	/* expecting a clean, zero exit: */
51 	T_ASSERT_TRUE(WIFEXITED(status), NULL);
52 	T_ASSERT_EQ(WEXITSTATUS(status), 0, NULL);
53 }
54