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 #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
verify_pwritev(unsigned int n)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
setup(void)96 static void setup(void)
97 {
98 memset(&buf, 0x61, CHUNK);
99
100 fd = SAFE_OPEN("file", O_RDWR | O_CREAT, 0644);
101 }
102
cleanup(void)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