]> git.ipfire.org Git - thirdparty/glibc.git/blame - stdio-common/tst-fseek.c
Prefer https to http for gnu.org and fsf.org URLs
[thirdparty/glibc.git] / stdio-common / tst-fseek.c
CommitLineData
2050f7b5 1/* Tests of fseek and fseeko.
04277e02 2 Copyright (C) 2000-2019 Free Software Foundation, Inc.
2050f7b5
UD
3 This file is part of the GNU C Library.
4 Contributed by Ulrich Drepper <drepper@redhat.com>, 2000.
5
6 The GNU C Library is free software; you can redistribute it and/or
41bdb6e2
AJ
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.
2050f7b5
UD
10
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
41bdb6e2 14 Lesser General Public License for more details.
2050f7b5 15
41bdb6e2 16 You should have received a copy of the GNU Lesser General Public
59ba27a6 17 License along with the GNU C Library; if not, see
5a82c748 18 <https://www.gnu.org/licenses/>. */
2050f7b5
UD
19
20#include <error.h>
21#include <errno.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <unistd.h>
78f056db 26#include <time.h>
2050f7b5
UD
27#include <sys/stat.h>
28
29
0e426475
AS
30static int
31do_test (void)
2050f7b5
UD
32{
33 const char *tmpdir;
34 char *fname;
35 int fd;
36 FILE *fp;
37 const char outstr[] = "hello world!\n";
38 char strbuf[sizeof outstr];
39 char buf[200];
40 struct stat64 st1;
41 struct stat64 st2;
42 int result = 0;
43
44 tmpdir = getenv ("TMPDIR");
45 if (tmpdir == NULL || tmpdir[0] == '\0')
46 tmpdir = "/tmp";
47
48 asprintf (&fname, "%s/tst-fseek.XXXXXX", tmpdir);
49 if (fname == NULL)
50 error (EXIT_FAILURE, errno, "cannot generate name for temporary file");
51
52 /* Create a temporary file. */
53 fd = mkstemp (fname);
54 if (fd == -1)
55 error (EXIT_FAILURE, errno, "cannot open temporary file");
56
57 fp = fdopen (fd, "w+");
58 if (fp == NULL)
59 error (EXIT_FAILURE, errno, "cannot get FILE for temporary file");
60
61 setbuffer (fp, strbuf, sizeof (outstr) -1);
62
63 if (fwrite (outstr, sizeof (outstr) - 1, 1, fp) != 1)
64 {
78ce5a3b 65 printf ("%d: write error\n", __LINE__);
2050f7b5
UD
66 result = 1;
67 goto out;
68 }
69
70 /* The EOF flag must be reset. */
71 if (fgetc (fp) != EOF)
72 {
78ce5a3b 73 printf ("%d: managed to read at end of file\n", __LINE__);
2050f7b5
UD
74 result = 1;
75 }
76 else if (! feof (fp))
77 {
78ce5a3b 78 printf ("%d: EOF flag not set\n", __LINE__);
2050f7b5
UD
79 result = 1;
80 }
81 if (fseek (fp, 0, SEEK_CUR) != 0)
82 {
78ce5a3b 83 printf ("%d: fseek(fp, 0, SEEK_CUR) failed\n", __LINE__);
2050f7b5
UD
84 result = 1;
85 }
86 else if (feof (fp))
87 {
78ce5a3b 88 printf ("%d: fseek() didn't reset EOF flag\n", __LINE__);
2050f7b5
UD
89 result = 1;
90 }
91
92 /* Do the same for fseeko(). */
2050f7b5
UD
93 if (fgetc (fp) != EOF)
94 {
78ce5a3b 95 printf ("%d: managed to read at end of file\n", __LINE__);
2050f7b5
UD
96 result = 1;
97 }
98 else if (! feof (fp))
99 {
78ce5a3b 100 printf ("%d: EOF flag not set\n", __LINE__);
2050f7b5
UD
101 result = 1;
102 }
103 if (fseeko (fp, 0, SEEK_CUR) != 0)
104 {
78ce5a3b 105 printf ("%d: fseek(fp, 0, SEEK_CUR) failed\n", __LINE__);
2050f7b5
UD
106 result = 1;
107 }
108 else if (feof (fp))
109 {
78ce5a3b 110 printf ("%d: fseek() didn't reset EOF flag\n", __LINE__);
2050f7b5
UD
111 result = 1;
112 }
2050f7b5
UD
113
114 /* Go back to the beginning of the file: absolute. */
115 if (fseek (fp, 0, SEEK_SET) != 0)
116 {
78ce5a3b 117 printf ("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__);
2050f7b5
UD
118 result = 1;
119 }
120 else if (fflush (fp) != 0)
121 {
78ce5a3b 122 printf ("%d: fflush() failed\n", __LINE__);
2050f7b5
UD
123 result = 1;
124 }
125 else if (lseek (fd, 0, SEEK_CUR) != 0)
126 {
78ce5a3b 127 printf ("%d: lseek() returned different position\n", __LINE__);
2050f7b5
UD
128 result = 1;
129 }
130 else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1)
131 {
78ce5a3b 132 printf ("%d: fread() failed\n", __LINE__);
2050f7b5
UD
133 result = 1;
134 }
135 else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0)
136 {
78ce5a3b 137 printf ("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__);
2050f7b5
UD
138 result = 1;
139 }
140
2050f7b5
UD
141 /* Now with fseeko. */
142 if (fseeko (fp, 0, SEEK_SET) != 0)
143 {
78ce5a3b 144 printf ("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__);
2050f7b5
UD
145 result = 1;
146 }
147 else if (fflush (fp) != 0)
148 {
78ce5a3b 149 printf ("%d: fflush() failed\n", __LINE__);
2050f7b5
UD
150 result = 1;
151 }
152 else if (lseek (fd, 0, SEEK_CUR) != 0)
153 {
78ce5a3b 154 printf ("%d: lseek() returned different position\n", __LINE__);
2050f7b5
UD
155 result = 1;
156 }
157 else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1)
158 {
78ce5a3b 159 printf ("%d: fread() failed\n", __LINE__);
2050f7b5
UD
160 result = 1;
161 }
162 else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0)
163 {
78ce5a3b 164 printf ("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__);
2050f7b5
UD
165 result = 1;
166 }
2050f7b5
UD
167
168 /* Go back to the beginning of the file: relative. */
ffa8d2a0 169 if (fseek (fp, -((int) sizeof (outstr) - 1), SEEK_CUR) != 0)
2050f7b5 170 {
78ce5a3b 171 printf ("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__);
2050f7b5
UD
172 result = 1;
173 }
174 else if (fflush (fp) != 0)
175 {
78ce5a3b 176 printf ("%d: fflush() failed\n", __LINE__);
2050f7b5
UD
177 result = 1;
178 }
179 else if (lseek (fd, 0, SEEK_CUR) != 0)
180 {
78ce5a3b 181 printf ("%d: lseek() returned different position\n", __LINE__);
2050f7b5
UD
182 result = 1;
183 }
184 else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1)
185 {
78ce5a3b 186 printf ("%d: fread() failed\n", __LINE__);
2050f7b5
UD
187 result = 1;
188 }
189 else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0)
190 {
78ce5a3b 191 printf ("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__);
2050f7b5
UD
192 result = 1;
193 }
194
2050f7b5 195 /* Now with fseeko. */
ffa8d2a0 196 if (fseeko (fp, -((int) sizeof (outstr) - 1), SEEK_CUR) != 0)
2050f7b5 197 {
78ce5a3b 198 printf ("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__);
2050f7b5
UD
199 result = 1;
200 }
201 else if (fflush (fp) != 0)
202 {
78ce5a3b 203 printf ("%d: fflush() failed\n", __LINE__);
2050f7b5
UD
204 result = 1;
205 }
206 else if (lseek (fd, 0, SEEK_CUR) != 0)
207 {
78ce5a3b 208 printf ("%d: lseek() returned different position\n", __LINE__);
2050f7b5
UD
209 result = 1;
210 }
211 else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1)
212 {
78ce5a3b 213 printf ("%d: fread() failed\n", __LINE__);
2050f7b5
UD
214 result = 1;
215 }
216 else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0)
217 {
78ce5a3b 218 printf ("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__);
2050f7b5
UD
219 result = 1;
220 }
2050f7b5
UD
221
222 /* Go back to the beginning of the file: from the end. */
ffa8d2a0 223 if (fseek (fp, -((int) sizeof (outstr) - 1), SEEK_END) != 0)
2050f7b5 224 {
78ce5a3b 225 printf ("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__);
2050f7b5
UD
226 result = 1;
227 }
228 else if (fflush (fp) != 0)
229 {
78ce5a3b 230 printf ("%d: fflush() failed\n", __LINE__);
2050f7b5
UD
231 result = 1;
232 }
233 else if (lseek (fd, 0, SEEK_CUR) != 0)
234 {
78ce5a3b 235 printf ("%d: lseek() returned different position\n", __LINE__);
2050f7b5
UD
236 result = 1;
237 }
238 else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1)
239 {
78ce5a3b 240 printf ("%d: fread() failed\n", __LINE__);
2050f7b5
UD
241 result = 1;
242 }
243 else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0)
244 {
78ce5a3b 245 printf ("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__);
2050f7b5
UD
246 result = 1;
247 }
248
2050f7b5 249 /* Now with fseeko. */
ffa8d2a0 250 if (fseeko (fp, -((int) sizeof (outstr) - 1), SEEK_END) != 0)
2050f7b5 251 {
78ce5a3b 252 printf ("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__);
2050f7b5
UD
253 result = 1;
254 }
255 else if (fflush (fp) != 0)
256 {
78ce5a3b 257 printf ("%d: fflush() failed\n", __LINE__);
2050f7b5
UD
258 result = 1;
259 }
260 else if (lseek (fd, 0, SEEK_CUR) != 0)
261 {
78ce5a3b 262 printf ("%d: lseek() returned different position\n", __LINE__);
2050f7b5
UD
263 result = 1;
264 }
265 else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1)
266 {
78ce5a3b 267 printf ("%d: fread() failed\n", __LINE__);
2050f7b5
UD
268 result = 1;
269 }
270 else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0)
271 {
78ce5a3b 272 printf ("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__);
2050f7b5
UD
273 result = 1;
274 }
2050f7b5
UD
275
276 if (fwrite (outstr, sizeof (outstr) - 1, 1, fp) != 1)
277 {
78ce5a3b 278 printf ("%d: write error 2\n", __LINE__);
2050f7b5
UD
279 result = 1;
280 goto out;
281 }
282
283 if (fwrite (outstr, sizeof (outstr) - 1, 1, fp) != 1)
284 {
78ce5a3b 285 printf ("%d: write error 3\n", __LINE__);
2050f7b5
UD
286 result = 1;
287 goto out;
288 }
289
290 if (fwrite (outstr, sizeof (outstr) - 1, 1, fp) != 1)
291 {
78ce5a3b 292 printf ("%d: write error 4\n", __LINE__);
2050f7b5
UD
293 result = 1;
294 goto out;
295 }
296
297 if (fwrite (outstr, sizeof (outstr) - 1, 1, fp) != 1)
298 {
78ce5a3b 299 printf ("%d: write error 5\n", __LINE__);
2050f7b5
UD
300 result = 1;
301 goto out;
302 }
303
304 if (fputc ('1', fp) == EOF || fputc ('2', fp) == EOF)
305 {
78ce5a3b 306 printf ("%d: cannot add characters at the end\n", __LINE__);
2050f7b5
UD
307 result = 1;
308 goto out;
309 }
310
311 /* Check the access time. */
312 if (fstat64 (fd, &st1) < 0)
313 {
78ce5a3b 314 printf ("%d: fstat64() before fseeko() failed\n\n", __LINE__);
2050f7b5
UD
315 result = 1;
316 }
317 else
318 {
319 sleep (1);
320
321 if (fseek (fp, -(2 + 2 * (sizeof (outstr) - 1)), SEEK_CUR) != 0)
322 {
78ce5a3b 323 printf ("%d: fseek() after write characters failed\n", __LINE__);
2050f7b5
UD
324 result = 1;
325 goto out;
326 }
327 else
328 {
329
330 time_t t;
331 /* Make sure the timestamp actually can be different. */
332 sleep (1);
333 t = time (NULL);
334
335 if (fstat64 (fd, &st2) < 0)
336 {
78ce5a3b 337 printf ("%d: fstat64() after fseeko() failed\n\n", __LINE__);
2050f7b5
UD
338 result = 1;
339 }
340 if (st1.st_ctime >= t)
341 {
78ce5a3b 342 printf ("%d: st_ctime not updated\n", __LINE__);
2050f7b5
UD
343 result = 1;
344 }
345 if (st1.st_mtime >= t)
346 {
78ce5a3b 347 printf ("%d: st_mtime not updated\n", __LINE__);
2050f7b5
UD
348 result = 1;
349 }
350 if (st1.st_ctime >= st2.st_ctime)
351 {
78ce5a3b 352 printf ("%d: st_ctime not changed\n", __LINE__);
2050f7b5
UD
353 result = 1;
354 }
355 if (st1.st_mtime >= st2.st_mtime)
356 {
78ce5a3b 357 printf ("%d: st_mtime not changed\n", __LINE__);
2050f7b5
UD
358 result = 1;
359 }
360 }
361 }
362
363 if (fread (buf, 1, 2 + 2 * (sizeof (outstr) - 1), fp)
364 != 2 + 2 * (sizeof (outstr) - 1))
365 {
78ce5a3b 366 printf ("%d: reading 2 records plus bits failed\n", __LINE__);
2050f7b5
UD
367 result = 1;
368 }
369 else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0
370 || memcmp (&buf[sizeof (outstr) - 1], outstr,
371 sizeof (outstr) - 1) != 0
372 || buf[2 * (sizeof (outstr) - 1)] != '1'
373 || buf[2 * (sizeof (outstr) - 1) + 1] != '2')
374 {
78ce5a3b 375 printf ("%d: reading records failed\n", __LINE__);
2050f7b5
UD
376 result = 1;
377 }
378 else if (ungetc ('9', fp) == EOF)
379 {
78ce5a3b 380 printf ("%d: ungetc() failed\n", __LINE__);
2050f7b5
UD
381 result = 1;
382 }
383 else if (fseek (fp, -(2 + 2 * (sizeof (outstr) - 1)), SEEK_END) != 0)
384 {
78ce5a3b 385 printf ("%d: fseek after ungetc failed\n", __LINE__);
2050f7b5
UD
386 result = 1;
387 }
388 else if (fread (buf, 1, 2 + 2 * (sizeof (outstr) - 1), fp)
389 != 2 + 2 * (sizeof (outstr) - 1))
390 {
78ce5a3b 391 printf ("%d: reading 2 records plus bits failed\n", __LINE__);
2050f7b5
UD
392 result = 1;
393 }
394 else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0
395 || memcmp (&buf[sizeof (outstr) - 1], outstr,
396 sizeof (outstr) - 1) != 0
397 || buf[2 * (sizeof (outstr) - 1)] != '1')
398 {
78ce5a3b 399 printf ("%d: reading records for the second time failed\n", __LINE__);
2050f7b5
UD
400 result = 1;
401 }
402 else if (buf[2 * (sizeof (outstr) - 1) + 1] == '9')
403 {
78ce5a3b 404 printf ("%d: unget character not ignored\n", __LINE__);
2050f7b5
UD
405 result = 1;
406 }
407 else if (buf[2 * (sizeof (outstr) - 1) + 1] != '2')
408 {
78ce5a3b 409 printf ("%d: unget somehow changed character\n", __LINE__);
2050f7b5
UD
410 result = 1;
411 }
412
903b3396
UD
413 fclose (fp);
414
903b3396
UD
415 fp = fopen (fname, "r");
416 if (fp == NULL)
417 {
78ce5a3b 418 printf ("%d: fopen() failed\n\n", __LINE__);
903b3396
UD
419 result = 1;
420 }
421 else if (fstat64 (fileno (fp), &st1) < 0)
422 {
78ce5a3b 423 printf ("%d: fstat64() before fseeko() failed\n\n", __LINE__);
903b3396
UD
424 result = 1;
425 }
426 else if (fseeko (fp, 0, SEEK_END) != 0)
427 {
78ce5a3b 428 printf ("%d: fseeko(fp, 0, SEEK_END) failed\n", __LINE__);
903b3396
UD
429 result = 1;
430 }
431 else if (ftello (fp) != st1.st_size)
432 {
78ce5a3b
UD
433 printf ("%d: fstat64 st_size %zd ftello %zd\n", __LINE__,
434 (size_t) st1.st_size, (size_t) ftello (fp));
903b3396
UD
435 result = 1;
436 }
437 else
78ce5a3b 438 printf ("%d: SEEK_END works\n", __LINE__);
903b3396
UD
439 if (fp != NULL)
440 fclose (fp);
441
442 fp = fopen (fname, "r");
443 if (fp == NULL)
444 {
78ce5a3b 445 printf ("%d: fopen() failed\n\n", __LINE__);
903b3396
UD
446 result = 1;
447 }
448 else if (fstat64 (fileno (fp), &st1) < 0)
449 {
78ce5a3b 450 printf ("%d: fstat64() before fgetc() failed\n\n", __LINE__);
903b3396
UD
451 result = 1;
452 }
453 else if (fgetc (fp) == EOF)
454 {
78ce5a3b 455 printf ("%d: fgetc() before fseeko() failed\n\n", __LINE__);
903b3396
UD
456 result = 1;
457 }
458 else if (fseeko (fp, 0, SEEK_END) != 0)
459 {
78ce5a3b 460 printf ("%d: fseeko(fp, 0, SEEK_END) failed\n", __LINE__);
903b3396
UD
461 result = 1;
462 }
463 else if (ftello (fp) != st1.st_size)
464 {
78ce5a3b
UD
465 printf ("%d: fstat64 st_size %zd ftello %zd\n", __LINE__,
466 (size_t) st1.st_size, (size_t) ftello (fp));
903b3396
UD
467 result = 1;
468 }
469 else
78ce5a3b 470 printf ("%d: SEEK_END works\n", __LINE__);
903b3396
UD
471 if (fp != NULL)
472 fclose (fp);
903b3396 473
2050f7b5
UD
474 out:
475 unlink (fname);
476
477 return result;
478}
0e426475 479
0e426475
AS
480#define TEST_FUNCTION do_test ()
481#include "../test-skeleton.c"