blob: 2b8e11a76756db738431651ec00e7f379bf837ca [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 * writev02.c
23 *
24 * DESCRIPTION
subrata_modak4bb656a2009-02-26 12:02:09 +000025 * In these testcases, writev() is called with partially valid data
plars865695b2001-08-27 22:15:12 +000026 * to be written in a sparse file.
27 *
28 * ALGORITHM
29 * The file is created and write() is called with valid buffer to write
30 * at some 8k th offset. After that writev() will be called with invalid
31 * vector. This should return EFAULT. And at the same time, try looking at
32 * the 8kth offset whether the file is intact or not.
33 *
34 * USAGE: <for command-line>
35 * writev02 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
36 * where, -c n : Run n copies concurrently.
37 * -e : Turn on errno logging.
38 * -i n : Execute test n times.
39 * -I x : Execute test for x seconds.
40 * -P x : Pause for x seconds between iterations.
41 * -t : Turn on syscall timing.
42 *
43 * History
44 * 07/2001 John George
45 * -Ported
robbiew4644c7e2002-04-26 14:33:32 +000046 * 04/2002 wjhuie sigset cleanups
plars865695b2001-08-27 22:15:12 +000047 *
48 * Restrictions
49 * None
50 */
51
52#include <sys/types.h>
53#include <signal.h>
54#include <sys/uio.h>
55#include <fcntl.h>
56#include <memory.h>
57#include <errno.h>
Garrett Coopere8530df2010-12-21 11:37:57 -080058#include "test.h"
robbiewa21a8b32003-11-14 16:52:38 +000059#include <sys/mman.h>
plars865695b2001-08-27 22:15:12 +000060
61#define K_1 8192
62
63#define NBUFS 2
subrata_modak56207ce2009-03-23 13:35:39 +000064#define CHUNK K_1 /* single chunk */
plars865695b2001-08-27 22:15:12 +000065#define MAX_IOVEC 2
66#define DATA_FILE "writev_data_file"
67
subrata_modak56207ce2009-03-23 13:35:39 +000068char buf1[K_1];
69char buf2[K_1];
plars865695b2001-08-27 22:15:12 +000070
subrata_modak56207ce2009-03-23 13:35:39 +000071char *bad_addr = 0;
robbiewa21a8b32003-11-14 16:52:38 +000072
subrata_modak56207ce2009-03-23 13:35:39 +000073struct iovec wr_iovec[MAX_IOVEC] = {
Wanlong Gao354ebb42012-12-07 10:10:04 +080074 {(caddr_t) - 1, CHUNK},
Cyril Hrubiscf0d6262014-09-23 14:03:31 +020075 {NULL, 0},
plars865695b2001-08-27 22:15:12 +000076};
77
subrata_modak56207ce2009-03-23 13:35:39 +000078char name[K_1], f_name[K_1];
plars865695b2001-08-27 22:15:12 +000079
subrata_modak56207ce2009-03-23 13:35:39 +000080int fd[2], in_sighandler;
81char *buf_list[NBUFS];
plars865695b2001-08-27 22:15:12 +000082
83char *TCID = "writev02";
84int TST_TOTAL = 1;
plars865695b2001-08-27 22:15:12 +000085
86void sighandler(int);
Garrett Cooper2aca6fc2010-12-19 03:12:40 -080087void l_seek(int, off_t, int);
plars865695b2001-08-27 22:15:12 +000088void setup(void);
89void cleanup(void);
90int fail;
91
robbiew7d5c5172003-03-27 22:54:57 +000092int main(int argc, char **argv)
plars865695b2001-08-27 22:15:12 +000093{
Cyril Hrubis89af32a2012-10-24 16:39:11 +020094 int lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +020095 const char *msg;
plars865695b2001-08-27 22:15:12 +000096
97 int nbytes;
98
Garrett Cooper2aca6fc2010-12-19 03:12:40 -080099 if ((msg = parse_opts(argc, argv, NULL, NULL)) != NULL)
plars865695b2001-08-27 22:15:12 +0000100 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
Garrett Cooper2c282152010-12-16 00:55:50 -0800101
Garrett Cooper2aca6fc2010-12-19 03:12:40 -0800102 setup();
plars865695b2001-08-27 22:15:12 +0000103
plars865695b2001-08-27 22:15:12 +0000104 for (lc = 0; TEST_LOOPING(lc); lc++) {
105
Caspar Zhangd59a6592013-03-07 14:59:12 +0800106 tst_count = 0;
plars865695b2001-08-27 22:15:12 +0000107
108 buf_list[0] = buf1;
109 buf_list[1] = buf2;
110
plars865695b2001-08-27 22:15:12 +0000111 memset(buf_list[0], 0, K_1);
112 memset(buf_list[1], 0, K_1);
113
subrata_modak56207ce2009-03-23 13:35:39 +0000114 fd[1] = -1; /* Invalid file descriptor */
plars865695b2001-08-27 22:15:12 +0000115
Garrett Cooper2aca6fc2010-12-19 03:12:40 -0800116 if (signal(SIGTERM, sighandler) == SIG_ERR)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800117 tst_brkm(TFAIL | TERRNO, cleanup,
118 "signal(SIGTERM, ..)");
plars865695b2001-08-27 22:15:12 +0000119
Garrett Cooper2aca6fc2010-12-19 03:12:40 -0800120 if (signal(SIGPIPE, sighandler) == SIG_ERR)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800121 tst_brkm(TFAIL | TERRNO, cleanup,
122 "signal(SIGPIPE, ..)");
plars865695b2001-08-27 22:15:12 +0000123
Wanlong Gao354ebb42012-12-07 10:10:04 +0800124 if ((fd[0] = open(f_name, O_WRONLY | O_CREAT, 0666)) < 0)
125 tst_brkm(TFAIL | TERRNO, cleanup,
126 "open(.., O_WRONLY|O_CREAT, ..) failed");
Garrett Cooper2aca6fc2010-12-19 03:12:40 -0800127 else {
plars865695b2001-08-27 22:15:12 +0000128 l_seek(fd[0], K_1, 0);
Garrett Cooper2aca6fc2010-12-19 03:12:40 -0800129 if ((nbytes = write(fd[0], buf_list[1], K_1)) != K_1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800130 tst_brkm(TFAIL | TERRNO, cleanup,
131 "write failed");
plars865695b2001-08-27 22:15:12 +0000132 }
133
Garrett Cooper2aca6fc2010-12-19 03:12:40 -0800134 if (close(fd[0]) == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800135 tst_brkm(TFAIL | TERRNO, cleanup, "close failed");
plars865695b2001-08-27 22:15:12 +0000136
Garrett Cooper2aca6fc2010-12-19 03:12:40 -0800137 if ((fd[0] = open(f_name, O_RDWR, 0666)) < 0)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800138 tst_brkm(TFAIL | TERRNO, cleanup,
139 "open(.., O_RDWR, ..) failed");
robbiew7d5c5172003-03-27 22:54:57 +0000140//block1:
plars865695b2001-08-27 22:15:12 +0000141 /*
142 * In this block we are trying to call writev() with invalid
143 * vector to be written in a sparse file. This will return
144 * EFAULT. At the same time, check should be made whether
145 * the scheduled write() with valid data at 8k th offset is
146 * done correctly or not.
147 */
148 tst_resm(TINFO, "Enter block 1");
plars865695b2001-08-27 22:15:12 +0000149
150 l_seek(fd[0], 0, 0);
plars1ad84512002-07-23 13:11:18 +0000151 TEST(writev(fd[0], wr_iovec, 2));
plars865695b2001-08-27 22:15:12 +0000152 if (TEST_RETURN < 0) {
plars865695b2001-08-27 22:15:12 +0000153 if (TEST_ERRNO == EFAULT) {
Garrett Cooper2aca6fc2010-12-19 03:12:40 -0800154 tst_resm(TPASS, "Received EFAULT as expected");
plars865695b2001-08-27 22:15:12 +0000155 } else if (TEST_ERRNO != EFAULT) {
156 tst_resm(TFAIL, "Expected EFAULT, got %d",
157 TEST_ERRNO);
plars865695b2001-08-27 22:15:12 +0000158 }
159 l_seek(fd[0], K_1, 0);
subrata_modak56207ce2009-03-23 13:35:39 +0000160 if ((nbytes = read(fd[0], buf_list[0], CHUNK)) != CHUNK) {
plars865695b2001-08-27 22:15:12 +0000161 tst_resm(TFAIL, "Expected nbytes = 64, got "
162 "%d", nbytes);
plars865695b2001-08-27 22:15:12 +0000163 } else {
164 if (memcmp(buf_list[0], buf_list[1], CHUNK)
Garrett Cooper2aca6fc2010-12-19 03:12:40 -0800165 != 0)
plars865695b2001-08-27 22:15:12 +0000166 tst_resm(TFAIL, "Error: writev() "
167 "over wrote %s", f_name);
plars865695b2001-08-27 22:15:12 +0000168 }
Garrett Cooper2aca6fc2010-12-19 03:12:40 -0800169 } else
plars865695b2001-08-27 22:15:12 +0000170 tst_resm(TFAIL, "Error writev returned a positive "
171 "value");
plars865695b2001-08-27 22:15:12 +0000172 tst_resm(TINFO, "Exit block 1");
173 }
174 cleanup();
Garrett Cooper2c282152010-12-16 00:55:50 -0800175 tst_exit();
vapier6925ca32006-02-27 04:25:25 +0000176}
177
subrata_modak56207ce2009-03-23 13:35:39 +0000178void setup(void)
plars865695b2001-08-27 22:15:12 +0000179{
Garrett Cooper2aca6fc2010-12-19 03:12:40 -0800180 tst_sig(FORK, sighandler, cleanup);
Garrett Cooper2c282152010-12-16 00:55:50 -0800181
plars865695b2001-08-27 22:15:12 +0000182 TEST_PAUSE;
183
plars865695b2001-08-27 22:15:12 +0000184 tst_tmpdir();
185
186 strcpy(name, DATA_FILE);
187 sprintf(f_name, "%s.%d", name, getpid());
robbiewa21a8b32003-11-14 16:52:38 +0000188
subrata_modak56207ce2009-03-23 13:35:39 +0000189 bad_addr = mmap(0, 1, PROT_NONE,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800190 MAP_PRIVATE_EXCEPT_UCLINUX | MAP_ANONYMOUS, 0, 0);
Garrett Cooper2aca6fc2010-12-19 03:12:40 -0800191 if (bad_addr == MAP_FAILED)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800192 tst_brkm(TBROK | TERRNO, cleanup, "mmap failed");
subrata_modak56207ce2009-03-23 13:35:39 +0000193 wr_iovec[0].iov_base = bad_addr;
robbiewa21a8b32003-11-14 16:52:38 +0000194
plars865695b2001-08-27 22:15:12 +0000195}
196
subrata_modak56207ce2009-03-23 13:35:39 +0000197void cleanup(void)
plars865695b2001-08-27 22:15:12 +0000198{
Garrett Cooper2aca6fc2010-12-19 03:12:40 -0800199 close(fd[0]);
200 close(fd[1]);
201
202 if (munmap(bad_addr, 1) == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800203 tst_resm(TWARN | TERRNO, "unmap failed");
Garrett Cooper2aca6fc2010-12-19 03:12:40 -0800204 if (unlink(f_name) == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800205 tst_resm(TWARN | TERRNO, "unlink failed");
Garrett Cooper2aca6fc2010-12-19 03:12:40 -0800206
plars865695b2001-08-27 22:15:12 +0000207 tst_rmdir();
208
plars865695b2001-08-27 22:15:12 +0000209}
210
subrata_modak56207ce2009-03-23 13:35:39 +0000211void sighandler(int sig)
plars865695b2001-08-27 22:15:12 +0000212{
subrata_modak56207ce2009-03-23 13:35:39 +0000213 switch (sig) {
214 case SIGTERM:
215 break;
216 case SIGPIPE:
217 ++in_sighandler;
218 return;
plars865695b2001-08-27 22:15:12 +0000219 default:
Garrett Cooper2aca6fc2010-12-19 03:12:40 -0800220 tst_resm(TBROK, "sighandler received invalid signal : %d", sig);
subrata_modak56207ce2009-03-23 13:35:39 +0000221 break;
plars865695b2001-08-27 22:15:12 +0000222 }
223
Garrett Cooper2aca6fc2010-12-19 03:12:40 -0800224 if (unlink(f_name) == -1 && errno != ENOENT)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800225 tst_resm(TFAIL | TERRNO, "unlink failed");
plars865695b2001-08-27 22:15:12 +0000226}
227
228/*
229 * l_seek()
230 * Wrap around for regular lseek function for giving error message
231 */
Garrett Cooper2aca6fc2010-12-19 03:12:40 -0800232void l_seek(int fdesc, off_t offset, int whence)
plars865695b2001-08-27 22:15:12 +0000233{
Garrett Cooper2aca6fc2010-12-19 03:12:40 -0800234 if (lseek(fdesc, offset, whence) == -1)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800235 tst_resm(TBROK | TERRNO, "lseek failed");
Garrett Cooper2aca6fc2010-12-19 03:12:40 -0800236}