/* * Copyright (c) International Business Machines Corp., 2002 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. */ /* * Check that if a child has a "broken pipe", this information * is transmitted to the waiting parent. */ #include #include #include #include #include #include "tst_test.h" #define SIZE 5 static int fd[2]; static char rdbuf[SIZE]; static char wrbuf[SIZE]; static void do_child(void) { SAFE_SIGNAL(SIGPIPE, SIG_DFL); SAFE_CLOSE(fd[0]); SAFE_WRITE(1, fd[1], wrbuf, SIZE); TST_CHECKPOINT_WAIT(0); SAFE_WRITE(1, fd[1], wrbuf, SIZE); exit(0); } static void verify_pipe(void) { int status; int sig = 0; pid_t pid; memset(wrbuf, 'a', SIZE); #ifdef UCLINUX maybe_run_child(&do_child, "dd", &fd[0], &fd[1]); #endif TEST(pipe(fd)); if (TST_RET == -1) { tst_res(TFAIL|TERRNO, "pipe() failed"); return; } pid = SAFE_FORK(); if (pid == 0) { #ifdef UCLINUX if (self_exec(av[0], "dd", fd[0], fd[1]) < 0) tst_brk(TBROK, "self_exec failed"); #else do_child(); #endif } memset(rdbuf, 0, SIZE); SAFE_CLOSE(fd[1]); SAFE_READ(1, fd[0], rdbuf, SIZE); if (memcmp(wrbuf, rdbuf, SIZE) != 0) { tst_res(TFAIL, "pipe read data and pipe " "write data didn't match"); return; } SAFE_CLOSE(fd[0]); TST_CHECKPOINT_WAKE(0); SAFE_WAIT(&status); if (!WIFSIGNALED(status)) { tst_res(TFAIL, "Child wasn't killed by signal"); } else { sig = WTERMSIG(status); if (sig != SIGPIPE) { tst_res(TFAIL, "Child killed by %s expected SIGPIPE", tst_strsig(sig)); } else { tst_res(TPASS, "Child killed by SIGPIPE"); } } } static struct tst_test test = { .forks_child = 1, .needs_checkpoints = 1, .test_all = verify_pipe, };