Update.
[glibc.git] / stdio-common / tst-fseek.c
blob79eef97b620e5893816b3c9cffaac7e19d0ed9ab
1 /* Tests of fseek and fseeko.
2 Copyright (C) 2000,01 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 puts ("write error");
67 result = 1;
68 goto out;
71 /* The EOF flag must be reset. */
72 if (fgetc (fp) != EOF)
74 puts ("managed to read at end of file");
75 result = 1;
77 else if (! feof (fp))
79 puts ("EOF flag not set");
80 result = 1;
82 if (fseek (fp, 0, SEEK_CUR) != 0)
84 puts ("fseek(fp, 0, SEEK_CUR) failed");
85 result = 1;
87 else if (feof (fp))
89 puts ("fseek() didn't reset EOF flag");
90 result = 1;
93 /* Do the same for fseeko(). */
94 #ifdef USE_IN_LIBIO
95 if (fgetc (fp) != EOF)
97 puts ("managed to read at end of file");
98 result = 1;
100 else if (! feof (fp))
102 puts ("EOF flag not set");
103 result = 1;
105 if (fseeko (fp, 0, SEEK_CUR) != 0)
107 puts ("fseek(fp, 0, SEEK_CUR) failed");
108 result = 1;
110 else if (feof (fp))
112 puts ("fseek() didn't reset EOF flag");
113 result = 1;
115 #endif
117 /* Go back to the beginning of the file: absolute. */
118 if (fseek (fp, 0, SEEK_SET) != 0)
120 puts ("fseek(fp, 0, SEEK_SET) failed");
121 result = 1;
123 else if (fflush (fp) != 0)
125 puts ("fflush() failed");
126 result = 1;
128 else if (lseek (fd, 0, SEEK_CUR) != 0)
130 puts ("lseek() returned different position");
131 result = 1;
133 else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1)
135 puts ("fread() failed");
136 result = 1;
138 else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0)
140 puts ("content after fseek(,,SEEK_SET) wrong");
141 result = 1;
144 #ifdef USE_IN_LIBIO
145 /* Now with fseeko. */
146 if (fseeko (fp, 0, SEEK_SET) != 0)
148 puts ("fseeko(fp, 0, SEEK_SET) failed");
149 result = 1;
151 else if (fflush (fp) != 0)
153 puts ("fflush() failed");
154 result = 1;
156 else if (lseek (fd, 0, SEEK_CUR) != 0)
158 puts ("lseek() returned different position");
159 result = 1;
161 else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1)
163 puts ("fread() failed");
164 result = 1;
166 else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0)
168 puts ("content after fseeko(,,SEEK_SET) wrong");
169 result = 1;
171 #endif
173 /* Go back to the beginning of the file: relative. */
174 if (fseek (fp, -(sizeof (outstr) - 1), SEEK_CUR) != 0)
176 puts ("fseek(fp, 0, SEEK_SET) failed");
177 result = 1;
179 else if (fflush (fp) != 0)
181 puts ("fflush() failed");
182 result = 1;
184 else if (lseek (fd, 0, SEEK_CUR) != 0)
186 puts ("lseek() returned different position");
187 result = 1;
189 else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1)
191 puts ("fread() failed");
192 result = 1;
194 else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0)
196 puts ("content after fseek(,,SEEK_SET) wrong");
197 result = 1;
200 #ifdef USE_IN_LIBIO
201 /* Now with fseeko. */
202 if (fseeko (fp, -(sizeof (outstr) - 1), SEEK_CUR) != 0)
204 puts ("fseeko(fp, 0, SEEK_SET) failed");
205 result = 1;
207 else if (fflush (fp) != 0)
209 puts ("fflush() failed");
210 result = 1;
212 else if (lseek (fd, 0, SEEK_CUR) != 0)
214 puts ("lseek() returned different position");
215 result = 1;
217 else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1)
219 puts ("fread() failed");
220 result = 1;
222 else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0)
224 puts ("content after fseeko(,,SEEK_SET) wrong");
225 result = 1;
227 #endif
229 /* Go back to the beginning of the file: from the end. */
230 if (fseek (fp, -(sizeof (outstr) - 1), SEEK_END) != 0)
232 puts ("fseek(fp, 0, SEEK_SET) failed");
233 result = 1;
235 else if (fflush (fp) != 0)
237 puts ("fflush() failed");
238 result = 1;
240 else if (lseek (fd, 0, SEEK_CUR) != 0)
242 puts ("lseek() returned different position");
243 result = 1;
245 else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1)
247 puts ("fread() failed");
248 result = 1;
250 else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0)
252 puts ("content after fseek(,,SEEK_SET) wrong");
253 result = 1;
256 #ifdef USE_IN_LIBIO
257 /* Now with fseeko. */
258 if (fseeko (fp, -(sizeof (outstr) - 1), SEEK_END) != 0)
260 puts ("fseeko(fp, 0, SEEK_SET) failed");
261 result = 1;
263 else if (fflush (fp) != 0)
265 puts ("fflush() failed");
266 result = 1;
268 else if (lseek (fd, 0, SEEK_CUR) != 0)
270 puts ("lseek() returned different position");
271 result = 1;
273 else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1)
275 puts ("fread() failed");
276 result = 1;
278 else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0)
280 puts ("content after fseeko(,,SEEK_SET) wrong");
281 result = 1;
283 #endif
285 if (fwrite (outstr, sizeof (outstr) - 1, 1, fp) != 1)
287 puts ("write error 2");
288 result = 1;
289 goto out;
292 if (fwrite (outstr, sizeof (outstr) - 1, 1, fp) != 1)
294 puts ("write error 3");
295 result = 1;
296 goto out;
299 if (fwrite (outstr, sizeof (outstr) - 1, 1, fp) != 1)
301 puts ("write error 4");
302 result = 1;
303 goto out;
306 if (fwrite (outstr, sizeof (outstr) - 1, 1, fp) != 1)
308 puts ("write error 5");
309 result = 1;
310 goto out;
313 if (fputc ('1', fp) == EOF || fputc ('2', fp) == EOF)
315 puts ("cannot add characters at the end");
316 result = 1;
317 goto out;
320 /* Check the access time. */
321 if (fstat64 (fd, &st1) < 0)
323 puts ("fstat64() before fseeko() failed\n");
324 result = 1;
326 else
328 sleep (1);
330 if (fseek (fp, -(2 + 2 * (sizeof (outstr) - 1)), SEEK_CUR) != 0)
332 puts ("fseek() after write characters failed");
333 result = 1;
334 goto out;
336 else
339 time_t t;
340 /* Make sure the timestamp actually can be different. */
341 sleep (1);
342 t = time (NULL);
344 if (fstat64 (fd, &st2) < 0)
346 puts ("fstat64() after fseeko() failed\n");
347 result = 1;
349 if (st1.st_ctime >= t)
351 puts ("st_ctime not updated");
352 result = 1;
354 if (st1.st_mtime >= t)
356 puts ("st_mtime not updated");
357 result = 1;
359 if (st1.st_ctime >= st2.st_ctime)
361 puts ("st_ctime not changed");
362 result = 1;
364 if (st1.st_mtime >= st2.st_mtime)
366 puts ("st_mtime not changed");
367 result = 1;
372 if (fread (buf, 1, 2 + 2 * (sizeof (outstr) - 1), fp)
373 != 2 + 2 * (sizeof (outstr) - 1))
375 puts ("reading 2 records plus bits failed");
376 result = 1;
378 else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0
379 || memcmp (&buf[sizeof (outstr) - 1], outstr,
380 sizeof (outstr) - 1) != 0
381 || buf[2 * (sizeof (outstr) - 1)] != '1'
382 || buf[2 * (sizeof (outstr) - 1) + 1] != '2')
384 puts ("reading records failed");
385 result = 1;
387 else if (ungetc ('9', fp) == EOF)
389 puts ("ungetc() failed");
390 result = 1;
392 else if (fseek (fp, -(2 + 2 * (sizeof (outstr) - 1)), SEEK_END) != 0)
394 puts ("fseek after ungetc failed");
395 result = 1;
397 else if (fread (buf, 1, 2 + 2 * (sizeof (outstr) - 1), fp)
398 != 2 + 2 * (sizeof (outstr) - 1))
400 puts ("reading 2 records plus bits failed");
401 result = 1;
403 else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0
404 || memcmp (&buf[sizeof (outstr) - 1], outstr,
405 sizeof (outstr) - 1) != 0
406 || buf[2 * (sizeof (outstr) - 1)] != '1')
408 puts ("reading records for the second time failed");
409 result = 1;
411 else if (buf[2 * (sizeof (outstr) - 1) + 1] == '9')
413 puts ("unget character not ignored");
414 result = 1;
416 else if (buf[2 * (sizeof (outstr) - 1) + 1] != '2')
418 puts ("unget somehow changed character");
419 result = 1;
422 out:
423 unlink (fname);
425 return result;