1/* 2* Copyright (c) 2015 Fujitsu Ltd. 3* Author: Xiao Yang <yangx.jy@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 34static int fd; 35static char buf[CHUNK]; 36 37static struct iovec rd_iovec[] = { 38 {buf, CHUNK}, 39 {NULL, 0}, 40}; 41 42static 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 53void 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 %zi", 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 %zi bytes successfully " 93 "with content '%c' expectedly", tc->size, tc->content); 94} 95 96void 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 109void cleanup(void) 110{ 111 if (fd > 0) 112 SAFE_CLOSE(fd); 113} 114 115static struct tst_test test = { 116 .tcnt = ARRAY_SIZE(tcases), 117 .setup = setup, 118 .cleanup = cleanup, 119 .test = verify_preadv, 120 .min_kver = "2.6.30", 121 .needs_tmpdir = 1, 122}; 123