1 /*
2 * Copyright (c) 2015-2016 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: pwritev02
19 *
20 * Description:
21 * 1) pwritev(2) fails if iov_len is invalid.
22 * 2) pwritev(2) fails if the vector count iovcnt is less than zero.
23 * 3) pwritev(2) fails if offset is negative.
24 * 4) pwritev(2) fails when attempts to write from a invalid address
25 * 5) pwritev(2) fails if file descriptor is invalid.
26 * 6) pwritev(2) fails if file descriptor is not open for writing.
27 * 7) pwritev(2) fails if fd is associated with a pipe.
28 *
29 * Expected Result:
30 * 1) pwritev(2) should return -1 and set errno to EINVAL.
31 * 2) pwritev(2) should return -1 and set errno to EINVAL.
32 * 3) pwritev(2) should return -1 and set errno to EINVAL.
33 * 4) pwritev(2) should return -1 and set errno to EFAULT.
34 * 5) pwritev(2) should return -1 and set errno to EBADF.
35 * 6) pwritev(2) should return -1 and set errno to EBADF.
36 * 7) pwritev(2) should return -1 and set errno to ESPIPE.
37 */
38
39 #include <sys/uio.h>
40 #include <unistd.h>
41 #include "tst_test.h"
42 #include "pwritev.h"
43
44 #define CHUNK 64
45
46 static int fd1;
47 static int fd2;
48 static int fd3 = -1;
49 static int fd4[2];
50
51 static char buf[CHUNK];
52
53 static struct iovec wr_iovec1[] = {
54 {buf, -1},
55 };
56
57 static struct iovec wr_iovec2[] = {
58 {buf, CHUNK},
59 };
60
61 static struct iovec wr_iovec3[] = {
62 {(char *)-1, CHUNK},
63 };
64
65 static struct tcase {
66 int *fd;
67 struct iovec *name;
68 int count;
69 off_t offset;
70 int exp_err;
71 } tcases[] = {
72 {&fd1, wr_iovec1, 1, 0, EINVAL},
73 {&fd1, wr_iovec2, -1, 0, EINVAL},
74 {&fd1, wr_iovec2, 1, -1, EINVAL},
75 {&fd1, wr_iovec3, 1, 0, EFAULT},
76 {&fd3, wr_iovec2, 1, 0, EBADF},
77 {&fd2, wr_iovec2, 1, 0, EBADF},
78 {&fd4[1], wr_iovec2, 1, 0, ESPIPE}
79 };
80
verify_pwritev(unsigned int n)81 static void verify_pwritev(unsigned int n)
82 {
83 struct tcase *tc = &tcases[n];
84
85 TEST(pwritev(*tc->fd, tc->name, tc->count, tc->offset));
86 if (TST_RET == 0) {
87 tst_res(TFAIL, "pwritev() succeeded unexpectedly");
88 return;
89 }
90
91 if (TST_ERR == tc->exp_err) {
92 tst_res(TPASS | TTERRNO, "pwritev() failed as expected");
93 return;
94 }
95
96 tst_res(TFAIL | TTERRNO, "pwritev() failed unexpectedly, expected %s",
97 tst_strerrno(tc->exp_err));
98 }
99
setup(void)100 static void setup(void)
101 {
102 fd1 = SAFE_OPEN("file", O_RDWR | O_CREAT, 0644);
103 SAFE_FTRUNCATE(fd1, getpagesize());
104 fd2 = SAFE_OPEN("file", O_RDONLY | O_CREAT, 0644);
105 SAFE_PIPE(fd4);
106 }
107
cleanup(void)108 static void cleanup(void)
109 {
110 if (fd1 > 0)
111 SAFE_CLOSE(fd1);
112
113 if (fd2 > 0)
114 SAFE_CLOSE(fd2);
115
116 if (fd4[0] > 0)
117 SAFE_CLOSE(fd4[0]);
118
119 if (fd4[1] > 0)
120 SAFE_CLOSE(fd4[1]);
121 }
122
123 static struct tst_test test = {
124 .tcnt = ARRAY_SIZE(tcases),
125 .setup = setup,
126 .cleanup = cleanup,
127 .test = verify_pwritev,
128 .min_kver = "2.6.30",
129 .needs_tmpdir = 1,
130 };
131