blob: 300ba58126c88bcc17bd7ba7ea35186ac25dda89 [file] [log] [blame]
robbiew3c658152003-01-07 21:50:34 +00001/*
2 *
3 * Copyright (c) International Business Machines Corp., 2002
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
robbiew3c658152003-01-07 21:50:34 +000018 */
19
20/*
21 * NAME
22 * pwrite04.c (ported from SPIE, section2/filesuite/pread_pwrite.c,
23 * by Airong Zhang)
24 *
25 * TEST SUMMARY
26 * Test the pwrite() system call with O_APPEND.
27 *
28 * USAGE
subrata_modak4bb656a2009-02-26 12:02:09 +000029 * pwrite04
robbiew3c658152003-01-07 21:50:34 +000030 *
31 */
32
33#define _XOPEN_SOURCE 500
34#include <stdio.h>
35#include <sys/types.h>
36#include <sys/stat.h>
37#include <unistd.h>
38#include <sys/fcntl.h>
39#include <memory.h>
40#include <errno.h>
robbiew3c658152003-01-07 21:50:34 +000041#include "test.h"
42
43char *TCID = "pwrite04";
44int TST_TOTAL = 1;
subrata_modak56207ce2009-03-23 13:35:39 +000045int local_flag;
robbiew3c658152003-01-07 21:50:34 +000046
47#define PASSED 1
48#define FAILED 0
49
subrata_modak56207ce2009-03-23 13:35:39 +000050int block_cnt = 0;
robbiew3c658152003-01-07 21:50:34 +000051
52#define K1 1024
53#define K2 (K1 * 2)
54#define K3 (K1 * 3)
55#define K4 (K1 * 4)
56#define K5 (K1 * 5)
57#define NBUFS 4
58#define DATA_FILE "pwrite04_file"
59
60char name[256], fname[256];
61
subrata_modak56207ce2009-03-23 13:35:39 +000062void init_buffers(char *[]);
robbiew3c658152003-01-07 21:50:34 +000063void l_seek(int, off_t, int, off_t);
subrata_modak24fc2132008-11-11 05:57:38 +000064static void cleanup(void);
robbiew3c658152003-01-07 21:50:34 +000065
subrata_modak4bb656a2009-02-26 12:02:09 +000066int main(int ac, char *av[])
robbiew3c658152003-01-07 21:50:34 +000067{
subrata_modak56207ce2009-03-23 13:35:39 +000068 int fd;
69 int nbytes;
70 char *wbuf[NBUFS];
71 struct stat statbuf;
Cyril Hrubis89af32a2012-10-24 16:39:11 +020072 int lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +020073 const char *msg;
robbiew3c658152003-01-07 21:50:34 +000074
75 strcpy(name, DATA_FILE);
76 sprintf(fname, "%s.%d", name, getpid());
77
subrata_modak56207ce2009-03-23 13:35:39 +000078 /*
79 * parse standard options
80 */
Garrett Cooper45e285d2010-11-22 12:19:25 -080081 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) {
subrata_modak56207ce2009-03-23 13:35:39 +000082 tst_resm(TBROK, "OPTION PARSING ERROR - %s", msg);
Garrett Cooper2c282152010-12-16 00:55:50 -080083
subrata_modak56207ce2009-03-23 13:35:39 +000084 }
robbiew3c658152003-01-07 21:50:34 +000085 tst_tmpdir();
86 for (lc = 0; TEST_LOOPING(lc); lc++) {
87
88 init_buffers(wbuf);
89 local_flag = PASSED;
90
91 if ((fd = open(fname, O_RDWR | O_CREAT, 0666)) < 0) {
subrata_modak56207ce2009-03-23 13:35:39 +000092 tst_resm(TBROK, "open failed: fname = %s, errno = %d",
93 fname, errno);
94 cleanup();
95 }
96 /*
97 * pwrite() K1 of data (0's) at offset 0.
98 */
99 if ((nbytes = pwrite(fd, wbuf[0], K1, 0)) != K1) {
100 tst_resm(TFAIL,
101 "pwrite at 0 failed: nbytes=%d, errno=%d",
102 nbytes, errno);
103 cleanup();
104 }
robbiew3c658152003-01-07 21:50:34 +0000105
subrata_modak56207ce2009-03-23 13:35:39 +0000106 /*
107 * We should still be at offset 0.
108 */
109 l_seek(fd, 0, SEEK_CUR, 0);
robbiew3c658152003-01-07 21:50:34 +0000110
subrata_modak56207ce2009-03-23 13:35:39 +0000111 /*
112 * lseek() to a non K boundary, just to be different.
113 */
114 l_seek(fd, K1 / 2, SEEK_SET, K1 / 2);
robbiew3c658152003-01-07 21:50:34 +0000115
subrata_modak56207ce2009-03-23 13:35:39 +0000116 /*
117 * pwrite() K1 of data (2's) at offset K2.
118 */
119 if ((nbytes = pwrite(fd, wbuf[2], K1, K2)) != K1) {
120 tst_resm(TFAIL,
121 "pwrite at K2 failed: nbytes=%d, errno=%d",
122 nbytes, errno);
123 cleanup();
124 }
robbiew3c658152003-01-07 21:50:34 +0000125
subrata_modak56207ce2009-03-23 13:35:39 +0000126 /*
127 * We should still be at our non K boundary.
128 */
129 l_seek(fd, 0, SEEK_CUR, K1 / 2);
robbiew3c658152003-01-07 21:50:34 +0000130
subrata_modak56207ce2009-03-23 13:35:39 +0000131 /*
132 * lseek() to an offset of K3.
133 */
134 l_seek(fd, K3, SEEK_SET, K3);
robbiew3c658152003-01-07 21:50:34 +0000135
subrata_modak56207ce2009-03-23 13:35:39 +0000136 /*
137 * This time use a normal write() of K1 of data (3's) which should
138 * take place at an offset of K3, moving the file pointer to K4.
139 */
140 if ((nbytes = write(fd, wbuf[3], K1)) != K1) {
141 tst_resm(TFAIL, "write failed: nbytes=%d, errno=%d",
142 nbytes, errno);
143 cleanup();
144 }
robbiew3c658152003-01-07 21:50:34 +0000145
subrata_modak56207ce2009-03-23 13:35:39 +0000146 /*
147 * We should be at offset K4.
148 */
149 l_seek(fd, 0, SEEK_CUR, K4);
robbiew3c658152003-01-07 21:50:34 +0000150
subrata_modak56207ce2009-03-23 13:35:39 +0000151 /*
152 * pwrite() K1 of data (1's) at offset K1.
153 */
154 if ((nbytes = pwrite(fd, wbuf[1], K1, K1)) != K1) {
155 tst_resm(TFAIL, "pwrite failed: nbytes=%d, errno=%d",
156 nbytes, errno);
157 cleanup();
158 }
robbiew3c658152003-01-07 21:50:34 +0000159
160 /*--------------------------------------------------------------*/
161
162 /*
163 * Now test that O_APPEND takes precedence over any
164 * offset specified by pwrite(), but that the file
165 * pointer remains unchanged. First, close then reopen
166 * the file and ensure it is already K4 in length and
167 * set the file pointer to it's midpoint, K2.
168 */
169 close(fd);
170 if ((fd = open(fname, O_RDWR | O_APPEND, 0666)) < 0) {
vapiercff4af02006-02-11 04:46:30 +0000171 tst_resm(TBROK, "open failed: fname = %s, errno = %d",
subrata_modak56207ce2009-03-23 13:35:39 +0000172 fname, errno);
subrata_modak814e03c2008-11-11 06:44:51 +0000173 cleanup();
robbiew3c658152003-01-07 21:50:34 +0000174 }
175 if (fstat(fd, &statbuf) == -1) {
vapiercff4af02006-02-11 04:46:30 +0000176 tst_resm(TFAIL, "fstat failed: errno = %d", errno);
subrata_modak814e03c2008-11-11 06:44:51 +0000177 cleanup();
robbiew3c658152003-01-07 21:50:34 +0000178 }
179 if (statbuf.st_size != K4) {
subrata_modak56207ce2009-03-23 13:35:39 +0000180 tst_resm(TFAIL, "file size is %ld != K4",
181 statbuf.st_size);
subrata_modak814e03c2008-11-11 06:44:51 +0000182 cleanup();
robbiew3c658152003-01-07 21:50:34 +0000183 }
184 l_seek(fd, K2, SEEK_SET, K2);
185
186 /*
187 * Finally, pwrite() some K1 of data at offset 0.
188 * What we should end up with is:
subrata_modak56207ce2009-03-23 13:35:39 +0000189 * -The file pointer should still be at K2.
190 * -The data should have been written to the end
191 * of the file (O_APPEND) and should be K5 in size.
subrata_modakbdbaec52009-02-26 12:14:51 +0000192 */
robbiew3c658152003-01-07 21:50:34 +0000193 if ((nbytes = pwrite(fd, wbuf[0], K1, 0)) != K1) {
subrata_modak56207ce2009-03-23 13:35:39 +0000194 tst_resm(TFAIL,
195 "pwrite at 0 failed: nbytes=%d, errno=%d",
196 nbytes, errno);
Garrett Cooper2c282152010-12-16 00:55:50 -0800197
robbiew3c658152003-01-07 21:50:34 +0000198 }
199 l_seek(fd, 0, SEEK_CUR, K2);
200 if (fstat(fd, &statbuf) == -1) {
vapiercff4af02006-02-11 04:46:30 +0000201 tst_resm(TFAIL, "fstat failed: errno = %d", errno);
Garrett Cooper2c282152010-12-16 00:55:50 -0800202
robbiew3c658152003-01-07 21:50:34 +0000203 }
204 if (statbuf.st_size != K5) {
subrata_modak56207ce2009-03-23 13:35:39 +0000205 tst_resm(TFAIL, "file size is %ld != K4",
206 statbuf.st_size);
Garrett Cooper2c282152010-12-16 00:55:50 -0800207
robbiew3c658152003-01-07 21:50:34 +0000208 }
subrata_modak56207ce2009-03-23 13:35:39 +0000209 tst_resm(TPASS, "O_APPEND test passed.");
robbiew3c658152003-01-07 21:50:34 +0000210
211 /*------------------------------------------------------------------------*/
212
213 close(fd);
214 unlink(fname);
subrata_modak56207ce2009-03-23 13:35:39 +0000215 } /* end for */
subrata_modak814e03c2008-11-11 06:44:51 +0000216 cleanup();
Garrett Cooper1e6f5a62010-12-19 09:58:10 -0800217 tst_exit();
Garrett Cooper2c282152010-12-16 00:55:50 -0800218
robbiew3c658152003-01-07 21:50:34 +0000219}
220
221/*------------------------------------------------------------------------*/
222
223/*
224 * init_buffers() allocates wbuf[] array
225 * as follows:
226 * wbuf[0] has 0's, wbuf[1] has 1's, wbuf[2] has 2's, and wbuf[3] has 3's.
227 */
228void init_buffers(char *wbuf[])
229{
subrata_modak4bb656a2009-02-26 12:02:09 +0000230 int i;
robbiew3c658152003-01-07 21:50:34 +0000231
subrata_modak56207ce2009-03-23 13:35:39 +0000232 for (i = 0; i < NBUFS; i++) {
Cyril Hrubisd218f342014-09-23 13:14:56 +0200233 wbuf[i] = malloc(K1);
robbiew3c658152003-01-07 21:50:34 +0000234 if (wbuf[i] == NULL) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100235 tst_brkm(TBROK, NULL, "ib: malloc failed: errno=%d",
236 errno);
robbiew3c658152003-01-07 21:50:34 +0000237 }
238 memset(wbuf[i], i, K1);
239 }
240}
241
242/*
243 * l_seek() is a local front end to lseek().
244 * "checkoff" is the offset at which we believe we should be at.
245 * Used to validate pwrite doesn't move the offset.
246 */
subrata_modak56207ce2009-03-23 13:35:39 +0000247void l_seek(int fdesc, off_t offset, int whence, off_t checkoff)
robbiew3c658152003-01-07 21:50:34 +0000248{
249 off_t offloc;
250
251 if ((offloc = lseek(fdesc, offset, whence)) != checkoff) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100252 tst_brkm(TFAIL, NULL,
253 "(%ld = lseek(%d, %ld, %d)) != %ld) errno = %d",
subrata_modak56207ce2009-03-23 13:35:39 +0000254 offloc, fdesc, offset, whence, checkoff, errno);
robbiew3c658152003-01-07 21:50:34 +0000255 }
256}
257
subrata_modak814e03c2008-11-11 06:44:51 +0000258/*
259 * cleanup() - Performs all ONE TIME cleanup for this test at
260 * completion or premature exit.
261 *
262 * Print test timing stats and errno log if test executed with options.
263 * Close the testfile if still opened.
264 * Remove temporary directory and sub-directories/files under it
265 * created during setup().
266 * Exit the test program with normal exit code.
267 */
Mike Frysingerc57fba52014-04-09 18:56:30 -0400268void cleanup(void)
subrata_modak814e03c2008-11-11 06:44:51 +0000269{
subrata_modak814e03c2008-11-11 06:44:51 +0000270
subrata_modak814e03c2008-11-11 06:44:51 +0000271 tst_rmdir();
272
Chris Dearmanec6edca2012-10-17 19:54:01 -0700273}