• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) International Business Machines Corp., 2002
4  */
5 
6 /*
7  * Check that if a child has a "broken pipe", this information
8  * is transmitted to the waiting parent.
9  */
10 
11 #include <errno.h>
12 #include <string.h>
13 #include <unistd.h>
14 #include <stdlib.h>
15 #include <sys/wait.h>
16 #include "tst_test.h"
17 
18 #define SIZE	5
19 
20 static int fd[2];
21 static char rdbuf[SIZE];
22 static char wrbuf[SIZE];
23 
do_child(void)24 static void do_child(void)
25 {
26 	SAFE_SIGNAL(SIGPIPE, SIG_DFL);
27 	SAFE_CLOSE(fd[0]);
28 	SAFE_WRITE(1, fd[1], wrbuf, SIZE);
29 
30 	TST_CHECKPOINT_WAIT(0);
31 
32 	SAFE_WRITE(1, fd[1], wrbuf, SIZE);
33 	exit(0);
34 }
35 
verify_pipe(void)36 static void verify_pipe(void)
37 {
38 	int status;
39 	int sig = 0;
40 	pid_t pid;
41 
42 	memset(wrbuf, 'a', SIZE);
43 
44 #ifdef UCLINUX
45 	maybe_run_child(&do_child, "dd", &fd[0], &fd[1]);
46 #endif
47 
48 	TEST(pipe(fd));
49 	if (TST_RET == -1) {
50 		tst_res(TFAIL|TTERRNO, "pipe() failed");
51 		return;
52 	}
53 
54 	pid = SAFE_FORK();
55 	if (pid == 0) {
56 #ifdef UCLINUX
57 		if (self_exec(av[0], "dd", fd[0], fd[1]) < 0)
58 			tst_brk(TBROK, "self_exec failed");
59 #else
60 		do_child();
61 #endif
62 	}
63 
64 	memset(rdbuf, 0, SIZE);
65 	SAFE_CLOSE(fd[1]);
66 	SAFE_READ(1, fd[0], rdbuf, SIZE);
67 
68 	if (memcmp(wrbuf, rdbuf, SIZE) != 0) {
69 		tst_res(TFAIL, "pipe read data and pipe "
70 			"write data didn't match");
71 		return;
72 	}
73 
74 	SAFE_CLOSE(fd[0]);
75 	TST_CHECKPOINT_WAKE(0);
76 	SAFE_WAIT(&status);
77 
78 	if (!WIFSIGNALED(status)) {
79 		tst_res(TFAIL, "Child wasn't killed by signal");
80 	} else {
81 		sig = WTERMSIG(status);
82 		if (sig != SIGPIPE) {
83 			tst_res(TFAIL, "Child killed by %s expected SIGPIPE",
84 				tst_strsig(sig));
85 		} else {
86 				tst_res(TPASS, "Child killed by SIGPIPE");
87 		}
88 	}
89 }
90 
91 static struct tst_test test = {
92 	.forks_child = 1,
93 	.needs_checkpoints = 1,
94 	.test_all = verify_pipe,
95 };
96