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