1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) 2015 Fujitsu Ltd.
4 * Author: Xiao Yang <yangx.jy@cn.fujitsu.com>
5 */
6
7 /*
8 * Test Name: pwritev01
9 *
10 * Test Description:
11 * Testcase to check the basic functionality of the pwritev(2).
12 * pwritev(2) should succeed to write the expected content of data
13 * and after writing the file, the file offset is not changed.
14 */
15
16 #define _GNU_SOURCE
17 #include <string.h>
18 #include <sys/uio.h>
19 #include "tst_test.h"
20 #include "pwritev.h"
21 #include "tst_safe_prw.h"
22
23 #define CHUNK 64
24
25 static char buf[CHUNK];
26 static char initbuf[CHUNK * 2];
27 static char preadbuf[CHUNK];
28 static int fd;
29
30 static struct iovec wr_iovec[] = {
31 {buf, CHUNK},
32 {NULL, 0},
33 };
34
35 static struct tcase {
36 int count;
37 off_t offset;
38 ssize_t size;
39 } tcases[] = {
40 {1, 0, CHUNK},
41 {2, 0, CHUNK},
42 {1, CHUNK/2, CHUNK},
43 };
44
verify_pwritev(unsigned int n)45 static void verify_pwritev(unsigned int n)
46 {
47 int i;
48 struct tcase *tc = &tcases[n];
49
50 SAFE_PWRITE(1, fd, initbuf, sizeof(initbuf), 0);
51
52 SAFE_LSEEK(fd, 0, SEEK_SET);
53
54 TEST(pwritev(fd, wr_iovec, tc->count, tc->offset));
55 if (TST_RET < 0) {
56 tst_res(TFAIL | TTERRNO, "pwritev() failed");
57 return;
58 }
59
60 if (TST_RET != tc->size) {
61 tst_res(TFAIL, "pwritev() wrote %li bytes, expected %zi",
62 TST_RET, tc->size);
63 return;
64 }
65
66 if (SAFE_LSEEK(fd, 0, SEEK_CUR) != 0) {
67 tst_res(TFAIL, "pwritev() had changed file offset");
68 return;
69 }
70
71 SAFE_PREAD(1, fd, preadbuf, tc->size, tc->offset);
72
73 for (i = 0; i < tc->size; i++) {
74 if (preadbuf[i] != 0x61)
75 break;
76 }
77
78 if (i != tc->size) {
79 tst_res(TFAIL, "buffer wrong at %i have %02x expected 61",
80 i, preadbuf[i]);
81 return;
82 }
83
84 tst_res(TPASS, "writev() wrote %zi bytes successfully "
85 "with content 'a' expectedly ", tc->size);
86 }
87
setup(void)88 static void setup(void)
89 {
90 memset(&buf, 0x61, CHUNK);
91
92 fd = SAFE_OPEN("file", O_RDWR | O_CREAT, 0644);
93 }
94
cleanup(void)95 static void cleanup(void)
96 {
97 if (fd > 0)
98 SAFE_CLOSE(fd);
99 }
100
101 static struct tst_test test = {
102 .tcnt = ARRAY_SIZE(tcases),
103 .setup = setup,
104 .cleanup = cleanup,
105 .test = verify_pwritev,
106 .needs_tmpdir = 1,
107 };
108