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: preadv02 19 * 20 * Description: 21 * 1) preadv(2) fails if iov_len is invalid. 22 * 2) preadv(2) fails if the vector count iovcnt is less than zero. 23 * 3) preadv(2) fails if offset is negative. 24 * 4) preadv(2) fails when attempts to read into a invalid address. 25 * 5) preadv(2) fails if file descriptor is invalid. 26 * 6) preadv(2) fails if file descriptor is not open for reading. 27 * 7) preadv(2) fails when fd refers to a directory. 28 * 8) preadv(2) fails if fd is associated with a pipe. 29 * 30 * Expected Result: 31 * 1) preadv(2) should return -1 and set errno to EINVAL. 32 * 2) preadv(2) should return -1 and set errno to EINVAL. 33 * 3) preadv(2) should return -1 and set errno to EINVAL. 34 * 4) preadv(2) should return -1 and set errno to EFAULT. 35 * 5) preadv(2) should return -1 and set errno to EBADF. 36 * 6) preadv(2) should return -1 and set errno to EBADF. 37 * 7) preadv(2) should return -1 and set errno to EISDIR. 38 * 8) preadv(2) should return -1 and set errno to ESPIPE. 39 */ 40 41 #include <sys/uio.h> 42 #include <unistd.h> 43 #include "tst_test.h" 44 #include "preadv.h" 45 46 #define CHUNK 64 47 48 static int fd1; 49 static int fd2; 50 static int fd3 = -1; 51 static int fd4; 52 static int fd5[2]; 53 54 static char buf[CHUNK]; 55 56 static struct iovec rd_iovec1[] = { 57 {buf, -1}, 58 }; 59 60 static struct iovec rd_iovec2[] = { 61 {buf, CHUNK}, 62 }; 63 64 static struct iovec rd_iovec3[] = { 65 {(char *)-1, CHUNK}, 66 }; 67 68 static struct tcase { 69 int *fd; 70 struct iovec *name; 71 int count; 72 off_t offset; 73 int exp_err; 74 } tcases[] = { 75 {&fd1, rd_iovec1, 1, 0, EINVAL}, 76 {&fd1, rd_iovec2, -1, 0, EINVAL}, 77 {&fd1, rd_iovec2, 1, -1, EINVAL}, 78 {&fd1, rd_iovec3, 1, 0, EFAULT}, 79 {&fd3, rd_iovec2, 1, 0, EBADF}, 80 {&fd2, rd_iovec2, 1, 0, EBADF}, 81 {&fd4, rd_iovec2, 1, 0, EISDIR}, 82 {&fd5[0], rd_iovec2, 1, 0, ESPIPE} 83 }; 84 85 static void verify_preadv(unsigned int n) 86 { 87 struct tcase *tc = &tcases[n]; 88 89 TEST(preadv(*tc->fd, tc->name, tc->count, tc->offset)); 90 91 if (TEST_RETURN == 0) { 92 tst_res(TFAIL, "preadv() succeeded unexpectedly"); 93 return; 94 } 95 96 if (TEST_ERRNO == tc->exp_err) { 97 tst_res(TPASS | TTERRNO, "preadv() failed as expected"); 98 return; 99 } 100 101 tst_res(TFAIL | TTERRNO, "preadv() failed unexpectedly, expected %s", 102 tst_strerrno(tc->exp_err)); 103 } 104 105 static void setup(void) 106 { 107 fd1 = SAFE_OPEN("file1", O_RDWR | O_CREAT, 0644); 108 SAFE_FTRUNCATE(fd1, getpagesize()); 109 fd2 = SAFE_OPEN("file2", O_WRONLY | O_CREAT, 0644); 110 fd4 = SAFE_OPEN(".", O_RDONLY); 111 SAFE_PIPE(fd5); 112 } 113 114 static void cleanup(void) 115 { 116 if (fd1 > 0) 117 SAFE_CLOSE(fd1); 118 119 if (fd2 > 0) 120 SAFE_CLOSE(fd2); 121 122 if (fd4 > 0) 123 SAFE_CLOSE(fd4); 124 125 if (fd5[0] > 0) 126 SAFE_CLOSE(fd5[0]); 127 128 if (fd5[1] > 0) 129 SAFE_CLOSE(fd5[1]); 130 } 131 132 static struct tst_test test = { 133 .tid = "preadv02", 134 .tcnt = ARRAY_SIZE(tcases), 135 .setup = setup, 136 .cleanup = cleanup, 137 .test = verify_preadv, 138 .min_kver = "2.6.30", 139 .needs_tmpdir = 1, 140 }; 141