.
[glibc/history.git] / stdio-common / tst-fseek.c
blob8992f7d456dd31bda14a878c165d1d7dc03d1adb
1 /* Tests of fseek and fseeko.
2 Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Ulrich Drepper <drepper@redhat.com>, 2000.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA. */
21 #include <error.h>
22 #include <errno.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <unistd.h>
27 #include <time.h>
28 #include <sys/stat.h>
31 int
32 main (void)
34 const char *tmpdir;
35 char *fname;
36 int fd;
37 FILE *fp;
38 const char outstr[] = "hello world!\n";
39 char strbuf[sizeof outstr];
40 char buf[200];
41 struct stat64 st1;
42 struct stat64 st2;
43 int result = 0;
45 tmpdir = getenv ("TMPDIR");
46 if (tmpdir == NULL || tmpdir[0] == '\0')
47 tmpdir = "/tmp";
49 asprintf (&fname, "%s/tst-fseek.XXXXXX", tmpdir);
50 if (fname == NULL)
51 error (EXIT_FAILURE, errno, "cannot generate name for temporary file");
53 /* Create a temporary file. */
54 fd = mkstemp (fname);
55 if (fd == -1)
56 error (EXIT_FAILURE, errno, "cannot open temporary file");
58 fp = fdopen (fd, "w+");
59 if (fp == NULL)
60 error (EXIT_FAILURE, errno, "cannot get FILE for temporary file");
62 setbuffer (fp, strbuf, sizeof (outstr) -1);
64 if (fwrite (outstr, sizeof (outstr) - 1, 1, fp) != 1)
66 printf ("%d: write error\n", __LINE__);
67 result = 1;
68 goto out;
71 /* The EOF flag must be reset. */
72 if (fgetc (fp) != EOF)
74 printf ("%d: managed to read at end of file\n", __LINE__);
75 result = 1;
77 else if (! feof (fp))
79 printf ("%d: EOF flag not set\n", __LINE__);
80 result = 1;
82 if (fseek (fp, 0, SEEK_CUR) != 0)
84 printf ("%d: fseek(fp, 0, SEEK_CUR) failed\n", __LINE__);
85 result = 1;
87 else if (feof (fp))
89 printf ("%d: fseek() didn't reset EOF flag\n", __LINE__);
90 result = 1;
93 /* Do the same for fseeko(). */
94 if (fgetc (fp) != EOF)
96 printf ("%d: managed to read at end of file\n", __LINE__);
97 result = 1;
99 else if (! feof (fp))
101 printf ("%d: EOF flag not set\n", __LINE__);
102 result = 1;
104 if (fseeko (fp, 0, SEEK_CUR) != 0)
106 printf ("%d: fseek(fp, 0, SEEK_CUR) failed\n", __LINE__);
107 result = 1;
109 else if (feof (fp))
111 printf ("%d: fseek() didn't reset EOF flag\n", __LINE__);
112 result = 1;
115 /* Go back to the beginning of the file: absolute. */
116 if (fseek (fp, 0, SEEK_SET) != 0)
118 printf ("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__);
119 result = 1;
121 else if (fflush (fp) != 0)
123 printf ("%d: fflush() failed\n", __LINE__);
124 result = 1;
126 else if (lseek (fd, 0, SEEK_CUR) != 0)
128 printf ("%d: lseek() returned different position\n", __LINE__);
129 result = 1;
131 else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1)
133 printf ("%d: fread() failed\n", __LINE__);
134 result = 1;
136 else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0)
138 printf ("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__);
139 result = 1;
142 /* Now with fseeko. */
143 if (fseeko (fp, 0, SEEK_SET) != 0)
145 printf ("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__);
146 result = 1;
148 else if (fflush (fp) != 0)
150 printf ("%d: fflush() failed\n", __LINE__);
151 result = 1;
153 else if (lseek (fd, 0, SEEK_CUR) != 0)
155 printf ("%d: lseek() returned different position\n", __LINE__);
156 result = 1;
158 else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1)
160 printf ("%d: fread() failed\n", __LINE__);
161 result = 1;
163 else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0)
165 printf ("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__);
166 result = 1;
169 /* Go back to the beginning of the file: relative. */
170 if (fseek (fp, -((int) sizeof (outstr) - 1), SEEK_CUR) != 0)
172 printf ("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__);
173 result = 1;
175 else if (fflush (fp) != 0)
177 printf ("%d: fflush() failed\n", __LINE__);
178 result = 1;
180 else if (lseek (fd, 0, SEEK_CUR) != 0)
182 printf ("%d: lseek() returned different position\n", __LINE__);
183 result = 1;
185 else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1)
187 printf ("%d: fread() failed\n", __LINE__);
188 result = 1;
190 else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0)
192 printf ("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__);
193 result = 1;
196 /* Now with fseeko. */
197 if (fseeko (fp, -((int) sizeof (outstr) - 1), SEEK_CUR) != 0)
199 printf ("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__);
200 result = 1;
202 else if (fflush (fp) != 0)
204 printf ("%d: fflush() failed\n", __LINE__);
205 result = 1;
207 else if (lseek (fd, 0, SEEK_CUR) != 0)
209 printf ("%d: lseek() returned different position\n", __LINE__);
210 result = 1;
212 else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1)
214 printf ("%d: fread() failed\n", __LINE__);
215 result = 1;
217 else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0)
219 printf ("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__);
220 result = 1;
223 /* Go back to the beginning of the file: from the end. */
224 if (fseek (fp, -((int) sizeof (outstr) - 1), SEEK_END) != 0)
226 printf ("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__);
227 result = 1;
229 else if (fflush (fp) != 0)
231 printf ("%d: fflush() failed\n", __LINE__);
232 result = 1;
234 else if (lseek (fd, 0, SEEK_CUR) != 0)
236 printf ("%d: lseek() returned different position\n", __LINE__);
237 result = 1;
239 else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1)
241 printf ("%d: fread() failed\n", __LINE__);
242 result = 1;
244 else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0)
246 printf ("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__);
247 result = 1;
250 /* Now with fseeko. */
251 if (fseeko (fp, -((int) sizeof (outstr) - 1), SEEK_END) != 0)
253 printf ("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__);
254 result = 1;
256 else if (fflush (fp) != 0)
258 printf ("%d: fflush() failed\n", __LINE__);
259 result = 1;
261 else if (lseek (fd, 0, SEEK_CUR) != 0)
263 printf ("%d: lseek() returned different position\n", __LINE__);
264 result = 1;
266 else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1)
268 printf ("%d: fread() failed\n", __LINE__);
269 result = 1;
271 else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0)
273 printf ("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__);
274 result = 1;
277 if (fwrite (outstr, sizeof (outstr) - 1, 1, fp) != 1)
279 printf ("%d: write error 2\n", __LINE__);
280 result = 1;
281 goto out;
284 if (fwrite (outstr, sizeof (outstr) - 1, 1, fp) != 1)
286 printf ("%d: write error 3\n", __LINE__);
287 result = 1;
288 goto out;
291 if (fwrite (outstr, sizeof (outstr) - 1, 1, fp) != 1)
293 printf ("%d: write error 4\n", __LINE__);
294 result = 1;
295 goto out;
298 if (fwrite (outstr, sizeof (outstr) - 1, 1, fp) != 1)
300 printf ("%d: write error 5\n", __LINE__);
301 result = 1;
302 goto out;
305 if (fputc ('1', fp) == EOF || fputc ('2', fp) == EOF)
307 printf ("%d: cannot add characters at the end\n", __LINE__);
308 result = 1;
309 goto out;
312 /* Check the access time. */
313 if (fstat64 (fd, &st1) < 0)
315 printf ("%d: fstat64() before fseeko() failed\n\n", __LINE__);
316 result = 1;
318 else
320 sleep (1);
322 if (fseek (fp, -(2 + 2 * (sizeof (outstr) - 1)), SEEK_CUR) != 0)
324 printf ("%d: fseek() after write characters failed\n", __LINE__);
325 result = 1;
326 goto out;
328 else
331 time_t t;
332 /* Make sure the timestamp actually can be different. */
333 sleep (1);
334 t = time (NULL);
336 if (fstat64 (fd, &st2) < 0)
338 printf ("%d: fstat64() after fseeko() failed\n\n", __LINE__);
339 result = 1;
341 if (st1.st_ctime >= t)
343 printf ("%d: st_ctime not updated\n", __LINE__);
344 result = 1;
346 if (st1.st_mtime >= t)
348 printf ("%d: st_mtime not updated\n", __LINE__);
349 result = 1;
351 if (st1.st_ctime >= st2.st_ctime)
353 printf ("%d: st_ctime not changed\n", __LINE__);
354 result = 1;
356 if (st1.st_mtime >= st2.st_mtime)
358 printf ("%d: st_mtime not changed\n", __LINE__);
359 result = 1;
364 if (fread (buf, 1, 2 + 2 * (sizeof (outstr) - 1), fp)
365 != 2 + 2 * (sizeof (outstr) - 1))
367 printf ("%d: reading 2 records plus bits failed\n", __LINE__);
368 result = 1;
370 else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0
371 || memcmp (&buf[sizeof (outstr) - 1], outstr,
372 sizeof (outstr) - 1) != 0
373 || buf[2 * (sizeof (outstr) - 1)] != '1'
374 || buf[2 * (sizeof (outstr) - 1) + 1] != '2')
376 printf ("%d: reading records failed\n", __LINE__);
377 result = 1;
379 else if (ungetc ('9', fp) == EOF)
381 printf ("%d: ungetc() failed\n", __LINE__);
382 result = 1;
384 else if (fseek (fp, -(2 + 2 * (sizeof (outstr) - 1)), SEEK_END) != 0)
386 printf ("%d: fseek after ungetc failed\n", __LINE__);
387 result = 1;
389 else if (fread (buf, 1, 2 + 2 * (sizeof (outstr) - 1), fp)
390 != 2 + 2 * (sizeof (outstr) - 1))
392 printf ("%d: reading 2 records plus bits failed\n", __LINE__);
393 result = 1;
395 else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0
396 || memcmp (&buf[sizeof (outstr) - 1], outstr,
397 sizeof (outstr) - 1) != 0
398 || buf[2 * (sizeof (outstr) - 1)] != '1')
400 printf ("%d: reading records for the second time failed\n", __LINE__);
401 result = 1;
403 else if (buf[2 * (sizeof (outstr) - 1) + 1] == '9')
405 printf ("%d: unget character not ignored\n", __LINE__);
406 result = 1;
408 else if (buf[2 * (sizeof (outstr) - 1) + 1] != '2')
410 printf ("%d: unget somehow changed character\n", __LINE__);
411 result = 1;
414 fclose (fp);
416 fp = fopen (fname, "r");
417 if (fp == NULL)
419 printf ("%d: fopen() failed\n\n", __LINE__);
420 result = 1;
422 else if (fstat64 (fileno (fp), &st1) < 0)
424 printf ("%d: fstat64() before fseeko() failed\n\n", __LINE__);
425 result = 1;
427 else if (fseeko (fp, 0, SEEK_END) != 0)
429 printf ("%d: fseeko(fp, 0, SEEK_END) failed\n", __LINE__);
430 result = 1;
432 else if (ftello (fp) != st1.st_size)
434 printf ("%d: fstat64 st_size %zd ftello %zd\n", __LINE__,
435 (size_t) st1.st_size, (size_t) ftello (fp));
436 result = 1;
438 else
439 printf ("%d: SEEK_END works\n", __LINE__);
440 if (fp != NULL)
441 fclose (fp);
443 fp = fopen (fname, "r");
444 if (fp == NULL)
446 printf ("%d: fopen() failed\n\n", __LINE__);
447 result = 1;
449 else if (fstat64 (fileno (fp), &st1) < 0)
451 printf ("%d: fstat64() before fgetc() failed\n\n", __LINE__);
452 result = 1;
454 else if (fgetc (fp) == EOF)
456 printf ("%d: fgetc() before fseeko() failed\n\n", __LINE__);
457 result = 1;
459 else if (fseeko (fp, 0, SEEK_END) != 0)
461 printf ("%d: fseeko(fp, 0, SEEK_END) failed\n", __LINE__);
462 result = 1;
464 else if (ftello (fp) != st1.st_size)
466 printf ("%d: fstat64 st_size %zd ftello %zd\n", __LINE__,
467 (size_t) st1.st_size, (size_t) ftello (fp));
468 result = 1;
470 else
471 printf ("%d: SEEK_END works\n", __LINE__);
472 if (fp != NULL)
473 fclose (fp);
475 out:
476 unlink (fname);
478 return result;