1 /* 2 * Copyright (c) International Business Machines Corp., 2002 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 12 * the GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. 16 */ 17 18 /* 19 * Check that if a child has a "broken pipe", this information 20 * is transmitted to the waiting parent. 21 */ 22 23 #include <errno.h> 24 #include <string.h> 25 #include <unistd.h> 26 #include <stdlib.h> 27 #include <sys/wait.h> 28 #include "tst_test.h" 29 30 #define SIZE 5 31 32 static int fd[2]; 33 static char rdbuf[SIZE]; 34 static char wrbuf[SIZE]; 35 36 static void do_child(void) 37 { 38 SAFE_SIGNAL(SIGPIPE, SIG_DFL); 39 SAFE_CLOSE(fd[0]); 40 SAFE_WRITE(1, fd[1], wrbuf, SIZE); 41 42 TST_CHECKPOINT_WAIT(0); 43 44 SAFE_WRITE(1, fd[1], wrbuf, SIZE); 45 exit(0); 46 } 47 48 static void verify_pipe(void) 49 { 50 int status; 51 int sig = 0; 52 pid_t pid; 53 54 memset(wrbuf, 'a', SIZE); 55 56 #ifdef UCLINUX 57 maybe_run_child(&do_child, "dd", &fd[0], &fd[1]); 58 #endif 59 60 TEST(pipe(fd)); 61 if (TEST_RETURN == -1) { 62 tst_res(TFAIL|TERRNO, "pipe() failed"); 63 return; 64 } 65 66 pid = SAFE_FORK(); 67 if (pid == 0) { 68 #ifdef UCLINUX 69 if (self_exec(av[0], "dd", fd[0], fd[1]) < 0) 70 tst_brk(TBROK, "self_exec failed"); 71 #else 72 do_child(); 73 #endif 74 } 75 76 memset(rdbuf, 0, SIZE); 77 SAFE_CLOSE(fd[1]); 78 SAFE_READ(1, fd[0], rdbuf, SIZE); 79 80 if (memcmp(wrbuf, rdbuf, SIZE) != 0) { 81 tst_res(TFAIL, "pipe read data and pipe " 82 "write data didn't match"); 83 return; 84 } 85 86 SAFE_CLOSE(fd[0]); 87 TST_CHECKPOINT_WAKE(0); 88 SAFE_WAIT(&status); 89 90 if (!WIFSIGNALED(status)) { 91 tst_res(TFAIL, "Child wasn't killed by signal"); 92 } else { 93 sig = WTERMSIG(status); 94 if (sig != SIGPIPE) { 95 tst_res(TFAIL, "Child killed by %s expected SIGPIPE", 96 tst_strsig(sig)); 97 } else { 98 tst_res(TPASS, "Child killed by SIGPIPE"); 99 } 100 } 101 } 102 103 static struct tst_test test = { 104 .tid = "pipe02", 105 .forks_child = 1, 106 .needs_checkpoints = 1, 107 .test_all = verify_pipe, 108 }; 109