1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright (c) International Business Machines Corp., 2001 4 * 07/2001 Ported by John George 5 * 04/2002 wjhuie sigset cleanups 6 * 08/2007 Ricardo Salveti de Araujo <rsalveti@linux.vnet.ibm.com> 7 * Copyright (c) Linux Test Project, 2002-2023 8 */ 9 10/*\ 11 * [Description] 12 * 13 * Check the return value, and errnos of write(2) 14 * 15 * - when the file descriptor is invalid - EBADF 16 * - when the buf parameter is invalid - EFAULT 17 * - on an attempt to write to a pipe that is not open for reading - EPIPE 18 */ 19 20#include <sys/types.h> 21#include <sys/stat.h> 22#include <fcntl.h> 23#include <errno.h> 24#include <stdio.h> 25#include <stdlib.h> 26#include <sys/wait.h> 27#include <sys/mman.h> 28#include "tst_test.h" 29 30static int fd; 31static int inv_fd = -1; 32static char b[32]; 33static char *buf = b; 34static char *bad_addr; 35static int pipefd[2]; 36 37static struct tcase { 38 int *fd; 39 char **buf; 40 size_t size; 41 int exp_errno; 42} tcases[] = { 43 {&inv_fd, &buf, sizeof(buf), EBADF}, 44 {&fd, &bad_addr, sizeof(buf), EFAULT}, 45 {&pipefd[1], &buf, sizeof(buf), EPIPE}, 46}; 47 48static volatile int sigpipe_cnt; 49 50static void sighandler(int sig) 51{ 52 if (sig == SIGPIPE) 53 sigpipe_cnt++; 54} 55 56static void verify_write(unsigned int i) 57{ 58 struct tcase *tc = &tcases[i]; 59 60 sigpipe_cnt = 0; 61 62 TST_EXP_FAIL2(write(*tc->fd, *tc->buf, tc->size), tc->exp_errno); 63 if (TST_RET != -1) 64 return; 65 66 if (tc->exp_errno == EPIPE && sigpipe_cnt != 1) 67 tst_res(TFAIL, "sigpipe_cnt = %i", sigpipe_cnt); 68} 69 70static void setup(void) 71{ 72 fd = SAFE_OPEN("write_test", O_RDWR | O_CREAT, 0644); 73 74 bad_addr = SAFE_MMAP(0, 1, PROT_NONE, 75 MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); 76 77 SAFE_PIPE(pipefd); 78 SAFE_CLOSE(pipefd[0]); 79 80 SAFE_SIGNAL(SIGPIPE, sighandler); 81} 82 83static void cleanup(void) 84{ 85 if (fd > 0) 86 SAFE_CLOSE(fd); 87 88 SAFE_MUNMAP(bad_addr, 1); 89} 90 91static struct tst_test test = { 92 .needs_tmpdir = 1, 93 .setup = setup, 94 .cleanup = cleanup, 95 .test = verify_write, 96 .tcnt = ARRAY_SIZE(tcases), 97}; 98