1 /* 2 * Copyright (c) 2015-2016 Fujitsu Ltd. 3 * Author: Xiao Yang <yangx.jy (at) cn.fujitsu.com> 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of version 2 of the GNU General Public License as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it would be useful, but 10 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 * 13 * You should have received a copy of the GNU General Public License 14 * alone with this program. 15 */ 16 17 /* 18 * Test Name: pwritev02 19 * 20 * Description: 21 * 1) pwritev(2) fails if iov_len is invalid. 22 * 2) pwritev(2) fails if the vector count iovcnt is less than zero. 23 * 3) pwritev(2) fails if offset is negative. 24 * 4) pwritev(2) fails when attempts to write from a invalid address 25 * 5) pwritev(2) fails if file descriptor is invalid. 26 * 6) pwritev(2) fails if file descriptor is not open for writing. 27 * 7) pwritev(2) fails if fd is associated with a pipe. 28 * 29 * Expected Result: 30 * 1) pwritev(2) should return -1 and set errno to EINVAL. 31 * 2) pwritev(2) should return -1 and set errno to EINVAL. 32 * 3) pwritev(2) should return -1 and set errno to EINVAL. 33 * 4) pwritev(2) should return -1 and set errno to EFAULT. 34 * 5) pwritev(2) should return -1 and set errno to EBADF. 35 * 6) pwritev(2) should return -1 and set errno to EBADF. 36 * 7) pwritev(2) should return -1 and set errno to ESPIPE. 37 */ 38 39 #include <sys/uio.h> 40 #include <unistd.h> 41 #include "tst_test.h" 42 #include "pwritev.h" 43 44 #define CHUNK 64 45 46 static int fd1; 47 static int fd2; 48 static int fd3 = -1; 49 static int fd4[2]; 50 51 static char buf[CHUNK]; 52 53 static struct iovec wr_iovec1[] = { 54 {buf, -1}, 55 }; 56 57 static struct iovec wr_iovec2[] = { 58 {buf, CHUNK}, 59 }; 60 61 static struct iovec wr_iovec3[] = { 62 {(char *)-1, CHUNK}, 63 }; 64 65 static struct tcase { 66 int *fd; 67 struct iovec *name; 68 int count; 69 off_t offset; 70 int exp_err; 71 } tcases[] = { 72 {&fd1, wr_iovec1, 1, 0, EINVAL}, 73 {&fd1, wr_iovec2, -1, 0, EINVAL}, 74 {&fd1, wr_iovec2, 1, -1, EINVAL}, 75 {&fd1, wr_iovec3, 1, 0, EFAULT}, 76 {&fd3, wr_iovec2, 1, 0, EBADF}, 77 {&fd2, wr_iovec2, 1, 0, EBADF}, 78 {&fd4[1], wr_iovec2, 1, 0, ESPIPE} 79 }; 80 81 static void verify_pwritev(unsigned int n) 82 { 83 struct tcase *tc = &tcases[n]; 84 85 TEST(pwritev(*tc->fd, tc->name, tc->count, tc->offset)); 86 if (TST_RET == 0) { 87 tst_res(TFAIL, "pwritev() succeeded unexpectedly"); 88 return; 89 } 90 91 if (TST_ERR == tc->exp_err) { 92 tst_res(TPASS | TTERRNO, "pwritev() failed as expected"); 93 return; 94 } 95 96 tst_res(TFAIL | TTERRNO, "pwritev() failed unexpectedly, expected %s", 97 tst_strerrno(tc->exp_err)); 98 } 99 100 static void setup(void) 101 { 102 fd1 = SAFE_OPEN("file", O_RDWR | O_CREAT, 0644); 103 SAFE_FTRUNCATE(fd1, getpagesize()); 104 fd2 = SAFE_OPEN("file", O_RDONLY | O_CREAT, 0644); 105 SAFE_PIPE(fd4); 106 } 107 108 static void cleanup(void) 109 { 110 if (fd1 > 0) 111 SAFE_CLOSE(fd1); 112 113 if (fd2 > 0) 114 SAFE_CLOSE(fd2); 115 116 if (fd4[0] > 0) 117 SAFE_CLOSE(fd4[0]); 118 119 if (fd4[1] > 0) 120 SAFE_CLOSE(fd4[1]); 121 } 122 123 static struct tst_test test = { 124 .tcnt = ARRAY_SIZE(tcases), 125 .setup = setup, 126 .cleanup = cleanup, 127 .test = verify_pwritev, 128 .min_kver = "2.6.30", 129 .needs_tmpdir = 1, 130 }; 131