blob: 50459ffac3b4df53dd23230631f2fb7f18cd7902 [file] [log] [blame]
plars865695b2001-08-27 22:15:12 +00001/*
2 *
3 * Copyright (c) International Business Machines Corp., 2001
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13 * the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
Wanlong Gao4548c6c2012-10-19 18:03:36 +080017 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
plars865695b2001-08-27 22:15:12 +000018 */
19
20/*
21 * NAME
22 * readv02.c
23 *
24 * DESCRIPTION
25 * Testcase to check the error conditions of the readv(2) system call.
26 *
27 * CALLS
28 * readv()
29 *
30 * ALGORITHM
31 * Create a IO vector, and attempt to readv() various components of it.
32 *
33 * USAGE
34 * readv02
35 *
36 * HISTORY
37 * 07/2001 Ported by Wayne Boyer
38 *
39 * RESTRICTIONS
40 * None
41 */
42#include <sys/types.h>
43#include <sys/uio.h>
44#include <sys/fcntl.h>
plars1ad84512002-07-23 13:11:18 +000045#include <sys/mman.h>
plars865695b2001-08-27 22:15:12 +000046#include <memory.h>
47#include <errno.h>
48
49#include "test.h"
plars865695b2001-08-27 22:15:12 +000050
51#define K_1 1024
52#define M_1 K_1 * K_1
53#define G_1 M_1 * K_1
54
55#define NBUFS 4
56#define CHUNK 64
57#define MAX_IOVEC 16
58#define DATA_FILE "readv_data_file"
59
60char buf1[K_1], buf2[K_1], buf3[K_1];
61
62struct iovec rd_iovec[MAX_IOVEC] = {
subrata_modak56207ce2009-03-23 13:35:39 +000063 /* iov_base *//* iov_len */
plars865695b2001-08-27 22:15:12 +000064
65 /* Test case #1 */
subrata_modak56207ce2009-03-23 13:35:39 +000066 {buf2, -1},
67 {(buf2 + CHUNK), CHUNK},
68 {(buf2 + CHUNK * 2), CHUNK},
plars865695b2001-08-27 22:15:12 +000069
70 /* Test case #2 */
subrata_modak56207ce2009-03-23 13:35:39 +000071 {(buf2 + CHUNK * 3), G_1},
72 {(buf2 + CHUNK * 4), G_1},
73 {(buf2 + CHUNK * 5), G_1},
plars865695b2001-08-27 22:15:12 +000074
75 /* Test case #3 */
subrata_modak56207ce2009-03-23 13:35:39 +000076 {(caddr_t) - 1, CHUNK},
77 {(buf2 + CHUNK * 6), CHUNK},
78 {(buf2 + CHUNK * 8), CHUNK},
plars865695b2001-08-27 22:15:12 +000079
80 /* Test case #4 */
subrata_modak56207ce2009-03-23 13:35:39 +000081 {(buf2 + CHUNK * 9), CHUNK}
plars865695b2001-08-27 22:15:12 +000082};
83
84char f_name[K_1];
85
86int fd[4];
87char *buf_list[NBUFS];
88
89char *TCID = "readv02";
90int TST_TOTAL = 1;
plars865695b2001-08-27 22:15:12 +000091
subrata_modak56207ce2009-03-23 13:35:39 +000092char *bad_addr = 0;
plars1ad84512002-07-23 13:11:18 +000093
plars865695b2001-08-27 22:15:12 +000094int init_buffs(char **);
95int fill_mem(char *, int, int);
96long l_seek(int, long, int);
97char *getenv();
98void setup();
99void cleanup();
100
robbiew0c7e81c2003-03-27 17:44:57 +0000101int main(int ac, char **av)
plars865695b2001-08-27 22:15:12 +0000102{
Cyril Hrubis89af32a2012-10-24 16:39:11 +0200103 int lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +0200104 const char *msg;
plars865695b2001-08-27 22:15:12 +0000105
Garrett Cooper45e285d2010-11-22 12:19:25 -0800106 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) {
Garrett Cooper60fa8012010-11-22 13:50:58 -0800107 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
Wanlong Gao354ebb42012-12-07 10:10:04 +0800108 }
plars865695b2001-08-27 22:15:12 +0000109
110 setup();
111
112 /* The following loop checks looping state if -i option given */
113 for (lc = 0; TEST_LOOPING(lc); lc++) {
114
Caspar Zhangd59a6592013-03-07 14:59:12 +0800115 /* reset tst_count in case we are looping */
116 tst_count = 0;
plars865695b2001-08-27 22:15:12 +0000117
robbiew0c7e81c2003-03-27 17:44:57 +0000118//test1:
plars865695b2001-08-27 22:15:12 +0000119 if (readv(fd[0], rd_iovec, 1) < 0) {
120 if (errno != EINVAL) {
121 tst_resm(TFAIL, "readv() set an illegal errno:"
122 " expected: EINVAL, got %d", errno);
123 } else {
124 tst_resm(TPASS, "got EINVAL");
125 }
126 } else {
127 tst_resm(TFAIL, "Error: readv returned a positive "
128 "value");
129 }
130
robbiew0c7e81c2003-03-27 17:44:57 +0000131//test2:
plars865695b2001-08-27 22:15:12 +0000132 l_seek(fd[0], CHUNK * 6, 0);
133 if (readv(fd[0], (rd_iovec + 6), 3) < 0) {
134 if (errno != EFAULT) {
135 tst_resm(TFAIL, "expected errno = EFAULT, "
vapier8dcffd82009-08-28 13:36:50 +0000136 "got %d", errno);
plars865695b2001-08-27 22:15:12 +0000137 } else {
138 tst_resm(TPASS, "got EFAULT");
139 }
140 if (memcmp((buf_list[0] + CHUNK * 6),
141 (buf_list[1] + CHUNK * 6), CHUNK * 3) != 0) {
142 tst_resm(TFAIL, "Error: readv() partially "
143 "overlaid buf[2]");
144 }
145 } else {
146 tst_resm(TFAIL, "Error: readv returned a positive "
147 "value");
148 }
149
robbiew0c7e81c2003-03-27 17:44:57 +0000150//test3:
plars865695b2001-08-27 22:15:12 +0000151 if (readv(fd[1], (rd_iovec + 9), 1) < 0) {
152 if (errno != EBADF) {
153 tst_resm(TFAIL, "expected errno = EBADF, "
154 "got %d", errno);
155 } else {
156 tst_resm(TPASS, "got EBADF");
157 }
158 } else {
159 tst_resm(TFAIL, "Error: readv returned a positive "
160 "value");
161 }
162
robbiew0c7e81c2003-03-27 17:44:57 +0000163//test4:
plars865695b2001-08-27 22:15:12 +0000164 l_seek(fd[0], CHUNK * 10, 0);
165 if (readv(fd[0], (rd_iovec + 10), -1) < 0) {
166 if (errno != EINVAL) {
167 tst_resm(TFAIL, "expected errno = EINVAL, "
168 "got %d", errno);
169 } else {
170 tst_resm(TPASS, "got EINVAL");
171 }
172 } else {
173 tst_resm(TFAIL, "Error: readv returned a positive "
174 "value");
175 }
176
177 }
subrata_modakdad6e1a2007-10-30 10:46:58 +0000178 close(fd[0]);
179 close(fd[1]);
plars865695b2001-08-27 22:15:12 +0000180 cleanup();
Garrett Cooper1e6f5a62010-12-19 09:58:10 -0800181 tst_exit();
plars865695b2001-08-27 22:15:12 +0000182
plars865695b2001-08-27 22:15:12 +0000183}
184
185/*
186 * setup() - performs all ONE TIME setup for this test.
187 */
Mike Frysingerc57fba52014-04-09 18:56:30 -0400188void setup(void)
plars865695b2001-08-27 22:15:12 +0000189{
190 int nbytes;
191
plars865695b2001-08-27 22:15:12 +0000192 tst_sig(NOFORK, DEF_HANDLER, cleanup);
193
plars865695b2001-08-27 22:15:12 +0000194 TEST_PAUSE;
195
196 /* make a temporary directory and cd to it */
197 tst_tmpdir();
198
199 buf_list[0] = buf1;
200 buf_list[1] = buf2;
201 buf_list[2] = buf3;
Garrett Cooper45e285d2010-11-22 12:19:25 -0800202 buf_list[3] = NULL;
plars865695b2001-08-27 22:15:12 +0000203
204 init_buffs(buf_list);
205
206 sprintf(f_name, "%s.%d", DATA_FILE, getpid());
207
208 if ((fd[0] = open(f_name, O_WRONLY | O_CREAT, 0666)) < 0) {
209 tst_brkm(TBROK, cleanup, "open failed: fname = %s, "
210 "errno = %d", f_name, errno);
211 } else {
212 if ((nbytes = write(fd[0], buf_list[2], K_1)) != K_1) {
213 tst_brkm(TBROK, cleanup, "write failed: nbytes "
214 "= %d " "errno = %d", nbytes, errno);
215 }
216 }
217
218 if (close(fd[0]) < 0) {
219 tst_brkm(TBROK, cleanup, "close failed: errno = %d", errno);
220 }
221
222 if ((fd[0] = open(f_name, O_RDONLY, 0666)) < 0) {
223 tst_brkm(TBROK, cleanup, "open failed: fname = %s, "
224 "errno = %d", f_name, errno);
225 }
226
227 fd[1] = -1; /* Invalid file descriptor */
plars1ad84512002-07-23 13:11:18 +0000228
robbiewd34d5812005-07-11 22:28:09 +0000229 bad_addr = mmap(0, 1, PROT_NONE,
subrata_modak56207ce2009-03-23 13:35:39 +0000230 MAP_PRIVATE_EXCEPT_UCLINUX | MAP_ANONYMOUS, 0, 0);
vapier0722a2b2006-05-12 15:44:11 +0000231 if (bad_addr == MAP_FAILED) {
plars1ad84512002-07-23 13:11:18 +0000232 tst_brkm(TBROK, cleanup, "mmap failed");
233 }
234 rd_iovec[6].iov_base = bad_addr;
plars865695b2001-08-27 22:15:12 +0000235}
236
237/*
238 * cleanup() - performs all ONE TIME cleanup for this test at
239 * completion or premature exit.
240 */
Mike Frysingerc57fba52014-04-09 18:56:30 -0400241void cleanup(void)
plars865695b2001-08-27 22:15:12 +0000242{
243 if (unlink(f_name) < 0) {
244 tst_brkm(TBROK, NULL, "unlink FAILED: file %s, errno %d",
245 f_name, errno);
246 }
247 tst_rmdir();
Garrett Cooper2c282152010-12-16 00:55:50 -0800248
plars865695b2001-08-27 22:15:12 +0000249}
250
subrata_modak56207ce2009-03-23 13:35:39 +0000251int init_buffs(char *pbufs[])
plars865695b2001-08-27 22:15:12 +0000252{
253 int i;
254
Garrett Cooper45e285d2010-11-22 12:19:25 -0800255 for (i = 0; pbufs[i] != NULL; i++) {
plars865695b2001-08-27 22:15:12 +0000256 switch (i) {
257 case 0:
subrata_modak56207ce2009-03-23 13:35:39 +0000258 /*FALLTHROUGH*/ case 1:
plars865695b2001-08-27 22:15:12 +0000259 fill_mem(pbufs[i], 0, 1);
260 break;
261
262 case 2:
263 fill_mem(pbufs[i], 1, 0);
264 break;
265
266 default:
267 tst_brkm(TBROK, cleanup, "Error in init_buffs()");
268 }
269 }
subrata_modak43337a32009-02-26 11:43:51 +0000270 return 0;
plars865695b2001-08-27 22:15:12 +0000271}
272
subrata_modak56207ce2009-03-23 13:35:39 +0000273int fill_mem(char *c_ptr, int c1, int c2)
plars865695b2001-08-27 22:15:12 +0000274{
275 int count;
276
277 for (count = 1; count <= K_1 / CHUNK; count++) {
278 if (count & 0x01) { /* if odd */
279 memset(c_ptr, c1, CHUNK);
subrata_modak56207ce2009-03-23 13:35:39 +0000280 } else { /* if even */
plars865695b2001-08-27 22:15:12 +0000281 memset(c_ptr, c2, CHUNK);
282 }
283 }
subrata_modak43337a32009-02-26 11:43:51 +0000284 return 0;
plars865695b2001-08-27 22:15:12 +0000285}
286
subrata_modak56207ce2009-03-23 13:35:39 +0000287long l_seek(int fdesc, long offset, int whence)
plars865695b2001-08-27 22:15:12 +0000288{
289 if (lseek(fdesc, offset, whence) < 0) {
290 tst_brkm(TBROK, cleanup, "lseek Failed : errno = %d", errno);
291 }
subrata_modak43337a32009-02-26 11:43:51 +0000292 return 0;
Chris Dearmanec6edca2012-10-17 19:54:01 -0700293}