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 #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