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/>. */
36 const char outstr
[] = "hello world!\n";
37 char strbuf
[sizeof outstr
];
43 tmpdir
= getenv ("TMPDIR");
44 if (tmpdir
== NULL
|| tmpdir
[0] == '\0')
47 asprintf (&fname
, "%s/tst-fseek.XXXXXX", tmpdir
);
49 error (EXIT_FAILURE
, errno
, "cannot generate name for temporary file");
51 /* Create a temporary file. */
54 error (EXIT_FAILURE
, errno
, "cannot open temporary file");
56 fp
= fdopen (fd
, "w+");
58 error (EXIT_FAILURE
, errno
, "cannot get FILE for temporary file");
60 setbuffer (fp
, strbuf
, sizeof (outstr
) -1);
62 if (fwrite (outstr
, sizeof (outstr
) - 1, 1, fp
) != 1)
64 printf ("%d: write error\n", __LINE__
);
69 /* The EOF flag must be reset. */
70 if (fgetc (fp
) != EOF
)
72 printf ("%d: managed to read at end of file\n", __LINE__
);
77 printf ("%d: EOF flag not set\n", __LINE__
);
80 if (fseek (fp
, 0, SEEK_CUR
) != 0)
82 printf ("%d: fseek(fp, 0, SEEK_CUR) failed\n", __LINE__
);
87 printf ("%d: fseek() didn't reset EOF flag\n", __LINE__
);
91 /* Do the same for fseeko(). */
92 if (fgetc (fp
) != EOF
)
94 printf ("%d: managed to read at end of file\n", __LINE__
);
99 printf ("%d: EOF flag not set\n", __LINE__
);
102 if (fseeko (fp
, 0, SEEK_CUR
) != 0)
104 printf ("%d: fseek(fp, 0, SEEK_CUR) failed\n", __LINE__
);
109 printf ("%d: fseek() didn't reset EOF flag\n", __LINE__
);
113 /* Go back to the beginning of the file: absolute. */
114 if (fseek (fp
, 0, SEEK_SET
) != 0)
116 printf ("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__
);
119 else if (fflush (fp
) != 0)
121 printf ("%d: fflush() failed\n", __LINE__
);
124 else if (lseek (fd
, 0, SEEK_CUR
) != 0)
126 printf ("%d: lseek() returned different position\n", __LINE__
);
129 else if (fread (buf
, sizeof (outstr
) - 1, 1, fp
) != 1)
131 printf ("%d: fread() failed\n", __LINE__
);
134 else if (memcmp (buf
, outstr
, sizeof (outstr
) - 1) != 0)
136 printf ("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__
);
140 /* Now with fseeko. */
141 if (fseeko (fp
, 0, SEEK_SET
) != 0)
143 printf ("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__
);
146 else if (fflush (fp
) != 0)
148 printf ("%d: fflush() failed\n", __LINE__
);
151 else if (lseek (fd
, 0, SEEK_CUR
) != 0)
153 printf ("%d: lseek() returned different position\n", __LINE__
);
156 else if (fread (buf
, sizeof (outstr
) - 1, 1, fp
) != 1)
158 printf ("%d: fread() failed\n", __LINE__
);
161 else if (memcmp (buf
, outstr
, sizeof (outstr
) - 1) != 0)
163 printf ("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__
);
167 /* Go back to the beginning of the file: relative. */
168 if (fseek (fp
, -((int) sizeof (outstr
) - 1), SEEK_CUR
) != 0)
170 printf ("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__
);
173 else if (fflush (fp
) != 0)
175 printf ("%d: fflush() failed\n", __LINE__
);
178 else if (lseek (fd
, 0, SEEK_CUR
) != 0)
180 printf ("%d: lseek() returned different position\n", __LINE__
);
183 else if (fread (buf
, sizeof (outstr
) - 1, 1, fp
) != 1)
185 printf ("%d: fread() failed\n", __LINE__
);
188 else if (memcmp (buf
, outstr
, sizeof (outstr
) - 1) != 0)
190 printf ("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__
);
194 /* Now with fseeko. */
195 if (fseeko (fp
, -((int) sizeof (outstr
) - 1), SEEK_CUR
) != 0)
197 printf ("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__
);
200 else if (fflush (fp
) != 0)
202 printf ("%d: fflush() failed\n", __LINE__
);
205 else if (lseek (fd
, 0, SEEK_CUR
) != 0)
207 printf ("%d: lseek() returned different position\n", __LINE__
);
210 else if (fread (buf
, sizeof (outstr
) - 1, 1, fp
) != 1)
212 printf ("%d: fread() failed\n", __LINE__
);
215 else if (memcmp (buf
, outstr
, sizeof (outstr
) - 1) != 0)
217 printf ("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__
);
221 /* Go back to the beginning of the file: from the end. */
222 if (fseek (fp
, -((int) sizeof (outstr
) - 1), SEEK_END
) != 0)
224 printf ("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__
);
227 else if (fflush (fp
) != 0)
229 printf ("%d: fflush() failed\n", __LINE__
);
232 else if (lseek (fd
, 0, SEEK_CUR
) != 0)
234 printf ("%d: lseek() returned different position\n", __LINE__
);
237 else if (fread (buf
, sizeof (outstr
) - 1, 1, fp
) != 1)
239 printf ("%d: fread() failed\n", __LINE__
);
242 else if (memcmp (buf
, outstr
, sizeof (outstr
) - 1) != 0)
244 printf ("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__
);
248 /* Now with fseeko. */
249 if (fseeko (fp
, -((int) sizeof (outstr
) - 1), SEEK_END
) != 0)
251 printf ("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__
);
254 else if (fflush (fp
) != 0)
256 printf ("%d: fflush() failed\n", __LINE__
);
259 else if (lseek (fd
, 0, SEEK_CUR
) != 0)
261 printf ("%d: lseek() returned different position\n", __LINE__
);
264 else if (fread (buf
, sizeof (outstr
) - 1, 1, fp
) != 1)
266 printf ("%d: fread() failed\n", __LINE__
);
269 else if (memcmp (buf
, outstr
, sizeof (outstr
) - 1) != 0)
271 printf ("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__
);
275 if (fwrite (outstr
, sizeof (outstr
) - 1, 1, fp
) != 1)
277 printf ("%d: write error 2\n", __LINE__
);
282 if (fwrite (outstr
, sizeof (outstr
) - 1, 1, fp
) != 1)
284 printf ("%d: write error 3\n", __LINE__
);
289 if (fwrite (outstr
, sizeof (outstr
) - 1, 1, fp
) != 1)
291 printf ("%d: write error 4\n", __LINE__
);
296 if (fwrite (outstr
, sizeof (outstr
) - 1, 1, fp
) != 1)
298 printf ("%d: write error 5\n", __LINE__
);
303 if (fputc ('1', fp
) == EOF
|| fputc ('2', fp
) == EOF
)
305 printf ("%d: cannot add characters at the end\n", __LINE__
);
310 /* Check the access time. */
311 if (fstat64 (fd
, &st1
) < 0)
313 printf ("%d: fstat64() before fseeko() failed\n\n", __LINE__
);
320 if (fseek (fp
, -(2 + 2 * (sizeof (outstr
) - 1)), SEEK_CUR
) != 0)
322 printf ("%d: fseek() after write characters failed\n", __LINE__
);
330 /* Make sure the timestamp actually can be different. */
334 if (fstat64 (fd
, &st2
) < 0)
336 printf ("%d: fstat64() after fseeko() failed\n\n", __LINE__
);
339 if (st1
.st_ctime
>= t
)
341 printf ("%d: st_ctime not updated\n", __LINE__
);
344 if (st1
.st_mtime
>= t
)
346 printf ("%d: st_mtime not updated\n", __LINE__
);
349 if (st1
.st_ctime
>= st2
.st_ctime
)
351 printf ("%d: st_ctime not changed\n", __LINE__
);
354 if (st1
.st_mtime
>= st2
.st_mtime
)
356 printf ("%d: st_mtime not changed\n", __LINE__
);
362 if (fread (buf
, 1, 2 + 2 * (sizeof (outstr
) - 1), fp
)
363 != 2 + 2 * (sizeof (outstr
) - 1))
365 printf ("%d: reading 2 records plus bits failed\n", __LINE__
);
368 else if (memcmp (buf
, outstr
, sizeof (outstr
) - 1) != 0
369 || memcmp (&buf
[sizeof (outstr
) - 1], outstr
,
370 sizeof (outstr
) - 1) != 0
371 || buf
[2 * (sizeof (outstr
) - 1)] != '1'
372 || buf
[2 * (sizeof (outstr
) - 1) + 1] != '2')
374 printf ("%d: reading records failed\n", __LINE__
);
377 else if (ungetc ('9', fp
) == EOF
)
379 printf ("%d: ungetc() failed\n", __LINE__
);
382 else if (fseek (fp
, -(2 + 2 * (sizeof (outstr
) - 1)), SEEK_END
) != 0)
384 printf ("%d: fseek after ungetc failed\n", __LINE__
);
387 else if (fread (buf
, 1, 2 + 2 * (sizeof (outstr
) - 1), fp
)
388 != 2 + 2 * (sizeof (outstr
) - 1))
390 printf ("%d: reading 2 records plus bits failed\n", __LINE__
);
393 else if (memcmp (buf
, outstr
, sizeof (outstr
) - 1) != 0
394 || memcmp (&buf
[sizeof (outstr
) - 1], outstr
,
395 sizeof (outstr
) - 1) != 0
396 || buf
[2 * (sizeof (outstr
) - 1)] != '1')
398 printf ("%d: reading records for the second time failed\n", __LINE__
);
401 else if (buf
[2 * (sizeof (outstr
) - 1) + 1] == '9')
403 printf ("%d: unget character not ignored\n", __LINE__
);
406 else if (buf
[2 * (sizeof (outstr
) - 1) + 1] != '2')
408 printf ("%d: unget somehow changed character\n", __LINE__
);
414 fp
= fopen (fname
, "r");
417 printf ("%d: fopen() failed\n\n", __LINE__
);
420 else if (fstat64 (fileno (fp
), &st1
) < 0)
422 printf ("%d: fstat64() before fseeko() failed\n\n", __LINE__
);
425 else if (fseeko (fp
, 0, SEEK_END
) != 0)
427 printf ("%d: fseeko(fp, 0, SEEK_END) failed\n", __LINE__
);
430 else if (ftello (fp
) != st1
.st_size
)
432 printf ("%d: fstat64 st_size %zd ftello %zd\n", __LINE__
,
433 (size_t) st1
.st_size
, (size_t) ftello (fp
));
437 printf ("%d: SEEK_END works\n", __LINE__
);
441 fp
= fopen (fname
, "r");
444 printf ("%d: fopen() failed\n\n", __LINE__
);
447 else if (fstat64 (fileno (fp
), &st1
) < 0)
449 printf ("%d: fstat64() before fgetc() failed\n\n", __LINE__
);
452 else if (fgetc (fp
) == EOF
)
454 printf ("%d: fgetc() before fseeko() failed\n\n", __LINE__
);
457 else if (fseeko (fp
, 0, SEEK_END
) != 0)
459 printf ("%d: fseeko(fp, 0, SEEK_END) failed\n", __LINE__
);
462 else if (ftello (fp
) != st1
.st_size
)
464 printf ("%d: fstat64 st_size %zd ftello %zd\n", __LINE__
,
465 (size_t) st1
.st_size
, (size_t) ftello (fp
));
469 printf ("%d: SEEK_END works\n", __LINE__
);
479 #define TEST_FUNCTION do_test ()
480 #include "../test-skeleton.c"