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 <fcntl.h> 39 40 #include "test.h" 41 #include "safe_macros.h" 42 43 #define TEMPFILE "pwrite_file" 44 #define K1 1024 45 46 TCID_DEFINE(pwrite02); 47 48 static char write_buf[K1]; 49 50 static void setup(void); 51 static void cleanup(void); 52 53 static void test_espipe(void); 54 static void test_einval(void); 55 static void test_ebadf1(void); 56 static void test_ebadf2(void); 57 58 #if !defined(UCLINUX) 59 static void test_efault(void); 60 #endif 61 62 static void (*testfunc[])(void) = { 63 test_espipe, test_einval, test_ebadf1, test_ebadf2, 64 #if !defined(UCLINUX) 65 test_efault 66 #endif 67 }; 68 69 int TST_TOTAL = ARRAY_SIZE(testfunc); 70 71 int main(int ac, char **av) 72 { 73 int i, lc; 74 75 tst_parse_opts(ac, av, NULL, NULL); 76 77 setup(); 78 79 for (lc = 0; TEST_LOOPING(lc); lc++) { 80 tst_count = 0; 81 82 for (i = 0; i < TST_TOTAL; i++) 83 (*testfunc[i])(); 84 } 85 86 cleanup(); 87 tst_exit(); 88 } 89 90 /* 91 * sighandler - handle SIGXFSZ 92 * 93 * This is here to start looking at a failure in test case #2. This 94 * test case passes on a machine running RedHat 6.2 but it will fail 95 * on a machine running RedHat 7.1. 96 */ 97 static void sighandler(int sig) 98 { 99 int ret; 100 101 if (sig != SIGXFSZ) { 102 ret = write(STDOUT_FILENO, "get wrong signal\n", 103 sizeof("get wrong signal\n")); 104 } else { 105 ret = write(STDOUT_FILENO, "caught SIGXFSZ\n", 106 sizeof("caught SIGXFSZ\n")); 107 } 108 109 (void)ret; 110 } 111 112 static void setup(void) 113 { 114 tst_sig(NOFORK, DEF_HANDLER, cleanup); 115 116 /* see the comment in the sighandler() function */ 117 /* call signal() to trap the signal generated */ 118 if (signal(SIGXFSZ, sighandler) == SIG_ERR) 119 tst_brkm(TBROK, cleanup, "signal() failed"); 120 121 TEST_PAUSE; 122 123 tst_tmpdir(); 124 125 memset(write_buf, 'a', K1); 126 } 127 128 static void print_test_result(int err, int exp_errno) 129 { 130 if (err == 0) { 131 tst_resm(TFAIL, "call succeeded unexpectedly"); 132 return; 133 } 134 135 if (err == exp_errno) { 136 tst_resm(TPASS, "pwrite failed as expected: %d - %s", 137 err, strerror(err)); 138 } else { 139 tst_resm(TFAIL, "pwrite failed unexpectedly; expected: %d - %s" 140 "return: %d - %s", exp_errno, strerror(exp_errno), 141 err, strerror(err)); 142 } 143 } 144 145 static void test_espipe(void) 146 { 147 int pipe_fds[2]; 148 149 SAFE_PIPE(cleanup, pipe_fds); 150 151 TEST(pwrite(pipe_fds[1], write_buf, K1, 0)); 152 153 print_test_result(errno, ESPIPE); 154 155 SAFE_CLOSE(cleanup, pipe_fds[0]); 156 SAFE_CLOSE(cleanup, pipe_fds[1]); 157 } 158 159 static void test_einval(void) 160 { 161 int fd; 162 163 fd = SAFE_OPEN(cleanup, TEMPFILE, O_RDWR | O_CREAT, 0666); 164 165 /* the specified offset was invalid */ 166 TEST(pwrite(fd, write_buf, K1, -1)); 167 168 print_test_result(errno, EINVAL); 169 170 SAFE_CLOSE(cleanup, fd); 171 } 172 173 static void test_ebadf1(void) 174 { 175 int fd = -1; 176 177 TEST(pwrite(fd, write_buf, K1, 0)); 178 179 print_test_result(errno, EBADF); 180 } 181 182 static void test_ebadf2(void) 183 { 184 int fd; 185 186 fd = SAFE_OPEN(cleanup, TEMPFILE, O_RDONLY | O_CREAT, 0666); 187 188 TEST(pwrite(fd, write_buf, K1, 0)); 189 190 print_test_result(errno, EBADF); 191 192 SAFE_CLOSE(cleanup, fd); 193 } 194 195 #if !defined(UCLINUX) 196 static void test_efault(void) 197 { 198 int fd; 199 char *buf = sbrk(0); 200 201 fd = SAFE_OPEN(cleanup, TEMPFILE, O_RDWR | O_CREAT, 0666); 202 203 TEST(pwrite(fd, buf, K1, 0)); 204 205 print_test_result(errno, EFAULT); 206 207 SAFE_CLOSE(cleanup, fd); 208 } 209 #endif 210 211 static void cleanup(void) 212 { 213 tst_rmdir(); 214 } 215