1 /* 2 * Copyright (c) 2015 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: preadv01 19 * 20 * Test Description: 21 * Testcase to check the basic functionality of the preadv(2). 22 * Preadv(2) should succeed to read the expected content of data 23 * and after reading the file, the file offset is not changed. 24 */ 25 26 #include <string.h> 27 #include <sys/uio.h> 28 29 #include "tst_test.h" 30 #include "preadv.h" 31 32 #define CHUNK 64 33 34 static int fd; 35 static char buf[CHUNK]; 36 37 static struct iovec rd_iovec[] = { 38 {buf, CHUNK}, 39 {NULL, 0}, 40 }; 41 42 static struct tcase { 43 int count; 44 off_t offset; 45 ssize_t size; 46 char content; 47 } tcases[] = { 48 {1, 0, CHUNK, 'a'}, 49 {2, 0, CHUNK, 'a'}, 50 {1, CHUNK*3/2, CHUNK/2, 'b'} 51 }; 52 53 void verify_preadv(unsigned int n) 54 { 55 int i; 56 char *vec; 57 struct tcase *tc = &tcases[n]; 58 59 vec = rd_iovec[0].iov_base; 60 memset(vec, 0x00, CHUNK); 61 62 SAFE_LSEEK(fd, 0, SEEK_SET); 63 64 TEST(preadv(fd, rd_iovec, tc->count, tc->offset)); 65 if (TEST_RETURN < 0) { 66 tst_res(TFAIL | TTERRNO, "Preadv(2) failed"); 67 return; 68 } 69 70 if (TEST_RETURN != tc->size) { 71 tst_res(TFAIL, "Preadv(2) read %li bytes, expected %li", 72 TEST_RETURN, tc->size); 73 return; 74 } 75 76 for (i = 0; i < tc->size; i++) { 77 if (vec[i] != tc->content) 78 break; 79 } 80 81 if (i < tc->size) { 82 tst_res(TFAIL, "Buffer wrong at %i have %02x expected %02x", 83 i, vec[i], tc->content); 84 return; 85 } 86 87 if (SAFE_LSEEK(fd, 0, SEEK_CUR) != 0) { 88 tst_res(TFAIL, "Preadv(2) has changed file offset"); 89 return; 90 } 91 92 tst_res(TPASS, "Preadv(2) read %li bytes successfully " 93 "with content '%c' expectedly", tc->size, tc->content); 94 } 95 96 void setup(void) 97 { 98 char buf[CHUNK]; 99 100 fd = SAFE_OPEN("file", O_RDWR | O_CREAT, 0644); 101 102 memset(buf, 'a', sizeof(buf)); 103 SAFE_WRITE(1, fd, buf, sizeof(buf)); 104 105 memset(buf, 'b', sizeof(buf)); 106 SAFE_WRITE(1, fd, buf, sizeof(buf)); 107 } 108 109 void cleanup(void) 110 { 111 if (fd > 0) 112 SAFE_CLOSE(fd); 113 } 114 115 static struct tst_test test = { 116 .tid = "preadv01", 117 .tcnt = ARRAY_SIZE(tcases), 118 .setup = setup, 119 .cleanup = cleanup, 120 .test = verify_preadv, 121 .min_kver = "2.6.30", 122 .needs_tmpdir = 1, 123 }; 124