1 /* Tests of fseek and fseeko.
2 Copyright (C) 2000-2023 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library 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 the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
28 #include <support/support.h>
37 const char outstr
[] = "hello world!\n";
38 char strbuf
[sizeof outstr
];
44 tmpdir
= getenv ("TMPDIR");
45 if (tmpdir
== NULL
|| tmpdir
[0] == '\0')
48 fname
= xasprintf ("%s/tst-fseek.XXXXXX", tmpdir
);
50 /* Create a temporary file. */
53 error (EXIT_FAILURE
, errno
, "cannot open temporary file");
55 fp
= fdopen (fd
, "w+");
57 error (EXIT_FAILURE
, errno
, "cannot get FILE for temporary file");
59 setbuffer (fp
, strbuf
, sizeof (outstr
) -1);
61 if (fwrite (outstr
, sizeof (outstr
) - 1, 1, fp
) != 1)
63 printf ("%d: write error\n", __LINE__
);
68 /* The EOF flag must be reset. */
69 if (fgetc (fp
) != EOF
)
71 printf ("%d: managed to read at end of file\n", __LINE__
);
76 printf ("%d: EOF flag not set\n", __LINE__
);
79 if (fseek (fp
, 0, SEEK_CUR
) != 0)
81 printf ("%d: fseek(fp, 0, SEEK_CUR) failed\n", __LINE__
);
86 printf ("%d: fseek() didn't reset EOF flag\n", __LINE__
);
90 /* Do the same for fseeko(). */
91 if (fgetc (fp
) != EOF
)
93 printf ("%d: managed to read at end of file\n", __LINE__
);
98 printf ("%d: EOF flag not set\n", __LINE__
);
101 if (fseeko (fp
, 0, SEEK_CUR
) != 0)
103 printf ("%d: fseek(fp, 0, SEEK_CUR) failed\n", __LINE__
);
108 printf ("%d: fseek() didn't reset EOF flag\n", __LINE__
);
112 /* Go back to the beginning of the file: absolute. */
113 if (fseek (fp
, 0, SEEK_SET
) != 0)
115 printf ("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__
);
118 else if (fflush (fp
) != 0)
120 printf ("%d: fflush() failed\n", __LINE__
);
123 else if (lseek (fd
, 0, SEEK_CUR
) != 0)
125 printf ("%d: lseek() returned different position\n", __LINE__
);
128 else if (fread (buf
, sizeof (outstr
) - 1, 1, fp
) != 1)
130 printf ("%d: fread() failed\n", __LINE__
);
133 else if (memcmp (buf
, outstr
, sizeof (outstr
) - 1) != 0)
135 printf ("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__
);
139 /* Now with fseeko. */
140 if (fseeko (fp
, 0, SEEK_SET
) != 0)
142 printf ("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__
);
145 else if (fflush (fp
) != 0)
147 printf ("%d: fflush() failed\n", __LINE__
);
150 else if (lseek (fd
, 0, SEEK_CUR
) != 0)
152 printf ("%d: lseek() returned different position\n", __LINE__
);
155 else if (fread (buf
, sizeof (outstr
) - 1, 1, fp
) != 1)
157 printf ("%d: fread() failed\n", __LINE__
);
160 else if (memcmp (buf
, outstr
, sizeof (outstr
) - 1) != 0)
162 printf ("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__
);
166 /* Go back to the beginning of the file: relative. */
167 if (fseek (fp
, -((int) sizeof (outstr
) - 1), SEEK_CUR
) != 0)
169 printf ("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__
);
172 else if (fflush (fp
) != 0)
174 printf ("%d: fflush() failed\n", __LINE__
);
177 else if (lseek (fd
, 0, SEEK_CUR
) != 0)
179 printf ("%d: lseek() returned different position\n", __LINE__
);
182 else if (fread (buf
, sizeof (outstr
) - 1, 1, fp
) != 1)
184 printf ("%d: fread() failed\n", __LINE__
);
187 else if (memcmp (buf
, outstr
, sizeof (outstr
) - 1) != 0)
189 printf ("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__
);
193 /* Now with fseeko. */
194 if (fseeko (fp
, -((int) sizeof (outstr
) - 1), SEEK_CUR
) != 0)
196 printf ("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__
);
199 else if (fflush (fp
) != 0)
201 printf ("%d: fflush() failed\n", __LINE__
);
204 else if (lseek (fd
, 0, SEEK_CUR
) != 0)
206 printf ("%d: lseek() returned different position\n", __LINE__
);
209 else if (fread (buf
, sizeof (outstr
) - 1, 1, fp
) != 1)
211 printf ("%d: fread() failed\n", __LINE__
);
214 else if (memcmp (buf
, outstr
, sizeof (outstr
) - 1) != 0)
216 printf ("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__
);
220 /* Go back to the beginning of the file: from the end. */
221 if (fseek (fp
, -((int) sizeof (outstr
) - 1), SEEK_END
) != 0)
223 printf ("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__
);
226 else if (fflush (fp
) != 0)
228 printf ("%d: fflush() failed\n", __LINE__
);
231 else if (lseek (fd
, 0, SEEK_CUR
) != 0)
233 printf ("%d: lseek() returned different position\n", __LINE__
);
236 else if (fread (buf
, sizeof (outstr
) - 1, 1, fp
) != 1)
238 printf ("%d: fread() failed\n", __LINE__
);
241 else if (memcmp (buf
, outstr
, sizeof (outstr
) - 1) != 0)
243 printf ("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__
);
247 /* Now with fseeko. */
248 if (fseeko (fp
, -((int) sizeof (outstr
) - 1), SEEK_END
) != 0)
250 printf ("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__
);
253 else if (fflush (fp
) != 0)
255 printf ("%d: fflush() failed\n", __LINE__
);
258 else if (lseek (fd
, 0, SEEK_CUR
) != 0)
260 printf ("%d: lseek() returned different position\n", __LINE__
);
263 else if (fread (buf
, sizeof (outstr
) - 1, 1, fp
) != 1)
265 printf ("%d: fread() failed\n", __LINE__
);
268 else if (memcmp (buf
, outstr
, sizeof (outstr
) - 1) != 0)
270 printf ("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__
);
274 if (fwrite (outstr
, sizeof (outstr
) - 1, 1, fp
) != 1)
276 printf ("%d: write error 2\n", __LINE__
);
281 if (fwrite (outstr
, sizeof (outstr
) - 1, 1, fp
) != 1)
283 printf ("%d: write error 3\n", __LINE__
);
288 if (fwrite (outstr
, sizeof (outstr
) - 1, 1, fp
) != 1)
290 printf ("%d: write error 4\n", __LINE__
);
295 if (fwrite (outstr
, sizeof (outstr
) - 1, 1, fp
) != 1)
297 printf ("%d: write error 5\n", __LINE__
);
302 if (fputc ('1', fp
) == EOF
|| fputc ('2', fp
) == EOF
)
304 printf ("%d: cannot add characters at the end\n", __LINE__
);
309 /* Check the access time. */
310 if (fstat64 (fd
, &st1
) < 0)
312 printf ("%d: fstat64() before fseeko() failed\n\n", __LINE__
);
319 if (fseek (fp
, -(2 + 2 * (sizeof (outstr
) - 1)), SEEK_CUR
) != 0)
321 printf ("%d: fseek() after write characters failed\n", __LINE__
);
329 /* Make sure the timestamp actually can be different. */
333 if (fstat64 (fd
, &st2
) < 0)
335 printf ("%d: fstat64() after fseeko() failed\n\n", __LINE__
);
338 if (st1
.st_ctime
>= t
)
340 printf ("%d: st_ctime not updated\n", __LINE__
);
343 if (st1
.st_mtime
>= t
)
345 printf ("%d: st_mtime not updated\n", __LINE__
);
348 if (st1
.st_ctime
>= st2
.st_ctime
)
350 printf ("%d: st_ctime not changed\n", __LINE__
);
353 if (st1
.st_mtime
>= st2
.st_mtime
)
355 printf ("%d: st_mtime not changed\n", __LINE__
);
361 if (fread (buf
, 1, 2 + 2 * (sizeof (outstr
) - 1), fp
)
362 != 2 + 2 * (sizeof (outstr
) - 1))
364 printf ("%d: reading 2 records plus bits failed\n", __LINE__
);
367 else if (memcmp (buf
, outstr
, sizeof (outstr
) - 1) != 0
368 || memcmp (&buf
[sizeof (outstr
) - 1], outstr
,
369 sizeof (outstr
) - 1) != 0
370 || buf
[2 * (sizeof (outstr
) - 1)] != '1'
371 || buf
[2 * (sizeof (outstr
) - 1) + 1] != '2')
373 printf ("%d: reading records failed\n", __LINE__
);
376 else if (ungetc ('9', fp
) == EOF
)
378 printf ("%d: ungetc() failed\n", __LINE__
);
381 else if (fseek (fp
, -(2 + 2 * (sizeof (outstr
) - 1)), SEEK_END
) != 0)
383 printf ("%d: fseek after ungetc failed\n", __LINE__
);
386 else if (fread (buf
, 1, 2 + 2 * (sizeof (outstr
) - 1), fp
)
387 != 2 + 2 * (sizeof (outstr
) - 1))
389 printf ("%d: reading 2 records plus bits failed\n", __LINE__
);
392 else if (memcmp (buf
, outstr
, sizeof (outstr
) - 1) != 0
393 || memcmp (&buf
[sizeof (outstr
) - 1], outstr
,
394 sizeof (outstr
) - 1) != 0
395 || buf
[2 * (sizeof (outstr
) - 1)] != '1')
397 printf ("%d: reading records for the second time failed\n", __LINE__
);
400 else if (buf
[2 * (sizeof (outstr
) - 1) + 1] == '9')
402 printf ("%d: unget character not ignored\n", __LINE__
);
405 else if (buf
[2 * (sizeof (outstr
) - 1) + 1] != '2')
407 printf ("%d: unget somehow changed character\n", __LINE__
);
413 fp
= fopen (fname
, "r");
416 printf ("%d: fopen() failed\n\n", __LINE__
);
419 else if (fstat64 (fileno (fp
), &st1
) < 0)
421 printf ("%d: fstat64() before fseeko() failed\n\n", __LINE__
);
424 else if (fseeko (fp
, 0, SEEK_END
) != 0)
426 printf ("%d: fseeko(fp, 0, SEEK_END) failed\n", __LINE__
);
429 else if (ftello (fp
) != st1
.st_size
)
431 printf ("%d: fstat64 st_size %zd ftello %zd\n", __LINE__
,
432 (size_t) st1
.st_size
, (size_t) ftello (fp
));
436 printf ("%d: SEEK_END works\n", __LINE__
);
440 fp
= fopen (fname
, "r");
443 printf ("%d: fopen() failed\n\n", __LINE__
);
446 else if (fstat64 (fileno (fp
), &st1
) < 0)
448 printf ("%d: fstat64() before fgetc() failed\n\n", __LINE__
);
451 else if (fgetc (fp
) == EOF
)
453 printf ("%d: fgetc() before fseeko() failed\n\n", __LINE__
);
456 else if (fseeko (fp
, 0, SEEK_END
) != 0)
458 printf ("%d: fseeko(fp, 0, SEEK_END) failed\n", __LINE__
);
461 else if (ftello (fp
) != st1
.st_size
)
463 printf ("%d: fstat64 st_size %zd ftello %zd\n", __LINE__
,
464 (size_t) st1
.st_size
, (size_t) ftello (fp
));
468 printf ("%d: SEEK_END works\n", __LINE__
);
478 #define TEST_FUNCTION do_test ()
479 #include "../test-skeleton.c"