blob: c0a79958da7db2af10f13b5abcff8f8c216f56cc [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 * writev05.c
23 *
24 * DESCRIPTION
25 * These testcases are written to test writev() on sparse files. This
26 * is same as writev02.c. But the initial write() with valid data is
27 * done at the beginning of the file.
28 *
29 * USAGE: <for command-line>
30 * writev05 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
31 * where, -c n : Run n copies concurrently.
32 * -e : Turn on errno logging.
33 * -i n : Execute test n times.
34 * -I x : Execute test for x seconds.
35 * -P x : Pause for x seconds between iterations.
36 * -t : Turn on syscall timing.
subrata_modakbdbaec52009-02-26 12:14:51 +000037 *
plars865695b2001-08-27 22:15:12 +000038 * History
39 * 07/2001 John George
40 * -Ported
robbiew4644c7e2002-04-26 14:33:32 +000041 * 04/2002 wjhuie sigset cleanups
plars865695b2001-08-27 22:15:12 +000042 *
43 * Restrictions
44 * NONE
45 */
46
47#include <sys/types.h>
48#include <signal.h>
49#include <sys/uio.h>
50#include <fcntl.h>
51#include <memory.h>
52#include <errno.h>
Garrett Coopere8530df2010-12-21 11:37:57 -080053#include "test.h"
robbiew37d19bd2003-11-14 16:57:49 +000054#include <sys/mman.h>
plars865695b2001-08-27 22:15:12 +000055
56#define K_1 8192
57
58#define NBUFS 2
subrata_modak56207ce2009-03-23 13:35:39 +000059#define CHUNK K_1 /* single chunk */
plars865695b2001-08-27 22:15:12 +000060#define MAX_IOVEC 2
61#define DATA_FILE "writev_data_file"
62
subrata_modak56207ce2009-03-23 13:35:39 +000063char buf1[K_1];
64char buf2[K_1];
65char buf3[K_1];
plars865695b2001-08-27 22:15:12 +000066
subrata_modak56207ce2009-03-23 13:35:39 +000067char *bad_addr = 0;
robbiew37d19bd2003-11-14 16:57:49 +000068
subrata_modak56207ce2009-03-23 13:35:39 +000069struct iovec wr_iovec[MAX_IOVEC] = {
70 {(caddr_t) - 1, CHUNK},
Cyril Hrubiscf0d6262014-09-23 14:03:31 +020071 {NULL, 0}
plars865695b2001-08-27 22:15:12 +000072};
73
subrata_modak56207ce2009-03-23 13:35:39 +000074char name[K_1], f_name[K_1];
75int fd[2], in_sighandler;
76char *buf_list[NBUFS];
plars865695b2001-08-27 22:15:12 +000077
78char *TCID = "writev05";
79int TST_TOTAL = 1;
plars865695b2001-08-27 22:15:12 +000080
81void sighandler(int);
82long l_seek(int, long, int);
83void setup(void);
84void cleanup(void);
85int fail;
86
vapier6925ca32006-02-27 04:25:25 +000087#if !defined(UCLINUX)
88
robbiew7d5c5172003-03-27 22:54:57 +000089int main(int argc, char **argv)
plars865695b2001-08-27 22:15:12 +000090{
Cyril Hrubis89af32a2012-10-24 16:39:11 +020091 int lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +020092 const char *msg;
plars865695b2001-08-27 22:15:12 +000093
94 int nbytes;
95
Wanlong Gao354ebb42012-12-07 10:10:04 +080096 if ((msg = parse_opts(argc, argv, NULL, NULL)) != NULL) {
plars865695b2001-08-27 22:15:12 +000097 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
Wanlong Gao354ebb42012-12-07 10:10:04 +080098 }
plars865695b2001-08-27 22:15:12 +000099
subrata_modak56207ce2009-03-23 13:35:39 +0000100 setup(); /* set "tstdir", and "testfile" vars */
plars865695b2001-08-27 22:15:12 +0000101
102 /* The following loop checks looping state if -i option given */
103 for (lc = 0; TEST_LOOPING(lc); lc++) {
104
Caspar Zhangd59a6592013-03-07 14:59:12 +0800105 /* reset tst_count in case we are looping */
106 tst_count = 0;
plars865695b2001-08-27 22:15:12 +0000107
108 buf_list[0] = buf1;
109 buf_list[1] = buf2;
110
subrata_modak56207ce2009-03-23 13:35:39 +0000111 fd[1] = -1; /* Invalid file descriptor */
plars865695b2001-08-27 22:15:12 +0000112
robbiew4644c7e2002-04-26 14:33:32 +0000113 if (signal(SIGTERM, sighandler) == SIG_ERR) {
114 perror("signal");
115 tst_resm(TFAIL, "signal() SIGTERM FAILED");
plars865695b2001-08-27 22:15:12 +0000116 cleanup();
Wanlong Gao354ebb42012-12-07 10:10:04 +0800117 }
plars865695b2001-08-27 22:15:12 +0000118
robbiew4644c7e2002-04-26 14:33:32 +0000119 if (signal(SIGPIPE, sighandler) == SIG_ERR) {
120 perror("signal");
121 tst_resm(TFAIL, "signal() SIGPIPE FAILED");
plars865695b2001-08-27 22:15:12 +0000122 cleanup();
Wanlong Gao354ebb42012-12-07 10:10:04 +0800123 }
plars865695b2001-08-27 22:15:12 +0000124
125 /* Fill the buf_list[0] and buf_list[1] with 0 zeros */
126 memset(buf_list[0], 0, K_1);
127 memset(buf_list[1], 0, K_1);
128
129 if ((fd[0] = open(f_name, O_WRONLY | O_CREAT, 0666)) < 0) {
130 tst_resm(TFAIL, "open(2) failed: fname = %s, "
131 "errno = %d", f_name, errno);
132 cleanup();
Wanlong Gao354ebb42012-12-07 10:10:04 +0800133 } else {
subrata_modak56207ce2009-03-23 13:35:39 +0000134 if ((nbytes = write(fd[0], buf_list[1], K_1)) != K_1) {
plars865695b2001-08-27 22:15:12 +0000135 tst_resm(TFAIL, "write(2) failed: nbytes "
subrata_modak56207ce2009-03-23 13:35:39 +0000136 "= %d, errno = %d", nbytes, errno);
plars865695b2001-08-27 22:15:12 +0000137 cleanup();
Wanlong Gao354ebb42012-12-07 10:10:04 +0800138 }
plars865695b2001-08-27 22:15:12 +0000139 }
140
141 if (close(fd[0]) < 0) {
142 tst_resm(TFAIL, "close failed: errno = %d", errno);
143 cleanup();
Wanlong Gao354ebb42012-12-07 10:10:04 +0800144 }
plars865695b2001-08-27 22:15:12 +0000145
146 if ((fd[0] = open(f_name, O_RDWR, 0666)) < 0) {
147 tst_resm(TFAIL, "open failed: fname = %s, errno = %d",
148 f_name, errno);
149 cleanup();
Wanlong Gao354ebb42012-12-07 10:10:04 +0800150 }
plars865695b2001-08-27 22:15:12 +0000151
152 /*
153 * In this block we are trying to call writev() with invalid
154 * vector to be written in a sparse file. This will return
155 * EFAULT. At the same time, check should be made whether
156 * the scheduled write() with valid data is done correctly
157 * or not.
158 */
robbiew7d5c5172003-03-27 22:54:57 +0000159//block1:
plars865695b2001-08-27 22:15:12 +0000160 tst_resm(TINFO, "Enter block 1");
161 fail = 0;
162
163 l_seek(fd[0], 0, 0);
plars1ad84512002-07-23 13:11:18 +0000164 TEST(writev(fd[0], wr_iovec, 2));
plars865695b2001-08-27 22:15:12 +0000165 if (TEST_RETURN < 0) {
plars865695b2001-08-27 22:15:12 +0000166 if (TEST_ERRNO == EFAULT) {
167 tst_resm(TINFO, "Received EFAULT as expected");
168 } else {
169 tst_resm(TFAIL, "Expected EFAULT, got %d",
170 TEST_ERRNO);
171 fail = 1;
172 }
173 l_seek(fd[0], K_1, 0);
174 if ((nbytes = read(fd[0], buf_list[0], CHUNK)) != 0) {
175 tst_resm(TFAIL, "Expected nbytes = 0, got "
176 "%d", nbytes);
177 fail = 1;
178 }
179 } else {
180 tst_resm(TFAIL, "Error writev returned a positive "
181 "value");
182 fail = 1;
183 }
184 if (fail) {
185 tst_resm(TINFO, "block 1 FAILED");
186 } else {
187 tst_resm(TINFO, "block 1 PASSED");
188 }
189 tst_resm(TINFO, "Exit block 1");
190 }
subrata_modakdad6e1a2007-10-30 10:46:58 +0000191 close(fd[0]);
192 close(fd[1]);
plars865695b2001-08-27 22:15:12 +0000193 cleanup();
Garrett Cooper2aca6fc2010-12-19 03:12:40 -0800194 tst_exit();
Garrett Cooper2c282152010-12-16 00:55:50 -0800195
plars865695b2001-08-27 22:15:12 +0000196}
197
vapier6925ca32006-02-27 04:25:25 +0000198#else
199
Mike Frysingerc57fba52014-04-09 18:56:30 -0400200int main(void)
vapier6925ca32006-02-27 04:25:25 +0000201{
202 tst_resm(TINFO, "test is not available on uClinux");
Garrett Cooper2c282152010-12-16 00:55:50 -0800203 tst_exit();
vapier6925ca32006-02-27 04:25:25 +0000204}
205
206#endif /* if !defined(UCLINUX) */
207
plars865695b2001-08-27 22:15:12 +0000208/*
209 * setup()
210 * performs all ONE TIME setup for this test
211 */
subrata_modak56207ce2009-03-23 13:35:39 +0000212void setup(void)
plars865695b2001-08-27 22:15:12 +0000213{
Garrett Cooper2c282152010-12-16 00:55:50 -0800214
plars865695b2001-08-27 22:15:12 +0000215 tst_sig(FORK, DEF_HANDLER, cleanup);
216
plars865695b2001-08-27 22:15:12 +0000217 /* Pause if that option was specified.
218 * TEST_PAUSE contains the code to fork the test with the -i option.
219 * You want to make sure you do this before you create your temporary
220 * directory.
221 */
222 TEST_PAUSE;
223
224 /* Create a unique temporary directory and chdir() to it. */
225 tst_tmpdir();
226
227 strcpy(name, DATA_FILE);
228 sprintf(f_name, "%s.%d", name, getpid());
229
subrata_modak56207ce2009-03-23 13:35:39 +0000230 bad_addr = mmap(0, 1, PROT_NONE,
231 MAP_PRIVATE_EXCEPT_UCLINUX | MAP_ANONYMOUS, 0, 0);
232 if (bad_addr == MAP_FAILED) {
233 printf("mmap failed\n");
234 }
235 wr_iovec[0].iov_base = bad_addr;
robbiew37d19bd2003-11-14 16:57:49 +0000236
plars865695b2001-08-27 22:15:12 +0000237}
238
239/*
240 * cleanup()
241 * performs all ONE TIME cleanup for this test at
242 * completion or premature exit
243 */
subrata_modak56207ce2009-03-23 13:35:39 +0000244void cleanup(void)
plars865695b2001-08-27 22:15:12 +0000245{
plars865695b2001-08-27 22:15:12 +0000246
247 if (unlink(f_name) < 0) {
248 tst_resm(TFAIL, "unlink Failed--file = %s, errno = %d",
249 f_name, errno);
250 }
251 tst_rmdir();
252
plars865695b2001-08-27 22:15:12 +0000253}
254
255/*
256 * sighandler()
257 * Signal handler for SIGTERM and SIGPIPE
258 */
subrata_modak56207ce2009-03-23 13:35:39 +0000259void sighandler(int sig)
plars865695b2001-08-27 22:15:12 +0000260{
subrata_modak56207ce2009-03-23 13:35:39 +0000261 switch (sig) {
262 case SIGTERM:
263 break;
264 case SIGPIPE:
265 ++in_sighandler;
266 return;
plars865695b2001-08-27 22:15:12 +0000267 default:
subrata_modak56207ce2009-03-23 13:35:39 +0000268 tst_resm(TFAIL, "sighandler() received invalid signal "
269 ": %d", sig);
270 break;
plars865695b2001-08-27 22:15:12 +0000271 }
272
273 if ((unlink(f_name) < 0) && (errno != ENOENT)) {
274 tst_resm(TFAIL, "unlink Failed--file = %s, errno = %d",
275 f_name, errno);
276 cleanup();
Wanlong Gao354ebb42012-12-07 10:10:04 +0800277 }
plars865695b2001-08-27 22:15:12 +0000278 exit(sig);
279}
280
281/*
282 * l_seek()
283 * Wrap around for regular lseek() to give error message on failure
284 */
subrata_modak56207ce2009-03-23 13:35:39 +0000285long l_seek(int fdesc, long offset, int whence)
plars865695b2001-08-27 22:15:12 +0000286{
287 if (lseek(fdesc, offset, whence) < 0) {
288 tst_resm(TFAIL, "lseek Failed : errno = %d", errno);
289 fail = 1;
290 }
subrata_modak43337a32009-02-26 11:43:51 +0000291 return 0;
Chris Dearmanec6edca2012-10-17 19:54:01 -0700292}