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#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
35static char buf[CHUNK];
36static char initbuf[CHUNK * 2];
37static char preadbuf[CHUNK];
38static int fd;
39
40static struct iovec wr_iovec[] = {
41	{buf, CHUNK},
42	{NULL, 0},
43};
44
45static 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
55static 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 (TEST_RETURN < 0) {
66		tst_res(TFAIL | TTERRNO, "pwritev() failed");
67		return;
68	}
69
70	if (TEST_RETURN != tc->size) {
71		tst_res(TFAIL, "pwritev() wrote %li bytes, expected %zi",
72			 TEST_RETURN, 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
98static void setup(void)
99{
100	memset(&buf, 0x61, CHUNK);
101
102	fd = SAFE_OPEN("file", O_RDWR | O_CREAT, 0644);
103}
104
105static void cleanup(void)
106{
107	if (fd > 0)
108		SAFE_CLOSE(fd);
109}
110
111static 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