1 /* 2 * 3 * Copyright (c) International Business Machines Corp., 2001 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 13 * the GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 */ 19 20 /* 21 * Test Description: 22 * Verify that, 23 * 1) pwrite() fails when attempted to write to an unnamed pipe, 24 * returns ESPIPE. 25 * 2) pwrite() fails if the specified offset position was invalid, 26 * returns EINVAL. 27 * 3) pwrite() fails if fd is not a valid file descriptor, 28 * returns EBADF. 29 * 4) pwrite() fails if fd is not open for writing, return EBADF. 30 * 5) pwrite() fails when attempted to write with buf outside 31 * accessible address space, returns EFAULT. 32 */ 33 34 #define _XOPEN_SOURCE 500 35 36 #include <errno.h> 37 #include <unistd.h> 38 #include <string.h> 39 40 #include "tst_test.h" 41 42 #define TEMPFILE "pwrite_file" 43 #define BS 1024 44 45 static int fd; 46 static int fd_ro; 47 static int inv_fd = -1; 48 static int pipe_fds[2]; 49 static char buf[BS]; 50 51 static struct tcase { 52 void *buf; 53 size_t size; 54 int *fd; 55 off_t off; 56 int exp_errno; 57 } tcases[] = { 58 {buf, sizeof(buf), &pipe_fds[1], 0, ESPIPE}, 59 {buf, sizeof(buf), &fd, -1, EINVAL}, 60 {buf, sizeof(buf), &inv_fd, 0, EBADF}, 61 {buf, sizeof(buf), &fd_ro, 0, EBADF}, 62 {NULL, sizeof(buf), &fd, 0, EFAULT}, 63 }; 64 65 /* 66 * sighandler - handle SIGXFSZ 67 * 68 * This is here to start looking at a failure in test case #2. This 69 * test case passes on a machine running RedHat 6.2 but it will fail 70 * on a machine running RedHat 7.1. 71 */ 72 static void sighandler(int sig) 73 { 74 int ret; 75 76 if (sig != SIGXFSZ) { 77 ret = write(STDOUT_FILENO, "get wrong signal\n", 78 sizeof("get wrong signal\n")); 79 } else { 80 ret = write(STDOUT_FILENO, "caught SIGXFSZ\n", 81 sizeof("caught SIGXFSZ\n")); 82 } 83 84 (void)ret; 85 } 86 87 static void verify_pwrite(unsigned int i) 88 { 89 struct tcase *tc = &tcases[i]; 90 91 TEST(pwrite(*tc->fd, tc->buf, BS, tc->off)); 92 93 if (TST_RET >= 0) { 94 tst_res(TFAIL, "call succeeded unexpectedly"); 95 return; 96 } 97 98 if (TST_ERR != tc->exp_errno) { 99 tst_res(TFAIL | TTERRNO, 100 "pwrite failed unexpectedly, expected %s", 101 tst_strerrno(tc->exp_errno)); 102 } 103 104 tst_res(TPASS | TTERRNO, "pwrite failed as expected"); 105 } 106 107 static void setup(void) 108 { 109 SAFE_SIGNAL(SIGXFSZ, sighandler); 110 111 SAFE_PIPE(pipe_fds); 112 113 fd = SAFE_OPEN(TEMPFILE, O_RDWR | O_CREAT, 0666); 114 fd_ro = SAFE_OPEN(TEMPFILE, O_RDONLY | O_CREAT, 0666); 115 } 116 117 static void cleanup(void) 118 { 119 if (fd > 0) 120 SAFE_CLOSE(fd); 121 122 if (fd_ro > 0) 123 SAFE_CLOSE(fd_ro); 124 125 if (pipe_fds[0] > 0) 126 SAFE_CLOSE(pipe_fds[0]); 127 128 if (pipe_fds[1] > 0) 129 SAFE_CLOSE(pipe_fds[1]); 130 } 131 132 static struct tst_test test = { 133 .needs_tmpdir = 1, 134 .setup = setup, 135 .cleanup = cleanup, 136 .test = verify_pwrite, 137 .tcnt = ARRAY_SIZE(tcases), 138 }; 139