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