Home | History | Annotate | Download | only in pwritev
      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 #include <string.h>
     27 #include <sys/uio.h>
     28 #include "tst_test.h"
     29 #include "pwritev.h"
     30 
     31 #define	CHUNK		64
     32 
     33 static char buf[CHUNK];
     34 static char initbuf[CHUNK * 2];
     35 static char preadbuf[CHUNK];
     36 static int fd;
     37 
     38 static struct iovec wr_iovec[] = {
     39 	{buf, CHUNK},
     40 	{NULL, 0},
     41 };
     42 
     43 static 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 
     53 static 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 
     96 static void setup(void)
     97 {
     98 	memset(&buf, 0x61, CHUNK);
     99 
    100 	fd = SAFE_OPEN("file", O_RDWR | O_CREAT, 0644);
    101 }
    102 
    103 static void cleanup(void)
    104 {
    105 	if (fd > 0 && close(fd))
    106 		tst_res(TWARN | TERRNO, "failed to close file");
    107 }
    108 
    109 static 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