blob: a772beb27dca2d12503b957c59c6ca2227523e39 [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
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
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>
53#include <test.h>
54#include <usctest.h>
robbiew37d19bd2003-11-14 16:57:49 +000055#include <sys/mman.h>
plars865695b2001-08-27 22:15:12 +000056
57#define K_1 8192
58
59#define NBUFS 2
subrata_modak56207ce2009-03-23 13:35:39 +000060#define CHUNK K_1 /* single chunk */
plars865695b2001-08-27 22:15:12 +000061#define MAX_IOVEC 2
62#define DATA_FILE "writev_data_file"
63
subrata_modak56207ce2009-03-23 13:35:39 +000064char buf1[K_1];
65char buf2[K_1];
66char buf3[K_1];
plars865695b2001-08-27 22:15:12 +000067
subrata_modak56207ce2009-03-23 13:35:39 +000068char *bad_addr = 0;
robbiew37d19bd2003-11-14 16:57:49 +000069
subrata_modak56207ce2009-03-23 13:35:39 +000070struct iovec wr_iovec[MAX_IOVEC] = {
71 {(caddr_t) - 1, CHUNK},
72 {(caddr_t) NULL, 0}
plars865695b2001-08-27 22:15:12 +000073};
74
75/* 0 terminated list of expected errnos */
subrata_modak56207ce2009-03-23 13:35:39 +000076int exp_enos[] = { 14, 0 };
plars865695b2001-08-27 22:15:12 +000077
subrata_modak56207ce2009-03-23 13:35:39 +000078char name[K_1], f_name[K_1];
79int fd[2], in_sighandler;
80char *buf_list[NBUFS];
plars865695b2001-08-27 22:15:12 +000081
82char *TCID = "writev05";
83int TST_TOTAL = 1;
plars865695b2001-08-27 22:15:12 +000084
85void sighandler(int);
86long l_seek(int, long, int);
87void setup(void);
88void cleanup(void);
89int fail;
90
vapier6925ca32006-02-27 04:25:25 +000091#if !defined(UCLINUX)
92
robbiew7d5c5172003-03-27 22:54:57 +000093int main(int argc, char **argv)
plars865695b2001-08-27 22:15:12 +000094{
subrata_modak56207ce2009-03-23 13:35:39 +000095 int lc; /* loop counter */
96 char *msg; /* message returned from parse_opts */
plars865695b2001-08-27 22:15:12 +000097
98 int nbytes;
99
100 /* parse standard options */
Garrett Cooper45e285d2010-11-22 12:19:25 -0800101 if ((msg = parse_opts(argc, argv, NULL, NULL)) !=
102 NULL) {
plars865695b2001-08-27 22:15:12 +0000103 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
Garrett Cooper53740502010-12-16 00:04:01 -0800104 }
plars865695b2001-08-27 22:15:12 +0000105
subrata_modak56207ce2009-03-23 13:35:39 +0000106 setup(); /* set "tstdir", and "testfile" vars */
plars865695b2001-08-27 22:15:12 +0000107
108 /* The following loop checks looping state if -i option given */
109 for (lc = 0; TEST_LOOPING(lc); lc++) {
110
111 /* reset Tst_count in case we are looping */
112 Tst_count = 0;
113
114 buf_list[0] = buf1;
115 buf_list[1] = buf2;
116
subrata_modak56207ce2009-03-23 13:35:39 +0000117 fd[1] = -1; /* Invalid file descriptor */
plars865695b2001-08-27 22:15:12 +0000118
robbiew4644c7e2002-04-26 14:33:32 +0000119 if (signal(SIGTERM, sighandler) == SIG_ERR) {
120 perror("signal");
121 tst_resm(TFAIL, "signal() SIGTERM FAILED");
plars865695b2001-08-27 22:15:12 +0000122 cleanup();
Garrett Cooper53740502010-12-16 00:04:01 -0800123 }
plars865695b2001-08-27 22:15:12 +0000124
robbiew4644c7e2002-04-26 14:33:32 +0000125 if (signal(SIGPIPE, sighandler) == SIG_ERR) {
126 perror("signal");
127 tst_resm(TFAIL, "signal() SIGPIPE FAILED");
plars865695b2001-08-27 22:15:12 +0000128 cleanup();
Garrett Cooper53740502010-12-16 00:04:01 -0800129 }
plars865695b2001-08-27 22:15:12 +0000130
131 /* Fill the buf_list[0] and buf_list[1] with 0 zeros */
132 memset(buf_list[0], 0, K_1);
133 memset(buf_list[1], 0, K_1);
134
135 if ((fd[0] = open(f_name, O_WRONLY | O_CREAT, 0666)) < 0) {
136 tst_resm(TFAIL, "open(2) failed: fname = %s, "
137 "errno = %d", f_name, errno);
138 cleanup();
Garrett Cooper53740502010-12-16 00:04:01 -0800139 } else {
subrata_modak56207ce2009-03-23 13:35:39 +0000140 if ((nbytes = write(fd[0], buf_list[1], K_1)) != K_1) {
plars865695b2001-08-27 22:15:12 +0000141 tst_resm(TFAIL, "write(2) failed: nbytes "
subrata_modak56207ce2009-03-23 13:35:39 +0000142 "= %d, errno = %d", nbytes, errno);
plars865695b2001-08-27 22:15:12 +0000143 cleanup();
Garrett Cooper53740502010-12-16 00:04:01 -0800144 }
plars865695b2001-08-27 22:15:12 +0000145 }
146
147 if (close(fd[0]) < 0) {
148 tst_resm(TFAIL, "close failed: errno = %d", errno);
149 cleanup();
Garrett Cooper53740502010-12-16 00:04:01 -0800150 }
plars865695b2001-08-27 22:15:12 +0000151
152 if ((fd[0] = open(f_name, O_RDWR, 0666)) < 0) {
153 tst_resm(TFAIL, "open failed: fname = %s, errno = %d",
154 f_name, errno);
155 cleanup();
Garrett Cooper53740502010-12-16 00:04:01 -0800156 }
plars865695b2001-08-27 22:15:12 +0000157
158 /*
159 * In this block we are trying to call writev() with invalid
160 * vector to be written in a sparse file. This will return
161 * EFAULT. At the same time, check should be made whether
162 * the scheduled write() with valid data is done correctly
163 * or not.
164 */
robbiew7d5c5172003-03-27 22:54:57 +0000165//block1:
plars865695b2001-08-27 22:15:12 +0000166 tst_resm(TINFO, "Enter block 1");
167 fail = 0;
168
169 l_seek(fd[0], 0, 0);
plars1ad84512002-07-23 13:11:18 +0000170 TEST(writev(fd[0], wr_iovec, 2));
plars865695b2001-08-27 22:15:12 +0000171 if (TEST_RETURN < 0) {
172 TEST_ERROR_LOG(TEST_ERRNO);
173 if (TEST_ERRNO == EFAULT) {
174 tst_resm(TINFO, "Received EFAULT as expected");
175 } else {
176 tst_resm(TFAIL, "Expected EFAULT, got %d",
177 TEST_ERRNO);
178 fail = 1;
179 }
180 l_seek(fd[0], K_1, 0);
181 if ((nbytes = read(fd[0], buf_list[0], CHUNK)) != 0) {
182 tst_resm(TFAIL, "Expected nbytes = 0, got "
183 "%d", nbytes);
184 fail = 1;
185 }
186 } else {
187 tst_resm(TFAIL, "Error writev returned a positive "
188 "value");
189 fail = 1;
190 }
191 if (fail) {
192 tst_resm(TINFO, "block 1 FAILED");
193 } else {
194 tst_resm(TINFO, "block 1 PASSED");
195 }
196 tst_resm(TINFO, "Exit block 1");
197 }
subrata_modakdad6e1a2007-10-30 10:46:58 +0000198 close(fd[0]);
199 close(fd[1]);
plars865695b2001-08-27 22:15:12 +0000200 cleanup();
Garrett Cooper2c282152010-12-16 00:55:50 -0800201
plars865695b2001-08-27 22:15:12 +0000202}
203
vapier6925ca32006-02-27 04:25:25 +0000204#else
205
206int main()
207{
208 tst_resm(TINFO, "test is not available on uClinux");
Garrett Cooper2c282152010-12-16 00:55:50 -0800209 tst_exit();
vapier6925ca32006-02-27 04:25:25 +0000210}
211
212#endif /* if !defined(UCLINUX) */
213
plars865695b2001-08-27 22:15:12 +0000214/*
215 * setup()
216 * performs all ONE TIME setup for this test
217 */
subrata_modak56207ce2009-03-23 13:35:39 +0000218void setup(void)
plars865695b2001-08-27 22:15:12 +0000219{
Garrett Cooper2c282152010-12-16 00:55:50 -0800220
plars865695b2001-08-27 22:15:12 +0000221 tst_sig(FORK, DEF_HANDLER, cleanup);
222
223 /* Set up the expected error numbers for -e option */
224 TEST_EXP_ENOS(exp_enos);
225
226 /* Pause if that option was specified.
227 * TEST_PAUSE contains the code to fork the test with the -i option.
228 * You want to make sure you do this before you create your temporary
229 * directory.
230 */
231 TEST_PAUSE;
232
233 /* Create a unique temporary directory and chdir() to it. */
234 tst_tmpdir();
235
236 strcpy(name, DATA_FILE);
237 sprintf(f_name, "%s.%d", name, getpid());
238
subrata_modak56207ce2009-03-23 13:35:39 +0000239 bad_addr = mmap(0, 1, PROT_NONE,
240 MAP_PRIVATE_EXCEPT_UCLINUX | MAP_ANONYMOUS, 0, 0);
241 if (bad_addr == MAP_FAILED) {
242 printf("mmap failed\n");
243 }
244 wr_iovec[0].iov_base = bad_addr;
robbiew37d19bd2003-11-14 16:57:49 +0000245
plars865695b2001-08-27 22:15:12 +0000246}
247
248/*
249 * cleanup()
250 * performs all ONE TIME cleanup for this test at
251 * completion or premature exit
252 */
subrata_modak56207ce2009-03-23 13:35:39 +0000253void cleanup(void)
plars865695b2001-08-27 22:15:12 +0000254{
255 /*
256 * print timing stats if that option was specified.
257 * print errno log if that option was specified.
258 */
259 TEST_CLEANUP;
260
261 if (unlink(f_name) < 0) {
262 tst_resm(TFAIL, "unlink Failed--file = %s, errno = %d",
263 f_name, errno);
264 }
265 tst_rmdir();
266
plars865695b2001-08-27 22:15:12 +0000267}
268
269/*
270 * sighandler()
271 * Signal handler for SIGTERM and SIGPIPE
272 */
subrata_modak56207ce2009-03-23 13:35:39 +0000273void sighandler(int sig)
plars865695b2001-08-27 22:15:12 +0000274{
subrata_modak56207ce2009-03-23 13:35:39 +0000275 switch (sig) {
276 case SIGTERM:
277 break;
278 case SIGPIPE:
279 ++in_sighandler;
280 return;
plars865695b2001-08-27 22:15:12 +0000281 default:
subrata_modak56207ce2009-03-23 13:35:39 +0000282 tst_resm(TFAIL, "sighandler() received invalid signal "
283 ": %d", sig);
284 break;
plars865695b2001-08-27 22:15:12 +0000285 }
286
287 if ((unlink(f_name) < 0) && (errno != ENOENT)) {
288 tst_resm(TFAIL, "unlink Failed--file = %s, errno = %d",
289 f_name, errno);
290 cleanup();
Garrett Cooper53740502010-12-16 00:04:01 -0800291 }
plars865695b2001-08-27 22:15:12 +0000292 exit(sig);
293}
294
295/*
296 * l_seek()
297 * Wrap around for regular lseek() to give error message on failure
298 */
subrata_modak56207ce2009-03-23 13:35:39 +0000299long l_seek(int fdesc, long offset, int whence)
plars865695b2001-08-27 22:15:12 +0000300{
301 if (lseek(fdesc, offset, whence) < 0) {
302 tst_resm(TFAIL, "lseek Failed : errno = %d", errno);
303 fail = 1;
304 }
subrata_modak43337a32009-02-26 11:43:51 +0000305 return 0;
Garrett Cooper2c282152010-12-16 00:55:50 -0800306}