blob: 476a80af21f3d1b0a2707d731463c72d1214ff8b [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;
84extern int Tst_count;
85
86void sighandler(int);
87long l_seek(int, long, int);
88void setup(void);
89void cleanup(void);
90int fail;
91
vapier6925ca32006-02-27 04:25:25 +000092#if !defined(UCLINUX)
93
robbiew7d5c5172003-03-27 22:54:57 +000094int main(int argc, char **argv)
plars865695b2001-08-27 22:15:12 +000095{
subrata_modak56207ce2009-03-23 13:35:39 +000096 int lc; /* loop counter */
97 char *msg; /* message returned from parse_opts */
plars865695b2001-08-27 22:15:12 +000098
99 int nbytes;
100
101 /* parse standard options */
Garrett Cooper45e285d2010-11-22 12:19:25 -0800102 if ((msg = parse_opts(argc, argv, NULL, NULL)) !=
103 NULL) {
plars865695b2001-08-27 22:15:12 +0000104 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
subrata_modak56207ce2009-03-23 13:35:39 +0000105 /*NOTREACHED*/}
plars865695b2001-08-27 22:15:12 +0000106
subrata_modak56207ce2009-03-23 13:35:39 +0000107 setup(); /* set "tstdir", and "testfile" vars */
plars865695b2001-08-27 22:15:12 +0000108
109 /* The following loop checks looping state if -i option given */
110 for (lc = 0; TEST_LOOPING(lc); lc++) {
111
112 /* reset Tst_count in case we are looping */
113 Tst_count = 0;
114
115 buf_list[0] = buf1;
116 buf_list[1] = buf2;
117
subrata_modak56207ce2009-03-23 13:35:39 +0000118 fd[1] = -1; /* Invalid file descriptor */
plars865695b2001-08-27 22:15:12 +0000119
robbiew4644c7e2002-04-26 14:33:32 +0000120 if (signal(SIGTERM, sighandler) == SIG_ERR) {
121 perror("signal");
122 tst_resm(TFAIL, "signal() SIGTERM FAILED");
plars865695b2001-08-27 22:15:12 +0000123 cleanup();
subrata_modak56207ce2009-03-23 13:35:39 +0000124 /*NOTREACHED*/}
plars865695b2001-08-27 22:15:12 +0000125
robbiew4644c7e2002-04-26 14:33:32 +0000126 if (signal(SIGPIPE, sighandler) == SIG_ERR) {
127 perror("signal");
128 tst_resm(TFAIL, "signal() SIGPIPE FAILED");
plars865695b2001-08-27 22:15:12 +0000129 cleanup();
subrata_modak56207ce2009-03-23 13:35:39 +0000130 /*NOTREACHED*/}
plars865695b2001-08-27 22:15:12 +0000131
132 /* Fill the buf_list[0] and buf_list[1] with 0 zeros */
133 memset(buf_list[0], 0, K_1);
134 memset(buf_list[1], 0, K_1);
135
136 if ((fd[0] = open(f_name, O_WRONLY | O_CREAT, 0666)) < 0) {
137 tst_resm(TFAIL, "open(2) failed: fname = %s, "
138 "errno = %d", f_name, errno);
139 cleanup();
subrata_modak56207ce2009-03-23 13:35:39 +0000140 /*NOTREACHED*/} else {
141 if ((nbytes = write(fd[0], buf_list[1], K_1)) != K_1) {
plars865695b2001-08-27 22:15:12 +0000142 tst_resm(TFAIL, "write(2) failed: nbytes "
subrata_modak56207ce2009-03-23 13:35:39 +0000143 "= %d, errno = %d", nbytes, errno);
plars865695b2001-08-27 22:15:12 +0000144 cleanup();
subrata_modak56207ce2009-03-23 13:35:39 +0000145 /*NOTREACHED*/}
plars865695b2001-08-27 22:15:12 +0000146 }
147
148 if (close(fd[0]) < 0) {
149 tst_resm(TFAIL, "close failed: errno = %d", errno);
150 cleanup();
subrata_modak56207ce2009-03-23 13:35:39 +0000151 /*NOTREACHED*/}
plars865695b2001-08-27 22:15:12 +0000152
153 if ((fd[0] = open(f_name, O_RDWR, 0666)) < 0) {
154 tst_resm(TFAIL, "open failed: fname = %s, errno = %d",
155 f_name, errno);
156 cleanup();
subrata_modak56207ce2009-03-23 13:35:39 +0000157 /*NOTREACHED*/}
plars865695b2001-08-27 22:15:12 +0000158
159 /*
160 * In this block we are trying to call writev() with invalid
161 * vector to be written in a sparse file. This will return
162 * EFAULT. At the same time, check should be made whether
163 * the scheduled write() with valid data is done correctly
164 * or not.
165 */
robbiew7d5c5172003-03-27 22:54:57 +0000166//block1:
plars865695b2001-08-27 22:15:12 +0000167 tst_resm(TINFO, "Enter block 1");
168 fail = 0;
169
170 l_seek(fd[0], 0, 0);
plars1ad84512002-07-23 13:11:18 +0000171 TEST(writev(fd[0], wr_iovec, 2));
plars865695b2001-08-27 22:15:12 +0000172 if (TEST_RETURN < 0) {
173 TEST_ERROR_LOG(TEST_ERRNO);
174 if (TEST_ERRNO == EFAULT) {
175 tst_resm(TINFO, "Received EFAULT as expected");
176 } else {
177 tst_resm(TFAIL, "Expected EFAULT, got %d",
178 TEST_ERRNO);
179 fail = 1;
180 }
181 l_seek(fd[0], K_1, 0);
182 if ((nbytes = read(fd[0], buf_list[0], CHUNK)) != 0) {
183 tst_resm(TFAIL, "Expected nbytes = 0, got "
184 "%d", nbytes);
185 fail = 1;
186 }
187 } else {
188 tst_resm(TFAIL, "Error writev returned a positive "
189 "value");
190 fail = 1;
191 }
192 if (fail) {
193 tst_resm(TINFO, "block 1 FAILED");
194 } else {
195 tst_resm(TINFO, "block 1 PASSED");
196 }
197 tst_resm(TINFO, "Exit block 1");
198 }
subrata_modakdad6e1a2007-10-30 10:46:58 +0000199 close(fd[0]);
200 close(fd[1]);
plars865695b2001-08-27 22:15:12 +0000201 cleanup();
subrata_modak43337a32009-02-26 11:43:51 +0000202 return 0;
plars865695b2001-08-27 22:15:12 +0000203}
204
vapier6925ca32006-02-27 04:25:25 +0000205#else
206
207int main()
208{
209 tst_resm(TINFO, "test is not available on uClinux");
210 return 0;
211}
212
213#endif /* if !defined(UCLINUX) */
214
plars865695b2001-08-27 22:15:12 +0000215/*
216 * setup()
217 * performs all ONE TIME setup for this test
218 */
subrata_modak56207ce2009-03-23 13:35:39 +0000219void setup(void)
plars865695b2001-08-27 22:15:12 +0000220{
221 /* capture signals */
222 tst_sig(FORK, DEF_HANDLER, cleanup);
223
224 /* Set up the expected error numbers for -e option */
225 TEST_EXP_ENOS(exp_enos);
226
227 /* Pause if that option was specified.
228 * TEST_PAUSE contains the code to fork the test with the -i option.
229 * You want to make sure you do this before you create your temporary
230 * directory.
231 */
232 TEST_PAUSE;
233
234 /* Create a unique temporary directory and chdir() to it. */
235 tst_tmpdir();
236
237 strcpy(name, DATA_FILE);
238 sprintf(f_name, "%s.%d", name, getpid());
239
subrata_modak56207ce2009-03-23 13:35:39 +0000240 bad_addr = mmap(0, 1, PROT_NONE,
241 MAP_PRIVATE_EXCEPT_UCLINUX | MAP_ANONYMOUS, 0, 0);
242 if (bad_addr == MAP_FAILED) {
243 printf("mmap failed\n");
244 }
245 wr_iovec[0].iov_base = bad_addr;
robbiew37d19bd2003-11-14 16:57:49 +0000246
plars865695b2001-08-27 22:15:12 +0000247}
248
249/*
250 * cleanup()
251 * performs all ONE TIME cleanup for this test at
252 * completion or premature exit
253 */
subrata_modak56207ce2009-03-23 13:35:39 +0000254void cleanup(void)
plars865695b2001-08-27 22:15:12 +0000255{
256 /*
257 * print timing stats if that option was specified.
258 * print errno log if that option was specified.
259 */
260 TEST_CLEANUP;
261
262 if (unlink(f_name) < 0) {
263 tst_resm(TFAIL, "unlink Failed--file = %s, errno = %d",
264 f_name, errno);
265 }
266 tst_rmdir();
267
268 tst_exit();
269}
270
271/*
272 * sighandler()
273 * Signal handler for SIGTERM and SIGPIPE
274 */
subrata_modak56207ce2009-03-23 13:35:39 +0000275void sighandler(int sig)
plars865695b2001-08-27 22:15:12 +0000276{
subrata_modak56207ce2009-03-23 13:35:39 +0000277 switch (sig) {
278 case SIGTERM:
279 break;
280 case SIGPIPE:
281 ++in_sighandler;
282 return;
plars865695b2001-08-27 22:15:12 +0000283 default:
subrata_modak56207ce2009-03-23 13:35:39 +0000284 tst_resm(TFAIL, "sighandler() received invalid signal "
285 ": %d", sig);
286 break;
plars865695b2001-08-27 22:15:12 +0000287 }
288
289 if ((unlink(f_name) < 0) && (errno != ENOENT)) {
290 tst_resm(TFAIL, "unlink Failed--file = %s, errno = %d",
291 f_name, errno);
292 cleanup();
subrata_modak56207ce2009-03-23 13:35:39 +0000293 /*NOTREACHED*/}
plars865695b2001-08-27 22:15:12 +0000294 exit(sig);
295}
296
297/*
298 * l_seek()
299 * Wrap around for regular lseek() to give error message on failure
300 */
subrata_modak56207ce2009-03-23 13:35:39 +0000301long l_seek(int fdesc, long offset, int whence)
plars865695b2001-08-27 22:15:12 +0000302{
303 if (lseek(fdesc, offset, whence) < 0) {
304 tst_resm(TFAIL, "lseek Failed : errno = %d", errno);
305 fail = 1;
306 }
subrata_modak43337a32009-02-26 11:43:51 +0000307 return 0;
plars865695b2001-08-27 22:15:12 +0000308}