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