1/*
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
17 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20/* ported from SPIE, section2/filesuite/stream3.c, by Airong Zhang */
21
22/*======================================================================
23	=================== TESTPLAN SEGMENT ===================
24>KEYS:  < fseek() ftell()
25>WHAT:  < 1) Ensure ftell reports the correct current byte offset.
26>HOW:   < 1) Open a file, write to it, reposition the file pointer and
27	     check it.
28>BUGS:  <
29======================================================================*/
30#define _XOPEN_SOURCE 500
31#include <stdio.h>
32#include <errno.h>
33#include <fcntl.h>
34#include <sys/types.h>
35#include <sys/stat.h>
36#include <inttypes.h>
37#include "test.h"
38
39char *TCID = "stream03";
40int TST_TOTAL = 1;
41int local_flag;
42
43#define PASSED 1
44#define FAILED 0
45
46char progname[] = "stream03()";
47char tempfile1[40] = "";
48
49int main(int ac, char *av[])
50{
51	FILE *stream;
52	char buf[30];
53	char *junk = "abcdefghijklmnopqrstuvwxyz";
54	long pos;
55	off_t opos;
56	int lc;
57
58	/*
59	 * parse standard options
60	 */
61	tst_parse_opts(ac, av, NULL, NULL);
62
63	local_flag = PASSED;
64	tst_tmpdir();
65
66	for (lc = 0; TEST_LOOPING(lc); lc++) {
67
68		sprintf(tempfile1, "stream03.%d", getpid());
69	/*--------------------------------------------------------------------*/
70		//block0:
71
72		if ((stream = fopen(tempfile1, "a+")) == NULL) {
73			tst_brkm(TBROK, NULL, "fopen(%s) a+ failed: %s",
74				 tempfile1,
75				 strerror(errno));
76		}
77
78		/* make sure offset of zero at start */
79		pos = ftell(stream);
80
81		if (pos != 0) {
82			tst_resm(TFAIL, "file pointer descrepancy 1");
83			local_flag = FAILED;
84		}
85
86		/* write something and check */
87		if (fwrite(junk, sizeof(*junk), strlen(junk), stream) == 0) {
88			tst_brkm(TFAIL, NULL, "fwrite failed: %s",
89				 strerror(errno));
90		}
91
92		pos = ftell(stream);
93
94		if (pos != strlen(junk)) {
95			tst_resm(TFAIL,
96				 "strlen(junk)=%zi: file pointer descrepancy 2 (pos=%li)",
97				 strlen(junk), pos);
98			local_flag = FAILED;
99		}
100
101		/* rewind and check */
102		rewind(stream);
103		pos = ftell(stream);
104
105		if (pos != 0) {
106			tst_resm(TFAIL,
107				 "file pointer descrepancy 3 (pos=%li, wanted pos=0)",
108				 pos);
109			local_flag = FAILED;
110		}
111
112		/* seek from current position and then check */
113		if (fseek(stream, strlen(junk), 1) != 0) {
114			tst_brkm(TFAIL, NULL, "fseek failed: %s",
115				 strerror(errno));
116		}
117
118		pos = ftell(stream);
119
120		if (pos != strlen(junk)) {
121			tst_resm(TFAIL,
122				 "strlen(junk)=%zi: file pointer descrepancy 4 (pos=%li)",
123				 strlen(junk), pos);
124			local_flag = FAILED;
125		}
126
127		/* seek from end of file and then check */
128		if (fseek(stream, 0, 2) != 0) {
129			tst_brkm(TFAIL, NULL, "fseek failed: %s",
130				 strerror(errno));
131		}
132
133		pos = ftell(stream);
134
135		if (pos != strlen(junk)) {
136			tst_resm(TFAIL,
137				 "strlen(junk)=%zi: file pointer descrepancy 5 (pos=%li)",
138				 strlen(junk), pos);
139			local_flag = FAILED;
140		}
141
142		/* rewind with seek and then check */
143		if (fseek(stream, 0, 0) != 0) {
144			tst_brkm(TFAIL, NULL, "fseek failed: %s",
145				 strerror(errno));
146		}
147
148		pos = ftell(stream);
149
150		if (pos != 0) {
151			tst_resm(TFAIL,
152				 "file pointer descrepancy 6 (pos=%li, wanted pos=0)",
153				 pos);
154			local_flag = FAILED;
155		}
156
157		/* read till EOF, do getc and then check ftell */
158		while (fgets(buf, sizeof(buf), stream)) ;
159		pos = ftell(stream);
160		getc(stream);
161		pos = ftell(stream);
162
163		if (pos != strlen(junk)) {
164			tst_resm(TFAIL,
165				 "strlen(junk)=%zi: file pointer descrepancy 7 (pos=%li)",
166				 strlen(junk), pos);
167			local_flag = FAILED;
168		}
169
170		fclose(stream);
171
172		if (local_flag == PASSED) {
173			tst_resm(TPASS, "Test passed in block0.");
174		} else {
175			tst_resm(TFAIL, "Test failed in block0.");
176		}
177
178		local_flag = PASSED;
179
180		unlink(tempfile1);
181	/*--------------------------------------------------------------------*/
182		//block1:
183		if ((stream = fopen(tempfile1, "a+")) == NULL) {
184			tst_brkm(TFAIL, NULL, "fopen(%s) a+ failed: %s",
185				 tempfile1,
186				 strerror(errno));
187		}
188
189		/* make sure offset of zero at start */
190		opos = ftello(stream);
191
192		if (opos != 0) {
193			tst_resm(TFAIL,
194				 "file pointer descrepancy 1 (opos=%" PRId64
195				 ", wanted opos=0)", (int64_t) opos);
196			local_flag = FAILED;
197		}
198
199		/* write something and check */
200		if (fwrite(junk, sizeof(*junk), strlen(junk), stream) == 0) {
201			tst_brkm(TFAIL, NULL, "fwrite failed: %s",
202				 strerror(errno));
203		}
204
205		opos = ftello(stream);
206
207		if (opos != strlen(junk)) {
208			tst_resm(TFAIL,
209				 "strlen(junk)=%zi: file pointer descrepancy 2 (opos=%"
210				 PRId64 ")", strlen(junk), (int64_t) opos);
211			local_flag = FAILED;
212		}
213
214		/* rewind and check */
215		rewind(stream);
216		opos = ftello(stream);
217
218		if (opos != 0) {
219			tst_resm(TFAIL,
220				 "file pointer descrepancy 3 (opos=%" PRId64
221				 ", wanted opos=0)", (int64_t) opos);
222			local_flag = FAILED;
223		}
224
225		/* seek from current position and then check */
226		if (fseeko(stream, strlen(junk), 1) != 0) {
227			tst_brkm(TFAIL, NULL, "fseeko failed: %s",
228				 strerror(errno));
229		}
230
231		opos = ftello(stream);
232
233		if (opos != strlen(junk)) {
234			tst_resm(TFAIL,
235				 "strlen(junk)=%zi: file pointer descrepancy 4 (opos=%"
236				 PRId64 ")", strlen(junk), (int64_t) opos);
237			local_flag = FAILED;
238		}
239
240		/* seek from end of file and then check */
241		if (fseeko(stream, 0, 2) != 0) {
242			tst_brkm(TFAIL, NULL, "fseeko failed: %s",
243				 strerror(errno));
244		}
245
246		opos = ftello(stream);
247
248		if (opos != strlen(junk)) {
249			tst_resm(TFAIL,
250				 "strlen(junk)=%zi: file pointer descrepancy 5 (opos=%"
251				 PRId64 ")", strlen(junk), (int64_t) opos);
252			local_flag = FAILED;
253		}
254
255		/* rewind with seek and then check */
256		if (fseeko(stream, 0, 0) != 0) {
257			tst_brkm(TFAIL, NULL, "fseeko failed: %s",
258				 strerror(errno));
259		}
260
261		opos = ftello(stream);
262
263		if (opos != 0) {
264			tst_resm(TFAIL,
265				 "file pointer descrepancy 6 (opos=%" PRId64
266				 ", wanted opos=0)", (int64_t) opos);
267			local_flag = FAILED;
268		}
269
270		/* read till EOF, do getc and then check ftello */
271		while (fgets(buf, sizeof(buf), stream)) ;
272
273		opos = ftello(stream);
274		getc(stream);
275		opos = ftello(stream);
276
277		if (opos != strlen(junk)) {
278			tst_resm(TFAIL,
279				 "strlen(junk)=%zi: file pointer descrepancy 7 (opos=%li)",
280				 strlen(junk), opos);
281			local_flag = FAILED;
282		}
283
284		fclose(stream);
285
286		if (local_flag == PASSED) {
287			tst_resm(TPASS, "Test passed in block1.");
288		} else {
289			tst_resm(TFAIL, "Test failed in block1.");
290		}
291
292		unlink(tempfile1);
293	}
294
295	tst_rmdir();
296	tst_exit();
297}
298