Quash warning in s_sincosl.
[platform/upstream/glibc.git] / stdio-common / tst-fseek.c
1 /* Tests of fseek and fseeko.
2    Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
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
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.
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
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library; if not, see
18    <http://www.gnu.org/licenses/>.  */
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>
26 #include <time.h>
27 #include <sys/stat.h>
28
29
30 int
31 main (void)
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     {
65       printf ("%d: write error\n", __LINE__);
66       result = 1;
67       goto out;
68     }
69
70   /* The EOF flag must be reset.  */
71   if (fgetc (fp) != EOF)
72     {
73       printf ("%d: managed to read at end of file\n", __LINE__);
74       result = 1;
75     }
76   else if (! feof (fp))
77     {
78       printf ("%d: EOF flag not set\n", __LINE__);
79       result = 1;
80     }
81   if (fseek (fp, 0, SEEK_CUR) != 0)
82     {
83       printf ("%d: fseek(fp, 0, SEEK_CUR) failed\n", __LINE__);
84       result = 1;
85     }
86   else if (feof (fp))
87     {
88       printf ("%d: fseek() didn't reset EOF flag\n", __LINE__);
89       result = 1;
90     }
91
92   /* Do the same for fseeko().  */
93     if (fgetc (fp) != EOF)
94     {
95       printf ("%d: managed to read at end of file\n", __LINE__);
96       result = 1;
97     }
98   else if (! feof (fp))
99     {
100       printf ("%d: EOF flag not set\n", __LINE__);
101       result = 1;
102     }
103   if (fseeko (fp, 0, SEEK_CUR) != 0)
104     {
105       printf ("%d: fseek(fp, 0, SEEK_CUR) failed\n", __LINE__);
106       result = 1;
107     }
108   else if (feof (fp))
109     {
110       printf ("%d: fseek() didn't reset EOF flag\n", __LINE__);
111       result = 1;
112     }
113
114   /* Go back to the beginning of the file: absolute.  */
115   if (fseek (fp, 0, SEEK_SET) != 0)
116     {
117       printf ("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__);
118       result = 1;
119     }
120   else if (fflush (fp) != 0)
121     {
122       printf ("%d: fflush() failed\n", __LINE__);
123       result = 1;
124     }
125   else if (lseek (fd, 0, SEEK_CUR) != 0)
126     {
127       printf ("%d: lseek() returned different position\n", __LINE__);
128       result = 1;
129     }
130   else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1)
131     {
132       printf ("%d: fread() failed\n", __LINE__);
133       result = 1;
134     }
135   else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0)
136     {
137       printf ("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__);
138       result = 1;
139     }
140
141   /* Now with fseeko.  */
142   if (fseeko (fp, 0, SEEK_SET) != 0)
143     {
144       printf ("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__);
145       result = 1;
146     }
147   else if (fflush (fp) != 0)
148     {
149       printf ("%d: fflush() failed\n", __LINE__);
150       result = 1;
151     }
152   else if (lseek (fd, 0, SEEK_CUR) != 0)
153     {
154       printf ("%d: lseek() returned different position\n", __LINE__);
155       result = 1;
156     }
157   else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1)
158     {
159       printf ("%d: fread() failed\n", __LINE__);
160       result = 1;
161     }
162   else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0)
163     {
164       printf ("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__);
165       result = 1;
166     }
167
168   /* Go back to the beginning of the file: relative.  */
169   if (fseek (fp, -((int) sizeof (outstr) - 1), SEEK_CUR) != 0)
170     {
171       printf ("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__);
172       result = 1;
173     }
174   else if (fflush (fp) != 0)
175     {
176       printf ("%d: fflush() failed\n", __LINE__);
177       result = 1;
178     }
179   else if (lseek (fd, 0, SEEK_CUR) != 0)
180     {
181       printf ("%d: lseek() returned different position\n", __LINE__);
182       result = 1;
183     }
184   else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1)
185     {
186       printf ("%d: fread() failed\n", __LINE__);
187       result = 1;
188     }
189   else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0)
190     {
191       printf ("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__);
192       result = 1;
193     }
194
195   /* Now with fseeko.  */
196   if (fseeko (fp, -((int) sizeof (outstr) - 1), SEEK_CUR) != 0)
197     {
198       printf ("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__);
199       result = 1;
200     }
201   else if (fflush (fp) != 0)
202     {
203       printf ("%d: fflush() failed\n", __LINE__);
204       result = 1;
205     }
206   else if (lseek (fd, 0, SEEK_CUR) != 0)
207     {
208       printf ("%d: lseek() returned different position\n", __LINE__);
209       result = 1;
210     }
211   else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1)
212     {
213       printf ("%d: fread() failed\n", __LINE__);
214       result = 1;
215     }
216   else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0)
217     {
218       printf ("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__);
219       result = 1;
220     }
221
222   /* Go back to the beginning of the file: from the end.  */
223   if (fseek (fp, -((int) sizeof (outstr) - 1), SEEK_END) != 0)
224     {
225       printf ("%d: fseek(fp, 0, SEEK_SET) failed\n", __LINE__);
226       result = 1;
227     }
228   else if (fflush (fp) != 0)
229     {
230       printf ("%d: fflush() failed\n", __LINE__);
231       result = 1;
232     }
233   else if (lseek (fd, 0, SEEK_CUR) != 0)
234     {
235       printf ("%d: lseek() returned different position\n", __LINE__);
236       result = 1;
237     }
238   else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1)
239     {
240       printf ("%d: fread() failed\n", __LINE__);
241       result = 1;
242     }
243   else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0)
244     {
245       printf ("%d: content after fseek(,,SEEK_SET) wrong\n", __LINE__);
246       result = 1;
247     }
248
249   /* Now with fseeko.  */
250   if (fseeko (fp, -((int) sizeof (outstr) - 1), SEEK_END) != 0)
251     {
252       printf ("%d: fseeko(fp, 0, SEEK_SET) failed\n", __LINE__);
253       result = 1;
254     }
255   else if (fflush (fp) != 0)
256     {
257       printf ("%d: fflush() failed\n", __LINE__);
258       result = 1;
259     }
260   else if (lseek (fd, 0, SEEK_CUR) != 0)
261     {
262       printf ("%d: lseek() returned different position\n", __LINE__);
263       result = 1;
264     }
265   else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1)
266     {
267       printf ("%d: fread() failed\n", __LINE__);
268       result = 1;
269     }
270   else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0)
271     {
272       printf ("%d: content after fseeko(,,SEEK_SET) wrong\n", __LINE__);
273       result = 1;
274     }
275
276   if (fwrite (outstr, sizeof (outstr) - 1, 1, fp) != 1)
277     {
278       printf ("%d: write error 2\n", __LINE__);
279       result = 1;
280       goto out;
281     }
282
283   if (fwrite (outstr, sizeof (outstr) - 1, 1, fp) != 1)
284     {
285       printf ("%d: write error 3\n", __LINE__);
286       result = 1;
287       goto out;
288     }
289
290   if (fwrite (outstr, sizeof (outstr) - 1, 1, fp) != 1)
291     {
292       printf ("%d: write error 4\n", __LINE__);
293       result = 1;
294       goto out;
295     }
296
297   if (fwrite (outstr, sizeof (outstr) - 1, 1, fp) != 1)
298     {
299       printf ("%d: write error 5\n", __LINE__);
300       result = 1;
301       goto out;
302     }
303
304   if (fputc ('1', fp) == EOF || fputc ('2', fp) == EOF)
305     {
306       printf ("%d: cannot add characters at the end\n", __LINE__);
307       result = 1;
308       goto out;
309     }
310
311   /* Check the access time.  */
312   if (fstat64 (fd, &st1) < 0)
313     {
314       printf ("%d: fstat64() before fseeko() failed\n\n", __LINE__);
315       result = 1;
316     }
317   else
318     {
319       sleep (1);
320
321       if (fseek (fp, -(2 + 2 * (sizeof (outstr) - 1)), SEEK_CUR) != 0)
322         {
323           printf ("%d: fseek() after write characters failed\n", __LINE__);
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             {
337               printf ("%d: fstat64() after fseeko() failed\n\n", __LINE__);
338               result = 1;
339             }
340           if (st1.st_ctime >= t)
341             {
342               printf ("%d: st_ctime not updated\n", __LINE__);
343               result = 1;
344             }
345           if (st1.st_mtime >= t)
346             {
347               printf ("%d: st_mtime not updated\n", __LINE__);
348               result = 1;
349             }
350           if (st1.st_ctime >= st2.st_ctime)
351             {
352               printf ("%d: st_ctime not changed\n", __LINE__);
353               result = 1;
354             }
355           if (st1.st_mtime >= st2.st_mtime)
356             {
357               printf ("%d: st_mtime not changed\n", __LINE__);
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     {
366       printf ("%d: reading 2 records plus bits failed\n", __LINE__);
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     {
375       printf ("%d: reading records failed\n", __LINE__);
376       result = 1;
377     }
378   else if (ungetc ('9', fp) == EOF)
379     {
380       printf ("%d: ungetc() failed\n", __LINE__);
381       result = 1;
382     }
383   else if (fseek (fp, -(2 + 2 * (sizeof (outstr) - 1)), SEEK_END) != 0)
384     {
385       printf ("%d: fseek after ungetc failed\n", __LINE__);
386       result = 1;
387     }
388   else if (fread (buf, 1, 2 + 2 * (sizeof (outstr) - 1), fp)
389       != 2 + 2 * (sizeof (outstr) - 1))
390     {
391       printf ("%d: reading 2 records plus bits failed\n", __LINE__);
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     {
399       printf ("%d: reading records for the second time failed\n", __LINE__);
400       result = 1;
401     }
402   else if (buf[2 * (sizeof (outstr) - 1) + 1] == '9')
403     {
404       printf ("%d: unget character not ignored\n", __LINE__);
405       result = 1;
406     }
407   else if (buf[2 * (sizeof (outstr) - 1) + 1] != '2')
408     {
409       printf ("%d: unget somehow changed character\n", __LINE__);
410       result = 1;
411     }
412
413   fclose (fp);
414
415   fp = fopen (fname, "r");
416   if (fp == NULL)
417     {
418       printf ("%d: fopen() failed\n\n", __LINE__);
419       result = 1;
420     }
421   else if (fstat64 (fileno (fp), &st1) < 0)
422     {
423       printf ("%d: fstat64() before fseeko() failed\n\n", __LINE__);
424       result = 1;
425     }
426   else if (fseeko (fp, 0, SEEK_END) != 0)
427     {
428       printf ("%d: fseeko(fp, 0, SEEK_END) failed\n", __LINE__);
429       result = 1;
430     }
431   else if (ftello (fp) != st1.st_size)
432     {
433       printf ("%d: fstat64 st_size %zd ftello %zd\n", __LINE__,
434               (size_t) st1.st_size, (size_t) ftello (fp));
435       result = 1;
436     }
437   else
438     printf ("%d: SEEK_END works\n", __LINE__);
439   if (fp != NULL)
440     fclose (fp);
441
442   fp = fopen (fname, "r");
443   if (fp == NULL)
444     {
445       printf ("%d: fopen() failed\n\n", __LINE__);
446       result = 1;
447     }
448   else if (fstat64 (fileno (fp), &st1) < 0)
449     {
450       printf ("%d: fstat64() before fgetc() failed\n\n", __LINE__);
451       result = 1;
452     }
453   else if (fgetc (fp) == EOF)
454     {
455       printf ("%d: fgetc() before fseeko() failed\n\n", __LINE__);
456       result = 1;
457     }
458   else if (fseeko (fp, 0, SEEK_END) != 0)
459     {
460       printf ("%d: fseeko(fp, 0, SEEK_END) failed\n", __LINE__);
461       result = 1;
462     }
463   else if (ftello (fp) != st1.st_size)
464     {
465       printf ("%d: fstat64 st_size %zd ftello %zd\n", __LINE__,
466               (size_t) st1.st_size, (size_t) ftello (fp));
467       result = 1;
468     }
469   else
470     printf ("%d: SEEK_END works\n", __LINE__);
471   if (fp != NULL)
472     fclose (fp);
473
474  out:
475   unlink (fname);
476
477   return result;
478 }