1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright (c) 2014 Fujitsu Ltd. 4 * Author: Xing Gu <gux.fnst@cn.fujitsu.com> 5 */ 6/* 7 * Description: 8 * Verify that, 9 * 1) tee() returns -1 and sets errno to EINVAL if fd_in does 10 * not refer to a pipe. 11 * 2) tee() returns -1 and sets errno to EINVAL if fd_out does 12 * not refer to a pipe. 13 * 3) tee() returns -1 and sets errno to EINVAL if fd_in and 14 * fd_out refer to the same pipe. 15 */ 16 17#define _GNU_SOURCE 18 19#include <sys/types.h> 20#include <sys/stat.h> 21#include <fcntl.h> 22#include <unistd.h> 23 24#include "tst_test.h" 25#include "lapi/tee.h" 26 27#define TEST_FILE "testfile" 28 29#define STR "abcdefghigklmnopqrstuvwxyz" 30#define TEE_TEST_LEN 10 31 32static int fd; 33static int pipes[2]; 34 35static struct tcase { 36 int *fdin; 37 int *fdout; 38 int exp_errno; 39} tcases[] = { 40 { &fd, &pipes[1], EINVAL }, 41 { &pipes[0], &fd, EINVAL }, 42 { &pipes[0], &pipes[1], EINVAL }, 43}; 44 45static void setup(void) 46{ 47 fd = SAFE_OPEN(TEST_FILE, O_RDWR | O_CREAT, 0644); 48 SAFE_PIPE(pipes); 49 SAFE_WRITE(SAFE_WRITE_ALL, pipes[1], STR, sizeof(STR) - 1); 50} 51 52static void tee_verify(unsigned int n) 53{ 54 struct tcase *tc = &tcases[n]; 55 56 TEST(tee(*(tc->fdin), *(tc->fdout), TEE_TEST_LEN, 0)); 57 58 if (TST_RET != -1) { 59 tst_res(TFAIL, "tee() returned %ld, " 60 "expected -1, errno:%d", TST_RET, 61 tc->exp_errno); 62 return; 63 } 64 65 if (TST_ERR != tc->exp_errno) { 66 tst_res(TFAIL | TTERRNO, 67 "tee() failed unexpectedly; expected: %d - %s", 68 tc->exp_errno, tst_strerrno(tc->exp_errno)); 69 return; 70 } 71 72 tst_res(TPASS | TTERRNO, "tee() failed as expected"); 73} 74 75static void cleanup(void) 76{ 77 if (fd > 0) 78 SAFE_CLOSE(fd); 79 80 if (pipes[0] > 0) 81 SAFE_CLOSE(pipes[0]); 82 83 if (pipes[1] > 0) 84 SAFE_CLOSE(pipes[1]); 85} 86 87static struct tst_test test = { 88 .setup = setup, 89 .cleanup = cleanup, 90 .test = tee_verify, 91 .tcnt = ARRAY_SIZE(tcases), 92 .needs_tmpdir = 1, 93}; 94