Home | History | Annotate | Download | only in preadv
      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: 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 
     34 static int fd;
     35 static char buf[CHUNK];
     36 
     37 static struct iovec rd_iovec[] = {
     38 	{buf, CHUNK},
     39 	{NULL, 0},
     40 };
     41 
     42 static 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 
     53 void 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 
     96 void 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 
    109 void cleanup(void)
    110 {
    111 	if (fd > 0)
    112 		SAFE_CLOSE(fd);
    113 }
    114 
    115 static 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