blob: cde97f7bc26b16dec3aee82d3a6bb3e2cb0d1966 [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 * Test Name: pread01
22 *
23 * Test Description:
24 * Verify the functionality of pread() by writing known data using pwrite()
25 * to the file at various specified offsets and later read from the file from
vapier22cf2042006-04-10 23:53:29 +000026 * various specified offsets, comparing the data read aganist the data
plars865695b2001-08-27 22:15:12 +000027 * written.
28 *
29 * Expected Result:
30 * pread() should succeed to read the expected no. of bytes of data and
31 * the data read should match aganist the data written to the file.
32 *
33 * Algorithm:
34 * Setup:
35 * Setup signal handling.
36 * Create temporary directory.
37 * Pause for SIGUSR1 if option specified.
38 *
39 * Test:
40 * Loop if the proper options are given.
41 * Execute system call
42 * Check return code, if system call failed (return=-1)
vapier22cf2042006-04-10 23:53:29 +000043 * Issue a FAIL message.
plars865695b2001-08-27 22:15:12 +000044 * Otherwise,
vapier22cf2042006-04-10 23:53:29 +000045 * Verify the Functionality of system call
plars865695b2001-08-27 22:15:12 +000046 * if successful,
vapier22cf2042006-04-10 23:53:29 +000047 * Issue Functionality-Pass message.
plars865695b2001-08-27 22:15:12 +000048 * Otherwise,
vapier22cf2042006-04-10 23:53:29 +000049 * Issue Functionality-Fail message.
plars865695b2001-08-27 22:15:12 +000050 * Cleanup:
51 * Print errno log and/or timing stats if options given
52 * Delete the temporary directory created.
53 *
54 * Usage: <for command-line>
55 * pread01 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
56 * where, -c n : Run n copies concurrently.
57 * -f : Turn off functionality Testing.
vapier22cf2042006-04-10 23:53:29 +000058 * -i n : Execute test n times.
59 * -I x : Execute test for x seconds.
60 * -P x : Pause for x seconds between iterations.
61 * -t : Turn on syscall timing.
plars865695b2001-08-27 22:15:12 +000062 *
63 * HISTORY
64 * 07/2001 Ported by Wayne Boyer
65 *
66 * RESTRICTIONS:
67 * None.
68 */
plars74948ad2002-11-14 16:16:14 +000069
70#define _XOPEN_SOURCE 500
71
plars865695b2001-08-27 22:15:12 +000072#include <stdlib.h>
73#include <errno.h>
74#include <unistd.h>
75#include <fcntl.h>
subrata_modak923b23f2009-11-02 13:57:16 +000076#include <inttypes.h>
plars865695b2001-08-27 22:15:12 +000077
78#include "test.h"
plars865695b2001-08-27 22:15:12 +000079
80#define TEMPFILE "pread_file"
81#define K1 1024
82#define K2 (K1 * 2)
83#define K3 (K1 * 3)
84#define K4 (K1 * 4)
85#define NBUFS 4
86
Cyril Hrubisfdce7d52013-04-04 18:35:48 +020087char *TCID = "pread01";
88int TST_TOTAL = 1;
plars865695b2001-08-27 22:15:12 +000089
90int fildes; /* file descriptor for tempfile */
91char *write_buf[NBUFS]; /* buffer to hold data to be written */
92char *read_buf[NBUFS]; /* buffer to hold data read from file */
93
94void setup(); /* Main setup function of test */
95void cleanup(); /* cleanup function for the test */
subrata_modak56207ce2009-03-23 13:35:39 +000096void l_seek(int, off_t, int, off_t); /* function to call lseek() */
plars865695b2001-08-27 22:15:12 +000097void init_buffers(); /* function to initialize/allocate buffers */
98void compare_bufers(); /* function to compare o/p of pread/pwrite */
99
subrata_modak56207ce2009-03-23 13:35:39 +0000100int main(int ac, char **av)
plars865695b2001-08-27 22:15:12 +0000101{
Cyril Hrubis89af32a2012-10-24 16:39:11 +0200102 int lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +0200103 const char *msg;
plars865695b2001-08-27 22:15:12 +0000104 int nread; /* no. of bytes read by pread() */
vapier22cf2042006-04-10 23:53:29 +0000105
Garrett Cooper7d0a4a52010-12-16 10:05:08 -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);
plars865695b2001-08-27 22:15:12 +0000108
plars865695b2001-08-27 22:15:12 +0000109 setup();
110
plars865695b2001-08-27 22:15:12 +0000111 for (lc = 0; TEST_LOOPING(lc); lc++) {
112
Caspar Zhangd59a6592013-03-07 14:59:12 +0800113 /* Reset tst_count in case we are looping */
114 tst_count = 0;
plars865695b2001-08-27 22:15:12 +0000115
vapier22cf2042006-04-10 23:53:29 +0000116 /*
plars865695b2001-08-27 22:15:12 +0000117 * Call pread() of K1 data (should be 2's) at offset K2.
118 */
vapier22cf2042006-04-10 23:53:29 +0000119 nread = pread(fildes, read_buf[2], K1, K2);
plars865695b2001-08-27 22:15:12 +0000120
121 /* Check for the return value of pread() */
122 if (nread != K1) {
123 tst_brkm(TFAIL, cleanup, "pread() at off. K2 failed: "
124 "nread=%d, error:%d", nread, errno);
125 }
126
127 /*
128 * We should still be at offset K4,
129 * which we were at the end of block 0.
130 */
131 l_seek(fildes, 0, SEEK_CUR, K4);
132
133 /* Now lseek() to offset 0. */
134 l_seek(fildes, 0, SEEK_SET, 0);
135
136 /* pread() K1 of data (should be 3's) at offset K3. */
vapier22cf2042006-04-10 23:53:29 +0000137 nread = pread(fildes, read_buf[3], K1, K3);
plars865695b2001-08-27 22:15:12 +0000138 if (nread != K1) {
139 tst_brkm(TFAIL, cleanup, "pread() at off. K3 failed: "
140 "nread=%d, error:%d", nread, errno);
141 }
142
143 /* We should still be at offset 0. */
144 l_seek(fildes, 0, SEEK_CUR, 0);
145
146 /*
vapier22cf2042006-04-10 23:53:29 +0000147 * Do a normal read() of K1 data (should be 0's)
plars865695b2001-08-27 22:15:12 +0000148 * which should take place at offset 0 and move the
149 * file pointer to an offset of K1.
150 */
151 if ((nread = read(fildes, read_buf[0], K1)) != K1) {
152 tst_brkm(TFAIL, cleanup, "read() at off. 0 failed: "
153 "nread=%d, errno=%d", nread, errno);
154 }
155
156 /* We should now be at an offset of K1. */
157 l_seek(fildes, 0, SEEK_CUR, K1);
158
subrata_modak56207ce2009-03-23 13:35:39 +0000159 /* pread() of K1 data (should be 1's) at offset K1. */
vapier22cf2042006-04-10 23:53:29 +0000160 nread = pread(fildes, read_buf[1], K1, K1);
plars865695b2001-08-27 22:15:12 +0000161 if (nread != K1) {
162 tst_brkm(TFAIL, cleanup, "pread() at off. K1 failed: "
163 "nread=%d, error:%d", nread, errno);
164 }
165
166 /* We should still be at offset K1. */
167 l_seek(fildes, 0, SEEK_CUR, K1);
168
169 /*
Cyril Hrubise38b9612014-06-02 17:20:57 +0200170 * Compare the read buffer data read
171 * with the data written to write buffer
172 * in the setup.
plars865695b2001-08-27 22:15:12 +0000173 */
Cyril Hrubise38b9612014-06-02 17:20:57 +0200174 compare_bufers();
plars865695b2001-08-27 22:15:12 +0000175
176 /* reset our location to offset K4 in case we are looping */
177 l_seek(fildes, K4, SEEK_SET, K4);
Garrett Cooper2c282152010-12-16 00:55:50 -0800178 }
179
plars865695b2001-08-27 22:15:12 +0000180 cleanup();
Garrett Cooper1e6f5a62010-12-19 09:58:10 -0800181 tst_exit();
Garrett Cooper2c282152010-12-16 00:55:50 -0800182}
plars865695b2001-08-27 22:15:12 +0000183
184/*
185 * setup() - performs all ONE TIME setup for this test.
186 *
187 * Initialize/allocate read/write buffers.
188 * Create a temporary directory and a file under it and
189 * write know data at different offset positions.
190 */
Mike Frysingerc57fba52014-04-09 18:56:30 -0400191void setup(void)
plars865695b2001-08-27 22:15:12 +0000192{
subrata_modak56207ce2009-03-23 13:35:39 +0000193 int nwrite = 0; /* no. of bytes written by pwrite() */
plars865695b2001-08-27 22:15:12 +0000194
plars865695b2001-08-27 22:15:12 +0000195 tst_sig(FORK, DEF_HANDLER, cleanup);
196
plars865695b2001-08-27 22:15:12 +0000197 TEST_PAUSE;
198
199 /* Allocate/Initialize the read/write buffer with know data */
200 init_buffers();
201
plars865695b2001-08-27 22:15:12 +0000202 tst_tmpdir();
203
204 /* Creat a temporary file used for mapping */
205 if ((fildes = open(TEMPFILE, O_RDWR | O_CREAT, 0666)) < 0) {
206 tst_brkm(TBROK, cleanup, "open() on %s failed, errno=%d : %s",
207 TEMPFILE, errno, strerror(errno));
208 }
209
210 /* pwrite() K1 of data (0's) at offset 0 of temporary file */
211 if ((nwrite = pwrite(fildes, write_buf[0], K1, 0)) != K1) {
212 tst_brkm(TBROK, cleanup, "pwrite() failed to write on %s, "
213 "errno=%d : %s", TEMPFILE, errno, strerror(errno));
214 }
vapier22cf2042006-04-10 23:53:29 +0000215
plars865695b2001-08-27 22:15:12 +0000216 /* We should still be at offset 0. */
217 l_seek(fildes, 0, SEEK_CUR, 0);
218
219 /* Now, lseek() to a non K boundary, just to be different. */
subrata_modak56207ce2009-03-23 13:35:39 +0000220 l_seek(fildes, K1 / 2, SEEK_SET, K1 / 2);
plars865695b2001-08-27 22:15:12 +0000221
222 /* Again, pwrite() K1 of data (2's) at offset K2 of temporary file */
223 if ((nwrite = pwrite(fildes, write_buf[2], K1, K2)) != K1) {
224 tst_brkm(TBROK, cleanup, "pwrite() failed to write at %d off. "
225 "on %s, errno=%d : %s", K2, TEMPFILE, errno,
226 strerror(errno));
227 }
228
229 /* We should still be at our non K boundary. */
subrata_modak56207ce2009-03-23 13:35:39 +0000230 l_seek(fildes, 0, SEEK_CUR, K1 / 2);
plars865695b2001-08-27 22:15:12 +0000231
232 /* lseek() to an offset of K3. */
233 l_seek(fildes, K3, SEEK_SET, K3);
234
235 /*
236 * Using write(), write of K1 of data (3's) which should take
237 * place at an offset of K3, moving the file pointer to K4.
238 */
239 if ((nwrite = write(fildes, write_buf[3], K1)) != K1) {
240 tst_brkm(TBROK, cleanup, "write() failed: nwrite=%d, errno=%d "
241 ": %s", nwrite, errno, strerror(errno));
242 }
243
244 /* We should be at offset K4. */
245 l_seek(fildes, 0, SEEK_CUR, K4);
246
247 /* Again, pwrite() K1 of data (1's) at offset K1. */
248 if ((nwrite = pwrite(fildes, write_buf[1], K1, K1)) != K1) {
249 tst_brkm(TBROK, cleanup, "pwrite() failed to write at %d off. "
250 "on %s, errno=%d : %s", K1, TEMPFILE, errno,
251 strerror(errno));
252 }
253}
254
255/*
256 * init_buffers - allocates both write_buf and read_buf arrays.
257 *
258 * Allocate the read and write buffers.
259 * Fill the write buffer with the following data like,
260 * write_buf[0] has 0's, write_buf[1] has 1's, write_buf[2] has 2's
261 * write_buf[3] has 3's.
262 */
Mike Frysingerc57fba52014-04-09 18:56:30 -0400263void init_buffers(void)
plars865695b2001-08-27 22:15:12 +0000264{
265 int count; /* counter variable for loop */
266
267 /* Allocate and Initialize read/write buffer */
268 for (count = 0; count < NBUFS; count++) {
Cyril Hrubisd218f342014-09-23 13:14:56 +0200269 write_buf[count] = malloc(K1);
270 read_buf[count] = malloc(K1);
plars865695b2001-08-27 22:15:12 +0000271
272 if ((write_buf[count] == NULL) || (read_buf[count] == NULL)) {
Garrett Cooper53740502010-12-16 00:04:01 -0800273 tst_brkm(TBROK, NULL,
plars865695b2001-08-27 22:15:12 +0000274 "malloc() failed on read/write buffers");
275 }
276 memset(write_buf[count], count, K1);
277 }
278}
279
280/*
281 * l_seek() - local front end to lseek().
282 *
283 * "checkoff" is the offset at which we believe we should be at.
284 * Used to validate pread/pwrite don't move the offset.
285 */
subrata_modak56207ce2009-03-23 13:35:39 +0000286void l_seek(int fdesc, off_t offset, int whence, off_t checkoff)
plars865695b2001-08-27 22:15:12 +0000287{
288 off_t offloc; /* offset ret. from lseek() */
289
290 if ((offloc = lseek(fdesc, offset, whence)) != checkoff) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800291 tst_resm(TWARN, "return = %" PRId64 ", expected %" PRId64,
292 (int64_t) offloc, (int64_t) checkoff);
293 tst_brkm(TBROK | TERRNO, cleanup, "lseek() on %s failed",
subrata_modak923b23f2009-11-02 13:57:16 +0000294 TEMPFILE);
plars865695b2001-08-27 22:15:12 +0000295 }
296}
297
298/*
299 * compare_bufers() - Compare the contents of read buffer aganist the
vapier22cf2042006-04-10 23:53:29 +0000300 * write buffer contents.
plars865695b2001-08-27 22:15:12 +0000301 *
302 * The contents of the index of each buffer should be as follows:
303 * [0] has 0's, [1] has 1's, [2] has 2's, and [3] has 3's.
304 *
305 * This function does memcmp of read/write buffer and display message
306 * about the functionality of pread().
307 */
Mike Frysingerc57fba52014-04-09 18:56:30 -0400308void compare_bufers(void)
plars865695b2001-08-27 22:15:12 +0000309{
310 int count; /* index for the loop */
311 int err_flg = 0; /* flag to indicate error */
312
313 for (count = 0; count < NBUFS; count++) {
314 if (memcmp(write_buf[count], read_buf[count], K1) != 0) {
315 tst_resm(TFAIL, "read/write buffer data mismatch");
316 err_flg++;
317 }
318 }
319
320 /* If no erros, Test successful */
321 if (!err_flg) {
322 tst_resm(TPASS, "Functionality of pread() is correct");
323 }
324}
325
326/*
327 * cleanup() - performs all ONE TIME cleanup for this test at
328 * completion or premature exit.
329 *
vapier22cf2042006-04-10 23:53:29 +0000330 * Deallocate the memory allocated to read/write buffers.
331 * Close the temporary file.
332 * Remove the temporary directory created.
plars865695b2001-08-27 22:15:12 +0000333 */
Mike Frysingerc57fba52014-04-09 18:56:30 -0400334void cleanup(void)
plars865695b2001-08-27 22:15:12 +0000335{
Cyril Hrubis605fa332015-02-04 13:11:20 +0100336 int count;
plars865695b2001-08-27 22:15:12 +0000337
338 /* Free the memory allocated for the read/write buffer */
339 for (count = 0; count < NBUFS; count++) {
340 free(write_buf[count]);
341 free(read_buf[count]);
342 }
343
344 /* Close the temporary file */
345 if (close(fildes) < 0) {
346 tst_brkm(TBROK, NULL, "close() on %s Failed, errno=%d : %s",
347 TEMPFILE, errno, strerror(errno));
348 }
349
plars865695b2001-08-27 22:15:12 +0000350 tst_rmdir();
351
Chris Dearmanec6edca2012-10-17 19:54:01 -0700352}