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