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